imgtools/buildrom/tools/configpaging.pm
changeset 0 044383f39525
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/buildrom/tools/configpaging.pm	Tue Oct 27 16:36:35 2009 +0000
@@ -0,0 +1,344 @@
+#
+# Copyright (c) 2006-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: 
+# changes the paging/unpaged configuration of binaries a generated
+# OBY file according to the list in configpaging.lst
+# use
+# externaltool=configpaging.pm
+# in oby file to enable
+# use
+# tool=configpaging \epoc32\rom\myconfigpaging.lst
+# to change the default configpaging.lst
+#
+
+package configpaging;
+
+use strict;
+
+our @EXPORT=qw(
+        configpaging_info
+		configpaging_initialize
+        configpaging_single
+        configpaging_multiple
+);
+use Exporter;
+our @ISA=qw(Exporter);
+
+#
+# Initialisation
+#
+use constant CONSTANT_UNPAGED => "unpaged";
+use constant CONSTANT_PAGED => "paged";
+use constant CONSTANT_UNPAGEDCODE => "unpagedcode";
+use constant CONSTANT_PAGEDCODE => "pagedcode";
+use constant CONSTANT_UNPAGEDDATA => "unpageddata";
+use constant CONSTANT_PAGEDDATA => "pageddata";
+use constant CONSTANT_CONFIG_PATH => "epoc32\\rom\\configpaging\\";
+my $epocroot = $ENV{EPOCROOT};
+my $configlist = $epocroot.CONSTANT_CONFIG_PATH."configpaging.cfg";
+
+
+# routine to provide information about the tool
+sub configpaging_info ()
+{
+    my %toolinfo;
+    $toolinfo{'name'} = "configpaging";
+    $toolinfo{'invocation'} = "InvocationPoint2";
+	$toolinfo{'initialize'} = \&configpaging_initialize;
+    $toolinfo{'multiple'} = \&configpaging_multiple;
+    $toolinfo{'single'} = \&configpaging_single;
+    return \%toolinfo;
+}
+
+sub configpaging_initialize
+	{
+	my ($cmdLine) = @_;
+	if (defined ($cmdLine))
+		{
+		print "configpaging.pm: Initializing with $cmdLine\n";
+		$configlist = $epocroot.CONSTANT_CONFIG_PATH.$cmdLine;
+		}
+	}
+
+# routine to handle multiple invocation
+sub configpaging_multiple
+{
+    my ($line) = @_;
+	my @args=split /[=\s]/, $line;
+	$configlist=$args[2];
+    return "REM configpaging.pm: Using $configlist";
+}
+
+
+sub isobystatement
+{
+	my ($li) = @_;
+	if ($li =~ /^\s*data(=|\s+)/i) { return 1;}
+	if ($li =~ /^\s*file(=|\s+)/i) { return 1;}
+	if ($li =~ /^\s*dll(=|\s+)/i) { return 1;}
+	if ($li =~ /^\s*secondary(=|\s+)/i) { return 1;}
+
+	return 0;
+}
+
+#codepaging is codepagingoverride setting
+#datapaging is datapagingoverride setting
+#listref is ref to an associated array keyed by <executable regex>, 
+#and the value is another associated array keyed (un)?paged(code|data)?
+#the value is 1 if set, undeffed if not.
+sub readConfigFile
+	{
+	my ($codepagingref, $datapagingref, $listref, $configfilename) = @_;
+	my $filecodepaging = "";
+	my $filedatapaging = "";
+
+	local *FILE; # need a filehandle local to this invocation
+	if(!open FILE, $configfilename)
+		{
+		print ("Configpaging Warning: Can't open $configfilename\n");
+		return;
+		}
+
+	# parse the configfilename
+	# insert the files listed into the listref and set the paging info accordingly.
+	while (my $line=<FILE>)
+		{
+		if ($line !~ /\S/ ) { next; }
+		if ($line =~ /^\s*#/ ) { next; }
+		chomp $line;
+		if ($line =~ /^\s*(code|data)?pagingoverride=(.*)\s*/i) {
+			if ($1 eq undef) {
+				if (lc($2) eq "defaultpaged") {
+					$$codepagingref = CONSTANT_PAGED;
+					$$datapagingref = CONSTANT_PAGED;
+				} elsif (lc($2) eq "defaultunpaged") {
+					$$codepagingref = CONSTANT_UNPAGED;
+					$$datapagingref = CONSTANT_UNPAGED;
+				} else {
+					print ("Configpaging Warning: invalid pagingoverride setting:$2\n");
+				}
+			} elsif (lc($1) eq "code") {
+				if (lc($2) eq "defaultpaged") {
+					$$codepagingref = CONSTANT_PAGED;
+				} elsif (lc($2) eq "defaultunpaged") {
+					$$codepagingref = CONSTANT_UNPAGED;
+				} else {
+					print ("Configpaging Warning: invalid codepagingoverride setting:$2\n");
+				}
+			} elsif ($1 eq "data") {
+				if (lc($2) eq "defaultpaged") {
+					$$datapagingref = CONSTANT_PAGED;
+				} elsif (lc($2) eq "defaultunpaged") {
+					$$datapagingref = CONSTANT_UNPAGED;
+				} else {
+					print ("Configpaging Warning: invalid datapagingoverride setting:$2\n");
+				}
+			} else {
+				print ("configpaging Warning: invalid keyword: $1" . "pagingoverride\n");
+			}
+		}
+		elsif ($line =~ /^\s*(un)?paged(code|data)?(\s+(un)?paged(code|data)?)?:/i ) {
+			$filecodepaging = "";
+			$filedatapaging = "";
+			if ($1 eq undef) {
+				if ($2 eq undef) {
+					$filecodepaging = CONSTANT_PAGED;
+					$filedatapaging = CONSTANT_PAGED;
+				}elsif (lc($2) eq "code") {
+					$filecodepaging = CONSTANT_PAGED;
+				} elsif(lc($2) eq "data") {
+					$filedatapaging = CONSTANT_PAGED;
+				} else {
+					print ("Configpaging Warning: unrecognized line:$line\n");
+				}
+			} elsif (lc($1) eq "un") {
+				if ($2 eq undef) {
+					$filecodepaging = CONSTANT_UNPAGED;
+					$filedatapaging = CONSTANT_UNPAGED;
+				}elsif (lc($2) eq "code") {
+					$filecodepaging = CONSTANT_UNPAGED;
+				} elsif(lc($2) eq "data") {
+					$filedatapaging = CONSTANT_UNPAGED;
+				} else {
+					print ("Configpaging Warning: unrecognized line:$line\n");
+				}
+			} else {
+				print ("Configpaging Warning: unrecognized line:$line\n");
+			}
+			if ($3 ne undef){		
+				if ($4 eq undef) {
+					if ($5 eq undef) {
+						$filecodepaging = CONSTANT_PAGED;
+						$filedatapaging = CONSTANT_PAGED;
+					}elsif (lc($5) eq "code") {
+						$filecodepaging = CONSTANT_PAGED;
+					} elsif(lc($5) eq "data") {
+						$filedatapaging = CONSTANT_PAGED;
+					} else {
+						print ("Configpaging Warning: unrecognized line:$line\n");
+					}
+				} elsif (lc($4) eq "un") {
+					if ($5 eq undef) {
+						$filecodepaging = CONSTANT_UNPAGED;
+						$filedatapaging = CONSTANT_UNPAGED;
+					}elsif (lc($5) eq "code") {
+						$filecodepaging = CONSTANT_UNPAGED;
+					} elsif(lc($5) eq "data") {
+						$filedatapaging = CONSTANT_UNPAGED;
+					} else {
+						print ("Configpaging Warning: unrecognized line:$line\n");
+					}
+				} else {
+					print ("Configpaging Warning: unrecognized line:$line\n");
+				}
+			}
+		}
+		elsif ($line =~ /^\s*include\s*\"(.*)\"/i)
+			{ readConfigFile($codepagingref, $datapagingref, $listref, $epocroot.CONSTANT_CONFIG_PATH.$1); } # go recursive
+		elsif ($line =~ /\s*(\S+)(\s+(un)?paged(code|data)?(\s+(un)?paged(code|data)?)?)?/i){
+			my %element;
+			$element{code} = $$codepagingref;
+			$element{data} = $$datapagingref;
+			if ($2 eq undef){
+				if ($filecodepaging ne "") {
+					$element{code} = $filecodepaging;
+				}
+				if ($filedatapaging ne "") {
+					$element{data} = $filedatapaging;
+				}
+			} else {
+				if ($4 eq undef){
+					if ($3 eq undef) {
+						$element{code} = CONSTANT_PAGED; 
+						$element{data} = CONSTANT_PAGED; 
+					} elsif (lc($3) eq "un") {
+						$element{code} = CONSTANT_UNPAGED; 
+						$element{data} = CONSTANT_UNPAGED; 
+					}
+				} elsif (lc($4) eq "code") {
+					if ($3 eq undef) {
+						$element{code} = CONSTANT_PAGED;
+					} elsif (lc($3) eq "un") {
+						$element{code} = CONSTANT_UNPAGED;
+					}
+				} elsif (lc($4) eq "data") {
+					if ($3 eq undef) {
+						$element{data} = CONSTANT_PAGED;
+					} elsif (lc($3) eq "un") {
+						$element{data} = CONSTANT_UNPAGED;
+					}
+				} else {
+					print ("Configpaging Warning: unrecognized attribute in line: $line\n");
+		}
+				if ($5 ne undef){
+					if ($7 eq undef){
+						if ($6 eq undef) {
+							$element{code} = CONSTANT_PAGED; 
+							$element{data} = CONSTANT_PAGED; 
+						} elsif (lc($6) eq "un") {
+							$element{code} = CONSTANT_UNPAGED; 
+							$element{data} = CONSTANT_UNPAGED; 
+						}
+					} elsif (lc($7) eq "code") {
+						if ($6 eq undef) {
+							$element{code} = CONSTANT_PAGED;
+						} elsif (lc($6) eq "un") {
+							$element{code} = CONSTANT_UNPAGED;
+						}
+					} elsif (lc($7) eq "data") {
+						if ($6 eq undef) {
+							$element{data} = CONSTANT_PAGED;
+						} elsif (lc($6) eq "un") {
+							$element{data} = CONSTANT_UNPAGED;
+						}
+					} else {
+						print ("Configpaging Warning: unrecognized attribute in line: $line\n");
+					}
+				}
+			}	
+			$$listref{$1} = \%element;
+		} else {
+			print ("ConfigPaging Warning: unrecognized line:$line\n");
+		}
+	}
+	close FILE;
+	}
+
+# routine to handle single invocation
+sub configpaging_single
+{
+	my $codepaging="";
+	my $datapaging="";
+	my %list;
+	my @keys;
+    my ($oby) = @_;
+
+	print "configpaging.pm: Modifying demand paging configuration using $configlist\n";
+	readConfigFile(\$codepaging, \$datapaging, \%list, $configlist);
+	# read the oby file that was handed to us
+	# find matches between each oby line and any files  in the paged or unpaged list
+	# modify the attributes of the oby line as appropriate
+	my @newlines;
+	my %element;
+	@keys = keys %list;
+	foreach my $line (@$oby)
+		{
+		my $codepagingadd="";
+		my $datapagingadd="";
+		chomp $line;
+		if (isobystatement($line))
+			{
+			my $lcline = lc($line);
+			for(my $index=@keys - 1; $index>=0; $index--) {
+				my $match = $keys[$index];
+				if ($lcline =~ /(\s+|\"|\\|=)$match(\s+|\"|$)/) {
+					%element = %{$list{$match}};
+					if ($element{code} eq CONSTANT_PAGED) {
+						$codepagingadd .= " " . CONSTANT_PAGEDCODE;
+					} elsif  ($element{code} eq CONSTANT_UNPAGED) {
+						$codepagingadd .= " " . CONSTANT_UNPAGEDCODE;
+					} 
+					if ($element{data} eq CONSTANT_PAGED) {
+						$datapagingadd .= " " . CONSTANT_PAGEDDATA;
+					} elsif  ($element{data} eq CONSTANT_UNPAGED) {
+						$datapagingadd .= " " . CONSTANT_UNPAGEDDATA;
+					}
+					last;
+				}
+			}
+			if (!$codepagingadd and $codepaging) {
+				$codepagingadd = " " . $codepaging . "code";
+			}
+			if (!$datapagingadd and $datapaging) {
+				$datapagingadd = " " . $datapaging . "data";
+					}
+			if ($codepagingadd and !$datapagingadd){
+				if ($line =~ /\b(un)?paged(data)?\b\s*$/) {
+					$datapagingadd = " " . $1 . "pageddata";
+				}
+			} elsif ($datapagingadd and !$codepagingadd) {
+				if ($line =~ /\b(un)?paged(code)?\b\s*$/) {
+					$codepagingadd = " " . $1 . "pagedcode";
+			}
+				}
+			if ($datapagingadd or $datapagingadd) {
+				$line =~ s/\b(un)?paged(code|data)?\b/ /ig;
+				}
+			}
+		push @newlines, "$line$codepagingadd$datapagingadd\n";
+		}
+	@$oby = @newlines;
+}
+
+1;