diff -r c7c26511138f -r 360bd6b35136 imgtools/romtools/maksym/fixupsym.pl --- a/imgtools/romtools/maksym/fixupsym.pl Wed Jun 16 16:51:40 2010 +0300 +++ b/imgtools/romtools/maksym/fixupsym.pl Wed Jun 23 16:56:47 2010 +0800 @@ -1,470 +1,470 @@ -# -# Copyright (c) 1999-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: -# Relinks the debug exe/dlls in a ROM if the make file is present -# - -require 5.003_07; -use strict; -no strict 'vars'; -use English; -use Cwd; -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 $debug = 0; -my $rombuild; -my @executables = ( 'euser' ); - -cwd =~ /^(.:)/o; -my $drive = $1; - -# get EPOCROOT for searching directories -my $epocroot = lc $ENV{EPOCROOT}; - -&args; -&main; - -exit 0; - - -# -# main -# -sub main - { - my $file; - my $text; - my $data; - my $bss; - my $textlen; - my $datalen; - my $bsslen; - - open (ROM, "<$rombuild") - or die "ERROR: Can't open rombuild log file \"$rombuild\"\n"; - - die "ERROR: \"$rombuild\" isn't a rombuild log file\n" - unless (( =~ /^ROMBUILD/) || ( =~ /^ROMBUILD/)); - - # build up a hash of all the make files indexed by build and exe name - # - # do this in a more directed way based on the map files for the - # executables we are interested in. - - %map = (); - &dirsearch($epocroot . "EPOC32\\", "BUILD"); - - while () - { - if (/^Writing Rom image/) - { - # stop at end of first ROM, ignoring any extension ROMs - # This is necessary because the same file could appear - # at different places in different extensions. - # - last; - } - if (/^Processing file (.*)/) - { - my $datalen; - my $skip; - - $file = lc $1; - $text = $bss = $data = $datalen = 0; - - # Work out final addresses of sections - while (defined($_=) && !/^$/) - { - if (/^Code start addr:\s+(\w+)/) - { - $text = hex($1); - } - elsif (/^DataBssLinearBase:\s+(\w+)/) - { - $data = hex($1); - } - elsif (/^Code size:\s+(\w+)/) - { - $textlen = hex($1); - } - elsif (/^Data size:\s+(\w+)/) - { - $datalen = hex($1); - $bss = $data + $datalen; - } - elsif (/^BssSize:\s+(\w+)/) - { - $bsslen = hex($1); - } - } - - # Sanity check - text section can't be zero (other sections may be) - die "ERROR: Can't find rombuild info for \"$file\"\n" - if (!$text); - - # get the build and exe name - # protect $epocroot with \Q and \E to stop it - # using \ as a special character - if ($file =~ /^\Q$epocroot\Eepoc32\\release\\(.*)\\(.*)\\(.*)$/o) - { - $build = lc $1; - $debrel = uc $2; - $executablefile = lc $3; - } - - # Only relink this file if it's kernel-side or matches the regexp - if ($build =~ /^(M|S)/i) - { - $skip = 0; - } - else - { - $skip = 1; - foreach $re (@executables) - { - $skip = 0 if ($file =~ /$re/i); - } - } - print "$file - skipped\n" if ($skip && $debug); - next if ($skip); - - if (! defined $map{"$build $executablefile"}) - { - print "$file - no makefile\n"; - next; - } - if ($debrel ne "UDEB") - { - print "$file - can't fixup $debrel\n"; - next; - } - - # relink this file - print "$file"; - - # lookup the makefile name - ($makepath, $workdir) = @{$map{"$build $executablefile"}}; - - # only relink if we have a makefile - if ($makepath && $workdir) - { - # optimisation: don't relink if already at correct address - $file =~ /(.+\.)[^\.]+/; - my $symfile = $drive.$1."sym"; - my $buf; - my $elffile; - open SYMFILE, $symfile or print"\nCannot open $symfile\n"; - read SYMFILE, $buf, 4; - if ($buf =~/^\x7F\x45\x4C\x46/){ - $elffile = $buf; - } - close SYMFILE; - if ($elffile){ - if ((-e $file) && (-e $symfile) && - open (CHILD, "fromelf -v $symfile |")) - { - my $oldtext; - my $olddata; - my $foundcode = 0; - my $founddata = 0; - while () - { - if (/ER_RO/) - { - $foundcode = 1; - } - if (/ER_RW/) - { - $founddata = 1; - } - - if (/Addr : 0x\w+/) - { - $_=~tr/0-9//dc; - if ($founddata == 1) - { - $founddata = 0; - $olddata = hex($_); - } - - if ($foundcode == 1) - { - $foundcode = 0; - $oldtext = hex($_); - } - } - } - close CHILD; - $skip = 1 if ((!$textlen || ($text == $oldtext)) && (!$datalen || ($data == $olddata))); - } - } - else { - if ((-e $file) && (-e $symfile) && - open (CHILD, "objdump --headers $symfile |")) - { - my $oldtext; - my $olddata; - my $oldbss; - while () - { - if (/^\s+\d+\s+(\.\w+)\s+[0-9a-fA-F]+\s+([0-9a-fA-F]+)\s/) - { - if ($1 eq '.text') - { - $oldtext = hex($2); - } - elsif ($1 eq '.data') - { - $olddata = hex($2); - } - elsif ($1 eq '.bss') - { - $oldbss = hex($2); - } - } - } - close CHILD; - $skip = 1 if ((!$textlen || ($text == $oldtext)) && - (!$datalen || ($data == $olddata)) && - (!$bsslen || ($bss == $oldbss))); - print " - current" if ($skip && $debug); - } - } - - if (!$skip) - { - chdir $workdir - or die "Can't cd to build directory \"$workdir\"\n"; - - # save executable in case relink fails - rename $file, "$file.bak" - or die "Can't rename \"$file\": $ERRNO\n" - if -e $file; - - $makepath = &fixMakefile($makepath); - my $command; - if ($elffile){ - if($makepath =~ /\.gcce/i){ - $command = - sprintf ("make -r -s -f \"$makepath\" $debrel " . - "USERLDFLAGS=\"-Ttext 0x%lx -Tdata 0x%lx\"", $text, $data); - } - else { - $command = - sprintf ("make -r -s -f \"$makepath\" $debrel " . - "USERLDFLAGS=\"--ro-base 0x%lx --rw-base 0x%lx\"", $text, $data); - } - } - else { - $command = - sprintf ("make -r -s -f \"$makepath\" $debrel " . - "USERLDFLAGS=\"--image-base 0 -Ttext 0x%lx " . - "-Tdata 0x%lx -Tbss 0x%lx\"", - $text, $data, $bss); - } - print "\n\"$command\"" if ($debug); - - open (CHILD, "$command |") - or die "\nERROR: Can't run \"$command\": $ERRNO\n"; - close CHILD; - - unlink $makepath; - if (-e $file) - { - unlink "$file.bak"; - } - else # relink failed for some reason - restore saved - { - rename "$file.bak", $file; - } - } - - print "\n"; - } - else - { - print " - can't fixup\n"; - } - } - } - close ROM; - } - -# -# 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; - } - else - { - print "\nERROR: Unknown flag \"-$flag\"\n"; - &usage; - exit 1; - } - } - else - { - push @args,$arg; - } - } - - $rombuild = shift @args; - - if (@args) - { - foreach $file (@args) - { - push @executables, quotemeta($file); - } - } - } - - -# recursive directory search -sub dirsearch - { - my ($input_path, $dir) = @_; - my $searchpath = "$input_path$dir\\"; - my $workdir; - - return unless (opendir DIRHANDLE, $searchpath); - my @allfiles = grep !/^\.\.?$/, readdir DIRHANDLE; - closedir DIRHANDLE; - - # Breadth first search: scan files and collect list of subdirectories - my @dirlist; - foreach $entry (@allfiles) - { - my $entrypath = "$searchpath$entry"; - if (-d $entrypath) - { - # don't look in udeb & urel directories which contain objects and binaries - push @dirlist, $entry unless ($entry =~ /(deb|rel)$/i); - } - elsif ($entry =~ /$dir$/i) - { - # ARM4/xxx.ARM4 => generated makefile - my $liney; - open (FILE, "<$entrypath"); - while ($liney=) - { - if ($liney =~ /^\# CWD\s(.+)\\/) - { - $workdir = lc $1; - } - if ($liney =~ /^\# Target\s(.*)$/) - { - my $target = lc $1; - - # add to the hash table - my $build = lc $dir; - $map{"$build $target"} = [lc "$entrypath", $workdir]; - $workdir = undef; - last; - } - } - close FILE; - } - } - undef @allfiles; - # Now process the subdirectories... - foreach $entry (@dirlist) - { - &dirsearch ($searchpath,$entry); - } - undef @dirlist; - } - -sub help () - { - my $build; - - &Load_ModuleL('E32TPVER'); - print "\nfixupsym - " . - "Fix up executables with locations taken from a ROM image (Build ", - &E32tpver, ")\n"; - &usage; - exit 0; - } - -sub usage () - { - print < [] - -Where: - Log file from rombuild tool. - Names of additional executables to fix up. - ASSP-specific executables and EUSER are always included. - -Example: - fixupsym rombuild.log efile efsrv .fsy -EOF - ; - exit 0; - } -sub fixMakefile() - { - my $makefile = shift @_; - my $tmpMakfile = $makefile.".TMP"; - open (FILEIN, $makefile) or die "Can't open file \"$makefile\" \n"; - open (FILEOUT, ">".$tmpMakfile) or die "Can't create file \"$tmpMakfile\" \n"; - while() { - if ($_ =~ /^\s*elf2e32/){ - print FILEOUT "#".$_; - } - else { - print FILEOUT $_; - } - } - close FILEIN; - close FILEOUT; - $tmpMakfile; - } +# +# Copyright (c) 1999-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: +# Relinks the debug exe/dlls in a ROM if the make file is present +# + +require 5.003_07; +use strict; +no strict 'vars'; +use English; +use Cwd; +use FindBin; # for FindBin::Bin + +my $PerlLibPath; + +BEGIN { +# check user has a version of perl that will cope + require 5.005_03; + $PerlLibPath = $FindBin::Bin; +} + +use lib $PerlLibPath; + +use romutl; + +# Version +my $MajorVersion = 1; +my $MinorVersion = 1; +my $PatchVersion = 1; + +# Globals +my $debug = 0; +my $rombuild; +my @executables = ( 'euser' ); + +cwd =~ /^(.:)/o; +my $drive = $1; + +# get EPOCROOT for searching directories +my $epocroot = lc &get_epocroot; + +&args; +&main; + +exit 0; + + +# +# main +# +sub main + { + my $file; + my $text; + my $data; + my $bss; + my $textlen; + my $datalen; + my $bsslen; + + open (ROM, "<$rombuild") + or die "ERROR: Can't open rombuild log file \"$rombuild\"\n"; + + die "ERROR: \"$rombuild\" isn't a rombuild log file\n" + unless (( =~ /^ROMBUILD/) || ( =~ /^ROMBUILD/)); + + # build up a hash of all the make files indexed by build and exe name + # + # do this in a more directed way based on the map files for the + # executables we are interested in. + + %map = (); + &dirsearch($epocroot . "EPOC32\\", "BUILD"); + + while () + { + if (/^Writing Rom image/) + { + # stop at end of first ROM, ignoring any extension ROMs + # This is necessary because the same file could appear + # at different places in different extensions. + # + last; + } + if (/^Processing file (.*)/) + { + my $datalen; + my $skip; + + $file = lc $1; + $text = $bss = $data = $datalen = 0; + + # Work out final addresses of sections + while (defined($_=) && !/^$/) + { + if (/^Code start addr:\s+(\w+)/) + { + $text = hex($1); + } + elsif (/^DataBssLinearBase:\s+(\w+)/) + { + $data = hex($1); + } + elsif (/^Code size:\s+(\w+)/) + { + $textlen = hex($1); + } + elsif (/^Data size:\s+(\w+)/) + { + $datalen = hex($1); + $bss = $data + $datalen; + } + elsif (/^BssSize:\s+(\w+)/) + { + $bsslen = hex($1); + } + } + + # Sanity check - text section can't be zero (other sections may be) + die "ERROR: Can't find rombuild info for \"$file\"\n" + if (!$text); + + # get the build and exe name + # protect $epocroot with \Q and \E to stop it + # using \ as a special character + if ($file =~ /^\Q$epocroot\Eepoc32\\release\\(.*)\\(.*)\\(.*)$/o) + { + $build = lc $1; + $debrel = uc $2; + $executablefile = lc $3; + } + + # Only relink this file if it's kernel-side or matches the regexp + if ($build =~ /^(M|S)/i) + { + $skip = 0; + } + else + { + $skip = 1; + foreach $re (@executables) + { + $skip = 0 if ($file =~ /$re/i); + } + } + print "$file - skipped\n" if ($skip && $debug); + next if ($skip); + + if (! defined $map{"$build $executablefile"}) + { + print "$file - no makefile\n"; + next; + } + if ($debrel ne "UDEB") + { + print "$file - can't fixup $debrel\n"; + next; + } + + # relink this file + print "$file"; + + # lookup the makefile name + ($makepath, $workdir) = @{$map{"$build $executablefile"}}; + + # only relink if we have a makefile + if ($makepath && $workdir) + { + # optimisation: don't relink if already at correct address + $file =~ /(.+\.)[^\.]+/; + my $symfile = $drive.$1."sym"; + my $buf; + my $elffile; + open SYMFILE, $symfile or print"\nCannot open $symfile\n"; + read SYMFILE, $buf, 4; + if ($buf =~/^\x7F\x45\x4C\x46/){ + $elffile = $buf; + } + close SYMFILE; + if ($elffile){ + if ((-e $file) && (-e $symfile) && + open (CHILD, "fromelf -v $symfile |")) + { + my $oldtext; + my $olddata; + my $foundcode = 0; + my $founddata = 0; + while () + { + if (/ER_RO/) + { + $foundcode = 1; + } + if (/ER_RW/) + { + $founddata = 1; + } + + if (/Addr : 0x\w+/) + { + $_=~tr/0-9//dc; + if ($founddata == 1) + { + $founddata = 0; + $olddata = hex($_); + } + + if ($foundcode == 1) + { + $foundcode = 0; + $oldtext = hex($_); + } + } + } + close CHILD; + $skip = 1 if ((!$textlen || ($text == $oldtext)) && (!$datalen || ($data == $olddata))); + } + } + else { + if ((-e $file) && (-e $symfile) && + open (CHILD, "objdump --headers $symfile |")) + { + my $oldtext; + my $olddata; + my $oldbss; + while () + { + if (/^\s+\d+\s+(\.\w+)\s+[0-9a-fA-F]+\s+([0-9a-fA-F]+)\s/) + { + if ($1 eq '.text') + { + $oldtext = hex($2); + } + elsif ($1 eq '.data') + { + $olddata = hex($2); + } + elsif ($1 eq '.bss') + { + $oldbss = hex($2); + } + } + } + close CHILD; + $skip = 1 if ((!$textlen || ($text == $oldtext)) && + (!$datalen || ($data == $olddata)) && + (!$bsslen || ($bss == $oldbss))); + print " - current" if ($skip && $debug); + } + } + + if (!$skip) + { + chdir $workdir + or die "Can't cd to build directory \"$workdir\"\n"; + + # save executable in case relink fails + rename $file, "$file.bak" + or die "Can't rename \"$file\": $ERRNO\n" + if -e $file; + + $makepath = &fixMakefile($makepath); + my $command; + if ($elffile){ + if($makepath =~ /\.gcce/i){ + $command = + sprintf ("make -r -s -f \"$makepath\" $debrel " . + "USERLDFLAGS=\"-Ttext 0x%lx -Tdata 0x%lx\"", $text, $data); + } + else { + $command = + sprintf ("make -r -s -f \"$makepath\" $debrel " . + "USERLDFLAGS=\"--ro-base 0x%lx --rw-base 0x%lx\"", $text, $data); + } + } + else { + $command = + sprintf ("make -r -s -f \"$makepath\" $debrel " . + "USERLDFLAGS=\"--image-base 0 -Ttext 0x%lx " . + "-Tdata 0x%lx -Tbss 0x%lx\"", + $text, $data, $bss); + } + print "\n\"$command\"" if ($debug); + + open (CHILD, "$command |") + or die "\nERROR: Can't run \"$command\": $ERRNO\n"; + close CHILD; + + unlink $makepath; + if (-e $file) + { + unlink "$file.bak"; + } + else # relink failed for some reason - restore saved + { + rename "$file.bak", $file; + } + } + + print "\n"; + } + else + { + print " - can't fixup\n"; + } + } + } + close ROM; + } + +# +# 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; + } + else + { + print "\nERROR: Unknown flag \"-$flag\"\n"; + &usage; + exit 1; + } + } + else + { + push @args,$arg; + } + } + + $rombuild = shift @args; + + if (@args) + { + foreach $file (@args) + { + push @executables, quotemeta($file); + } + } + } + + +# recursive directory search +sub dirsearch + { + my ($input_path, $dir) = @_; + my $searchpath = "$input_path$dir\\"; + my $workdir; + + return unless (opendir DIRHANDLE, $searchpath); + my @allfiles = grep !/^\.\.?$/, readdir DIRHANDLE; + closedir DIRHANDLE; + + # Breadth first search: scan files and collect list of subdirectories + my @dirlist; + foreach $entry (@allfiles) + { + my $entrypath = "$searchpath$entry"; + if (-d $entrypath) + { + # don't look in udeb & urel directories which contain objects and binaries + push @dirlist, $entry unless ($entry =~ /(deb|rel)$/i); + } + elsif ($entry =~ /$dir$/i) + { + # ARM4/xxx.ARM4 => generated makefile + my $liney; + open (FILE, "<$entrypath"); + while ($liney=) + { + if ($liney =~ /^\# CWD\s(.+)\\/) + { + $workdir = lc $1; + } + if ($liney =~ /^\# Target\s(.*)$/) + { + my $target = lc $1; + + # add to the hash table + my $build = lc $dir; + $map{"$build $target"} = [lc "$entrypath", $workdir]; + $workdir = undef; + last; + } + } + close FILE; + } + } + undef @allfiles; + # Now process the subdirectories... + foreach $entry (@dirlist) + { + &dirsearch ($searchpath,$entry); + } + undef @dirlist; + } + +sub help () + { + my $build; + + print "\nfixupsym - " . + "Fix up executables with locations taken from a ROM image V${MajorVersion}.${MinorVersion}.${PatchVersion}\n"; + &usage; + exit 0; + } + +sub usage () + { + print < [] + +Where: + Log file from rombuild tool. + Names of additional executables to fix up. + ASSP-specific executables and EUSER are always included. + +Example: + fixupsym rombuild.log efile efsrv .fsy +EOF + ; + exit 0; + } +sub fixMakefile() + { + my $makefile = shift @_; + my $tmpMakfile = $makefile.".TMP"; + open (FILEIN, $makefile) or die "Can't open file \"$makefile\" \n"; + open (FILEOUT, ">".$tmpMakfile) or die "Can't create file \"$tmpMakfile\" \n"; + while() { + if ($_ =~ /^\s*elf2e32/){ + print FILEOUT "#".$_; + } + else { + print FILEOUT $_; + } + } + close FILEIN; + close FILEOUT; + $tmpMakfile; + }