imgtools/buildrom/tools/buildrom.pm
changeset 0 044383f39525
child 590 360bd6b35136
child 606 30b30f9da0b7
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     1 #
       
     2 # Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 # All rights reserved.
       
     4 # This component and the accompanying materials are made available
       
     5 # under the terms of the License "Eclipse Public License v1.0"
       
     6 # which accompanies this distribution, and is available
       
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 #
       
     9 # Initial Contributors:
       
    10 # Nokia Corporation - initial contribution.
       
    11 #
       
    12 # Contributors:
       
    13 #
       
    14 # Description: 
       
    15 # This package is to build rom image
       
    16 #
       
    17 
       
    18 package buildrom;
       
    19 
       
    20 require Exporter;
       
    21 @ISA=qw(Exporter);
       
    22 @EXPORT=qw(
       
    23 	image_content_processing_phase
       
    24 	process_cmdline_arguments
       
    25 	preprocessing_phase
       
    26 	substitution_phase
       
    27 	reorganize_phase
       
    28 	plugin_phase
       
    29 	multlinguify_phase
       
    30 	spi_creation_phase
       
    31 	suppress_phase
       
    32 	bitmap_aif_converison_phase
       
    33 	cleaning_phase
       
    34 	create_dumpfile
       
    35 	create_dirlisting
       
    36 	suppress_image_generation
       
    37 	invoke_rombuild
       
    38 	getOBYDataRef
       
    39 	isobystatement
       
    40 	isdatastatement
       
    41 	isspidatastatement
       
    42 	isexecutablefile
       
    43 	isdirectorymetadata
       
    44 	isbitmap
       
    45 	isaif
       
    46 	isresource
       
    47 	hardwarevariant
       
    48 	executableextension
       
    49 	executabletype
       
    50 	getSourceFile
       
    51 	getDestFile
       
    52 	getOBYAttributes
       
    53 	getHardwareVariant
       
    54 	getObyCommand
       
    55 	process_dlldata
       
    56 	featurefile_creation_phase
       
    57 	processData
       
    58 	create_smrimage
       
    59 );
       
    60 
       
    61 my $enforceFeatureManager = 0; # Flag to make Feature Manager mandatory if SYMBIAN_FEATURE_MANAGER macro is defined. 
       
    62 
       
    63 my $BuildromMajorVersion = 3 ;
       
    64 my $BuildromMinorVersion = 17;
       
    65 my $BuildromPatchVersion = 0;
       
    66 
       
    67 sub print_usage
       
    68 {
       
    69 
       
    70 	# Option "-fm" will be supported instead of option "-f|fr" if SYMBIAN_FEATURE_MANAGER macro is defined.
       
    71 	my $featuresOptionUsage = "-ffeatureuids or -fr=featureuids -- feature registry database XML file name";
       
    72 	if ($enforceFeatureManager) 
       
    73 	{
       
    74 		$featuresOptionUsage = "-fm=featuredatabasefile          -- feature manager/feature registry database XML file name.\n".
       
    75 							   "\t\t\t\t    Multiple XML files can be passed seperated by commas.\n".
       
    76 							   "   -nofm=featuresdatafile           -- don't generate features data file.".
       
    77 							   " Instead use pre-built features data file.";
       
    78 	}
       
    79 
       
    80 #........1.........2.........3.........4.........5.........6.........7.....
       
    81 	print <<USAGE_EOF;
       
    82 
       
    83 BUILDROM - ROM configuration tool V$BuildromMajorVersion.$BuildromMinorVersion.$BuildromPatchVersion
       
    84 
       
    85 Usage:
       
    86   buildrom [options] obyfile [obyfile2 ...]   
       
    87 
       
    88 Build a ROM according to the specification defined by concatenating the
       
    89 specified obyfiles.
       
    90 
       
    91 The initial specification is modified by C++ preprocessor directives,
       
    92 and subsequently adjusted by statements in the ROM specification language.
       
    93 The final specification is in the subset of the specification language
       
    94 which is understood directly by ROMBUILD.
       
    95 
       
    96 Each obyfile parameter specifies a file via a search path: if the
       
    97 filename is not matched then buildrom will look in \\epoc32\\rom\\include.
       
    98 
       
    99 Buildrom invokes ROMBUILD to generate the ROM image, and produces a
       
   100 number of related files such as the ROM symbol file. The name of the
       
   101 image file is specified directly by the -o option, or determined by 
       
   102 scanning the final specification for the "romname" keyword. If there is 
       
   103 more than one "romname" statement, the last one takes precedence.
       
   104 
       
   105 The available options are
       
   106 
       
   107    -Dxxx                            -- C++ preprocessor arguments
       
   108    -oimagename                      -- ROM image name, overriding any ROMNAME statement
       
   109    -s                               -- strict option, any missing files will stop buildrom 
       
   110    -p                               -- preserves the intermediate files pertaining to data drive, Z drive and BMCONV
       
   111    -spi                             -- enable producing SPI files
       
   112    -spiplacement                    -- enable positioning of spi file
       
   113    -w                               -- warn if file has been selected from a different directory 
       
   114    $featuresOptionUsage
       
   115    -etool                           -- external tool specification (xx is tool's perl module)
       
   116    -compress                        -- compression type of ROM image:
       
   117                                        -compress compress whole ROM image.
       
   118                                        -compress=paged compress paged section in the ROM image only.
       
   119                                        -compress=unpaged compress unpaged section in the ROM image only. 
       
   120    -ccomprmethod                    -- compression method: none|inflate|bytepair
       
   121    -geninc                          -- generate INC file
       
   122    -gendep                          -- generate dependence graph for rom image
       
   123    -nosymbols                       -- disable creation of symbol file
       
   124    -noimage                         -- disable creation of ROM/ROFS/DataDrive Image
       
   125    -fastcompress                    -- compress files with faster bytepair and tradeoff of compress ratio
       
   126    -j<digit>                        -- do the main job with <digit> threads
       
   127    -loglevel<level>                 -- Level of information logging where loglevel is 0,1,2
       
   128                                        0 default level of information
       
   129                                        1 host/ROM filenames, file size and the hidden attribute along with level0 log
       
   130                                        2 E32 file header attributes along with level1 log
       
   131    -z=xxx or -zdrivepath=xxx        -- specify a location to create Z drive directory. 
       
   132    -d=xxx or -datadrivepath=xxx     -- specify a location to create data drive directory.
       
   133    -k or -keepgoing                 -- enable keepgoing,continue to create the data drive image even
       
   134                                     if the non-sis, sis or zdrive image file(s) are missing or corrupt.
       
   135    -r or -retainfolder              -- enable retainfolder,would retain pre-existence of z & data drive folder. 
       
   136    -zdriveimage=xxx                 -- specify Z drive image (ROM, CORE, ROFS or Ext-ROFS image).
       
   137    -pfile=xxx                       -- specify a parameter file for interpretsis to take additional parameters.
       
   138    -argforinterpretsis=xxx          -- specify command line argument(s) for interpretsis which will override the 
       
   139                                     parameter file contents.
       
   140    -l=xxx or -logimagecontents=xxx  -- extract all stub-sis and SWI certificate store file(s) only 
       
   141                                     and log all the file(s) that are part of the Z drive image on to a log file.  
       
   142    -I<directory>                    -- Use <directory> for the referenced IBY/OBY files
       
   143    -argfile=xxx                     -- specify argument-file name containing list of command-line arguments to buildrom   
       
   144    -lowmem                          -- use memory-mapped file for image build to reduce physical memory consumption   
       
   145 
       
   146 Popular -D defines to use include
       
   147 
       
   148    -D_DEBUG         -- select debug versions of some files
       
   149    -D_FULL_DEBUG    -- select debug versions of all files
       
   150    -D_ARM4          -- specify the target platform
       
   151 
       
   152    -D_EABI=xxxx     -- specify target for all files (e.g. ARMV5)
       
   153    -D_KABI=xxxx     -- specify the target platform for the Kernel (e.g. ARMV5)
       
   154 
       
   155 Other defines may be useful for particular OBY files.
       
   156 
       
   157 USAGE_EOF
       
   158 }
       
   159 
       
   160 use strict;
       
   161 my $PerlLibPath;    # fully qualified pathname of the directory containing our Perl modules
       
   162 # establish the path to the Perl libraries
       
   163 $PerlLibPath = $FindBin::Bin;	# X:/epoc32/tools
       
   164 $PerlLibPath =~ s/\//\\/g;	# X:\epoc32\tools
       
   165 $PerlLibPath .= "\\";
       
   166 sub ExportDirs ($);
       
   167 
       
   168 use BPABIutl; # for BPABIutl::BPABIutl_Plat_List
       
   169 
       
   170 my $xmlrequired = 0; # assume xml required is false. Used to determine if xml
       
   171                      # modules should be loaded.
       
   172 
       
   173 use Modload;	     # To load modules dynamically
       
   174 
       
   175 # Work out the relative path to the epoc32 directory
       
   176 use spitool qw(&createSpi);
       
   177 use Cwd;
       
   178 use Pathutl;
       
   179 use E32Variant;
       
   180 use E32Plat;
       
   181 use Genutl;
       
   182 use BPABIutl;		# for BPABIutl::BPABIutl_Plat_List
       
   183 use externaltools; 	#To invoke External Tools
       
   184 
       
   185 my @tempfiles;  	
       
   186 my $preserve = 0; 	#flag to indicate if temporary files should be preserved
       
   187 my $uppath="x";	    	# will be initialised when first needed
       
   188 
       
   189 my $epocroot = $ENV{EPOCROOT};
       
   190 die "ERROR: Must set the EPOCROOT environment variable\n" if (!defined($epocroot));
       
   191 $epocroot =~ s-/-\\-go;	# for those working with UNIX shells
       
   192 die "ERROR: EPOCROOT must not include a drive letter\n" if ($epocroot =~ /^.:/);
       
   193 die "ERROR: EPOCROOT must be an absolute path without a drive letter\n" if ($epocroot !~ /^\\/);
       
   194 die "ERROR: EPOCROOT must not be a UNC path\n" if ($epocroot =~ /^\\\\/);
       
   195 die "ERROR: EPOCROOT must end with a backslash\n" if ($epocroot !~ /\\$/);
       
   196 die "ERROR: EPOCROOT must specify an existing directory\n" if (!-d $epocroot);
       
   197 
       
   198 my $epoc32 = relative_path("${epocroot}epoc32");
       
   199 $epoc32 =~ s-\\-/-go;
       
   200 
       
   201 my @obyfiles;
       
   202 my $cppargs = "-nostdinc -undef";
       
   203 my $opt_v = 0;
       
   204 my $opt_o = "";
       
   205 my $strict = 0;
       
   206 my $warnSelection = 0; # default is not warn about selecting files from 
       
   207 		       # different directories when the file is missing from
       
   208 		       # the specified directory
       
   209 
       
   210 my $createspi = 0; # don't create SPI files by default
       
   211 my $spiset=0;
       
   212 my $spiplacement = 0; # enable the placement of spi file
       
   213 my %spipositionflag = (); # map of Image index at which the keyword SPI_POSITION is used.
       
   214 
       
   215 use constant NONE => 0;
       
   216 use constant INFLATE => 1;
       
   217 use constant BYTEPAIR => 2;
       
   218 my $opt_compression;  # Default compression method parameter undefined
       
   219 
       
   220 use constant UNCOMPRESSED   => 0;        # Indicates the ROM image will not be compressed.
       
   221 use constant ALLSECTIONS    => 1;        # Indicates both paged section and unpaged section will be compressed.
       
   222 use constant PAGEDSECTION   => 2;        # Indicates only paged section will be compressed.
       
   223 use constant UNPAGEDSECTION => 3;        # Indicates only unpaged section will be compressed.
       
   224 my $opt_compression_type = UNCOMPRESSED; # Leave the ROM image uncompressed by default.
       
   225 
       
   226 my $thisdir=cwd;
       
   227 $thisdir=~s-/-\\-go;		    # separator from Perl 5.005_02+ is forward slash
       
   228 $thisdir=~s-^(.*[^\\])$-$1\\-o;	    # ensure path ends with a backslash
       
   229 $thisdir=~s-^.:\\--o;		    # remove drive letter and leading backslash
       
   230 
       
   231 my $rominclude = "$epoc32/rom/include";
       
   232 my %plugintypes; #hash of plugin types and their SPI files' destinations in ROM
       
   233 $plugintypes{"ECOM"} = "\\private\\10009d8f\\"; #ECOM SPI files' destination in ROM image
       
   234 
       
   235 my @obydata;
       
   236 my @newobydata;
       
   237 my %substitutionData;
       
   238 my @substitutionOrder;
       
   239 my %languageCodes;
       
   240 my $defaultLanguageCode;
       
   241 my %multiLinguifyAlias;  # to by-pass the 'mustbesysbin' option for multilinguify 'alias'es. 
       
   242 my $abiDowngrade;
       
   243 my @binarySelectionOrder;
       
   244 my $fromDIR;
       
   245 my %rombuildOptions = ("-type-safe-link" => 1 );
       
   246 my $enforceSysBin = 0;
       
   247 
       
   248 my $line;
       
   249 my $errors = 0;
       
   250 my @romimage;
       
   251 my $rombasename;
       
   252 
       
   253 my $sourcefile;
       
   254 my $sourceline;
       
   255 my ($line);
       
   256 my %romfiles;
       
   257 
       
   258 # To handle BINARY_SELECTION_ORDER macro.
       
   259 my $firstDIR;
       
   260 my $binarySelectionOrderFlag = 0;
       
   261 
       
   262 my %DllDataMap = ();	#Map to keep track of DLL Data patch statements.
       
   263 my $patchDataStmtFlag = 0;
       
   264 
       
   265 my $featuremanager = 0; #Flag to enable support for feature manager database XML file and to generate  
       
   266 			# features data file.
       
   267 my $noFeatureManager = 0; # Flag to stop the generation of features.dat file and use pre-built features.dat if provided.
       
   268 my $preBuiltFeaturesDataFile  = ''; # To store the name of pre-built features.dat file provided with "-nofm" option.
       
   269 
       
   270 #Image Content XML file that supports specific feature to be added
       
   271 my $image_content = undef;
       
   272 #Feature list XML file that acts as database containing all features details
       
   273 my $featureXml = undef;
       
   274 my $geninc = "";
       
   275 my $gendep = "";
       
   276 my $nosymbols = "";
       
   277 my $noimage = "";
       
   278 my $customizedPlat = undef;
       
   279 my $opt_fastcompress = "";
       
   280 my $opt_jobs= "";
       
   281 
       
   282 #Summary of files(both executables and data files) currently includes 
       
   283 #	host and ROM file names, 
       
   284 #	size of the file in ROM
       
   285 #	whether the file is hidden
       
   286 # This option is added so that the above additional information is emitted by rombuild/rofsbuild tools
       
   287 # only when supplied with this option so that the existing tools don't get affected.
       
   288 my $logLevel="";
       
   289 
       
   290 # This option is used to pass -lowmem argument to rombuild/rofsbuild tools
       
   291 my $lowMem="";
       
   292 
       
   293 # Feature Variation modules and data
       
   294 use featurevariantparser;
       
   295 use featurevariantmap;
       
   296 my %featureVariant;
       
   297 
       
   298 # global variables specific to data drive image generation. 
       
   299 use File::Path;					# Module to provide functions to remove or create directories in a convenient way.
       
   300 use File::Copy;					# Module to provide functions to copy file(s) from source to destination.
       
   301 use File::Find;
       
   302 use datadriveimage;				# module which provides all necessary functions to create data drive image.
       
   303 my $ZDirloc = "";				# location of Z drive directory.
       
   304 my $DataDriveDirloc = "";		# location of data drive directory.
       
   305 my @sisfilelist;				# an array to hold sis file(s).
       
   306 my @zDriveImageList;			# an array to hold z drive image name.
       
   307 my @datadiveobydata;			# an array to hold data drive oby data.
       
   308 my @datadriveimage;				# array which holds data drive image attribute.
       
   309 my $rootdir = "";				# which holds root directory information.
       
   310 my @datadrivedata;				# array to maintain list of lines taken from processed data drive oby file.
       
   311 my @nonsisFilelist;				# array to maintain list of nonsis file(s). 
       
   312 my @sisobydata;					# array to maintain all list of files(s) got by installing sis files. 
       
   313 my @renameList;					# array to maintain list of file(s) that has to be renamed.
       
   314 my @aliaslist;					# array to maintain list of file(s) that has to be made alias.
       
   315 my @hideList;					# array to maintain list of file(s) that has to be made hidden.
       
   316 my $sisfilepresent = 0;			# enable if sis file(s) are present.
       
   317 my $stubsisfilepresent = 0;		# enable if stub-sis file(s) are present.
       
   318 my $opt_k = 0;					# enable if keepgoing option is specified by the user.
       
   319 my $opt_r = 0;					# enable if retain pre-existence of folder is specified by the user.
       
   320 my $dataImageCount = 0;			# no of data drive image that has to generated.
       
   321 my @zdriveImageName;			# list of Z drive image name(s) specified using zdriveimagename in oby/iby file.
       
   322 my $opt_zimage = 0;				# enable if z drive image is found.
       
   323 my $zDrivePresent = 0;			# flag to check whether Z drive needs to be created.
       
   324 my @dataDriveFileList;			# list of processed data drive related files.
       
   325 my $paraFile = undef;			# parameter file for interpretsis.
       
   326 my @romImages;					# list of generated z drive image(s)(rom/rofs). 
       
   327 my $imageEntryLogFile = undef;	# a log file to log all the z drive image contents.
       
   328 my $opt_logFile = 0;			# enable if z drive entries has to be logged on to a log file.
       
   329 my %dataIndexHash = ();			# a hash which holds key-value pair between datadrive index and datadrive image count.
       
   330 my $interpretsisOpt = undef;	# enable if command line arguments are specified by the user to INTERPRETSIS.
       
   331 my @interpretsisOptList;		# an array which holds all the list of option(s) that needs to passed to INTERPRETSIS. 
       
   332 my @Global_BPABIPlats;
       
   333 my @Global_PlatList;
       
   334 my @smrImageFileList;
       
   335 my $needSmrImage = 0;
       
   336 my %smrPartitions;
       
   337 my %smrNameInfo;
       
   338 my @obeyFileList;
       
   339 my $smrNoImageName = 0;
       
   340 my $onlysmrimage = 1;
       
   341 
       
   342 sub match_obyfile
       
   343 {
       
   344 	my ($obyfile) = @_;
       
   345 	if (-f $obyfile)
       
   346 	{
       
   347 		push @obyfiles, $obyfile;
       
   348 		return 1;
       
   349 	}
       
   350 
       
   351 	# search for the oby file in the list of include directories
       
   352 	my @otherDirs = ($rominclude);
       
   353 
       
   354 	if ($featureVariant{'VALID'})
       
   355 	{
       
   356 		my $dirRef = $featureVariant{'ROM_INCLUDES'};
       
   357 
       
   358 		@otherDirs = @$dirRef if ($dirRef);
       
   359 	}
       
   360 	foreach my $dir (@otherDirs)
       
   361 	{
       
   362 		if (-f "$dir/$obyfile")
       
   363 		{
       
   364 		    push @obyfiles, "$dir/$obyfile";
       
   365 		    return 1;
       
   366 		}
       
   367 	}
       
   368 	return 0;
       
   369 }
       
   370 
       
   371 
       
   372 # This function invokes ROFSBUILD tool with appropriate parameters to generate data drive image.
       
   373 # It also deletes zdrive and datadrive folder after all the image has been processed and generated
       
   374 # if and only if preserve(-p) option is disabled.
       
   375 sub create_datadriveImage
       
   376 {
       
   377 	for (my $dataidx=0; $dataidx < $dataImageCount; $dataidx++)
       
   378 	{
       
   379 		my $driveIndex = $dataIndexHash{$dataidx};
       
   380 
       
   381 		if(defined($driveIndex))
       
   382 		{
       
   383 			my $obeyfile=$datadriveimage[$driveIndex]{obeyfile};
       
   384 			my $compress=$datadriveimage[$driveIndex]{compress};
       
   385 			my $uncompress=$datadriveimage[$driveIndex]{uncompress};
       
   386 
       
   387 			if ($obeyfile)
       
   388 			{
       
   389 				if(!defined $opt_compression)
       
   390 				{
       
   391 					if ($compress ne 0)
       
   392 					{
       
   393 						$compress=" -compress";
       
   394 					}
       
   395 					elsif($uncompress ne 0)
       
   396 					{
       
   397 						$compress=" -uncompress";
       
   398 					}
       
   399 					elsif($compress eq 0)
       
   400 					{
       
   401 						$compress=" ";
       
   402 					}
       
   403 				}
       
   404 				else
       
   405 				{
       
   406 					$compress = $opt_compression;
       
   407 					$compress =~m/\s-(compression)(method)\s(none|inflate|bytepair)/;
       
   408 					print "* ".$1." ".$2.": ".$3;
       
   409 				}
       
   410 				my $command = "rofsbuild -slog".$compress." -datadrive=$obeyfile.oby";
       
   411 				print "* Executing $command\n" if ($opt_v);
       
   412 				system($command);
       
   413 				if ($? != 0)
       
   414 				{
       
   415 					&datadriveimage::reportError("* ROFSBUILD failed to generate data drive image",$opt_k);
       
   416 				}
       
   417 				else
       
   418 				{
       
   419 					push(@dataDriveFileList,$obeyfile.".img");
       
   420 				}
       
   421 			}
       
   422 		}
       
   423 	}
       
   424 	# after processing all the data drive image(s) delete zdrive and datadrive directory 
       
   425 	# if and only if preserve(-p) option is disabled.
       
   426 	if($dataImageCount)
       
   427 	{
       
   428 		# delete Z drive directory if and only if preserve(-p) option is disabled.
       
   429 		my $retVal = &deleteDirectory($ZDirloc,$opt_v)if(!($preserve));
       
   430 		if($retVal)
       
   431 		{
       
   432 			&datadriveimage::reportError("* Warning could not delete $ZDirloc",$opt_k);
       
   433 		}
       
   434 		# delete data drive directory if and only if preserve(-p) option is disabled.
       
   435 		my $retVal = &deleteDirectory($DataDriveDirloc,$opt_v)if(!($preserve));
       
   436 		if($retVal)
       
   437 		{
       
   438 			&datadriveimage::reportError("* Warning could not delete $DataDriveDirloc",$opt_k);
       
   439 		}
       
   440 		# reset image count to zero.
       
   441 		$dataImageCount = 0;
       
   442 		# reset z drive present to zero.
       
   443 		$zDrivePresent = 0;
       
   444 	}
       
   445 }
       
   446 
       
   447 sub tidy_exit
       
   448 {
       
   449 	#-------------------------------------------------------
       
   450 	# Tidy and exit
       
   451 	
       
   452 	if (!$preserve)
       
   453 	{
       
   454 	    foreach my $tempfiles (@tempfiles)
       
   455 	    {
       
   456 			unlink "$tempfiles";
       
   457 	    }
       
   458 	}
       
   459 	if($rombasename)
       
   460 	{
       
   461 		system("dir $rombasename.*");
       
   462 	}
       
   463 	if(@dataDriveFileList)
       
   464 	{
       
   465 		print "\n";
       
   466 		print " ----------------------------------------------------------\n";
       
   467 		print "| List of file(s) generated pertaining to data drive image |\n";
       
   468 		print " ----------------------------------------------------------\n";
       
   469 		my $arraySize = scalar(@dataDriveFileList);
       
   470 		for( my $i=0; $i < $arraySize; $i++ )
       
   471 		{
       
   472 			# remove the first element from an array and return it 
       
   473 			my $element = shift(@dataDriveFileList);
       
   474 			# get the size of the file.
       
   475 			my $size = -s $element;
       
   476 			print "Size = ".$size." bytes"."\t"."File = ".$element."\n";
       
   477 		}
       
   478 	}
       
   479 	exit(0);
       
   480 }
       
   481 
       
   482 # This is the main function which is responsible for processing data drive image.
       
   483 # This function internally calls other functions to create datadrive folder,zdrive folder
       
   484 # and external tools such as INTERPRETSIS, READIMAGE and finally ROFSBUILD to generate 
       
   485 # appropriate data drive image.
       
   486 sub processData		
       
   487 {
       
   488 	if($dataImageCount)
       
   489 	{
       
   490 		# set the default path for Z drive and Data drive directory,
       
   491 		# if and only if, path is not specified by the user. 
       
   492 		$ZDirloc = &datadriveimage::setPath("zdrive") unless ($ZDirloc);
       
   493 		$DataDriveDirloc = &datadriveimage::setPath("datadrive") unless ($DataDriveDirloc);
       
   494 		#delete any existing Z drive directory.
       
   495 		my $retVal = &datadriveimage::deleteDirectory($ZDirloc,$opt_v)if(!$opt_r);
       
   496 		if($retVal)
       
   497 		{
       
   498 			exit(1) if(!$opt_k);
       
   499 		}
       
   500 		# delete pre-existence of data drive folder, if and only if -r option is not enabled.
       
   501 		my $retVal = &datadriveimage::deleteDirectory($DataDriveDirloc,$opt_v) if(!$opt_r);
       
   502 		if($retVal)
       
   503 		{
       
   504 			exit(1) if(!$opt_k);
       
   505 		}
       
   506 		if($opt_logFile)
       
   507 		{
       
   508 			# clean any pre-existance of log file.
       
   509 			unlink($ZDirloc."\\".$imageEntryLogFile);
       
   510 		}
       
   511 		
       
   512 		for (my $datadriveidx=0; $datadriveidx < $dataImageCount; $datadriveidx++)
       
   513 		{
       
   514 			my $driveIndex = $dataIndexHash{$datadriveidx};
       
   515 			# get the data drive name.
       
   516 			if( defined( $driveIndex ) )
       
   517 			{
       
   518 				my $datadrivename=$datadriveimage[$driveIndex]{obeyfile};
       
   519 				# get the size of the data drive.
       
   520 				my $size = $datadriveimage[$driveIndex]{size};
       
   521 				if( $datadrivename )
       
   522 				{
       
   523 					# set data drive oby file.
       
   524 					my $datadriveobyfile = $datadrivename.".oby";
       
   525 					# final location of prototype data drive.
       
   526 					my $proDataDriveDirloc;
       
   527 					# Location of stub-sis file(s) inside Z Drive folder.
       
   528 					my $zDriveSisFileLoc;
       
   529 					# check if more than one data drive image needs to be generated. 
       
   530 					if( $dataImageCount > 1 )
       
   531 					{
       
   532 						# if yes, then set the location of prototype data drive folder as 
       
   533 						# DataDriveDirloc + datadrivename
       
   534 						$proDataDriveDirloc = $DataDriveDirloc."\\".$datadrivename;
       
   535 					}
       
   536 					else
       
   537 					{
       
   538 						# else, then set the location of prototype data drive folder as DataDriveDirloc 
       
   539 						$proDataDriveDirloc = $DataDriveDirloc;
       
   540 					}
       
   541 
       
   542 					# create prototype data drive folder.
       
   543 					print "creating data drive folder\n" if ($opt_v);
       
   544 					&datadriveimage::createDirectory($proDataDriveDirloc);
       
   545 
       
   546 					# check for sis file keyword in ROM description file.
       
   547 					# if found,then locate for stub-sisfile.
       
   548 					# create Z drive( if and only if stub-sis files are present in ROM description file )
       
   549 					# and dump all the non-sis files on to the Z drive folder. 
       
   550 					if(&datadriveimage::checkForSisFile($datadriveobyfile,\@sisfilelist,\$sisfilepresent))
       
   551 					{
       
   552 						my $zDriveImagePresent = 0; # flag to check whether z drive image is Present;
       
   553 						if(&datadriveimage::checkForZDriveImageKeyword($datadriveobyfile,\@zDriveImageList,\$zDriveImagePresent) )
       
   554 						{
       
   555 							# find out size of the array
       
   556 							my $arraysize = scalar(@zDriveImageList);
       
   557 							for( my $i=0; $i < $arraysize; $i++ )
       
   558 							{
       
   559 								$zDriveSisFileLoc =  $ZDirloc."\\".$datadrivename;
       
   560 								&datadriveimage::invokeReadImage(pop(@zDriveImageList),$zDriveSisFileLoc,$opt_v,$imageEntryLogFile,$opt_k);
       
   561 							}
       
   562 						}
       
   563 						else
       
   564 						{
       
   565 							$zDriveSisFileLoc = $ZDirloc;
       
   566 							# locate and copy stub-sis file(s),for the first time.
       
   567 							if( !$zDrivePresent )
       
   568 							{
       
   569 								# check for image file.
       
   570 								if( $opt_zimage )
       
   571 								{
       
   572 									# image(s)supplied to BUILDROM(like rom,rofs,extrofs or core) using "-zdriveimage" option, 
       
   573 									# are maintained in a seperate array and the element from the array is fetched one by one and is 
       
   574 									# fed to READIMAGE as an input.
       
   575 									foreach my $element (@zdriveImageName)
       
   576 									{
       
   577 										# invoke READIMAGE to extract all /swi stub sis file(s) from the given image.
       
   578 										$zDrivePresent = &datadriveimage::invokeReadImage($element,$zDriveSisFileLoc,$opt_v,$imageEntryLogFile,$opt_k);
       
   579 									}
       
   580 								}
       
   581 								else
       
   582 								{
       
   583 									# if zdrive image(s) such as (rom,core,rofs or extrofs) are generated ealier to the data drive image processing
       
   584 									# then these images are maintained in an array and the element from the array is fetched one by one and is 
       
   585 									# fed to READIMAGE as an input.
       
   586 									foreach my $element (@romImages)
       
   587 									{
       
   588 										# invoke READIMAGE to extract all /swi stub sis file(s) from the given image.
       
   589 										$zDrivePresent = &datadriveimage::invokeReadImage($element,$zDriveSisFileLoc,$opt_v,$imageEntryLogFile,$opt_k);
       
   590 									}
       
   591 								}
       
   592 							}
       
   593 						}
       
   594 						# invoke INTERPRETSIS tool with z drive folder location.
       
   595 						&datadriveimage::invokeInterpretsis( \@sisfilelist,$proDataDriveDirloc,$opt_v,$zDriveSisFileLoc,$paraFile,$opt_k,\@interpretsisOptList)if($sisfilepresent);
       
   596 					}
       
   597 
       
   598 					# create an oby file by traversing through upated prototype data drive directory.
       
   599 					&datadriveimage::dumpDatadriveObydata( $proDataDriveDirloc,$datadriveobyfile,$size,\@nonsisFilelist,
       
   600 										\@renameList,\@aliaslist,\@hideList,\@sisobydata,\@datadrivedata,$opt_k,$opt_v );
       
   601 					#reset sisfilepresent flag to zero;
       
   602 					$sisfilepresent =0;
       
   603 				}
       
   604 			}
       
   605 		}
       
   606 		create_datadriveImage();
       
   607 	}
       
   608 	tidy_exit;
       
   609 }
       
   610 #Parse and process image content xml file
       
   611 #Gets the oby files listed in the xml file
       
   612 # Pushes all the oby files found to an array
       
   613 
       
   614 sub image_content_processing_phase
       
   615 {
       
   616 	if(!defined ($image_content))
       
   617 	{
       
   618 		return;
       
   619 	}
       
   620 	&ImageContentHandler::ParseImageContentXML($image_content);
       
   621 	&ImageContentHandler::ProcessImageContent;
       
   622 
       
   623 	if(defined ($image_content) )
       
   624 	{
       
   625 #		Collect the oby files if any in the Image content file
       
   626 		my $files = &ImageContentHandler::GetObyFiles;
       
   627 		foreach my $obeyfile (@$files)
       
   628 		{
       
   629 			next if match_obyfile($obeyfile);
       
   630 			next if (match_obyfile("$obeyfile.oby"));
       
   631 		}
       
   632 	}
       
   633 }
       
   634 
       
   635 # Subroutine to process parameter-file
       
   636 sub parameterFileProcessor
       
   637 {
       
   638 	my $paramFile = shift(@_);	
       
   639 	my @paramFileParamaters = ();	
       
   640 
       
   641 	my $fileOpenFlag = 1;
       
   642 	open FILE,"<", $paramFile or $fileOpenFlag = 0;
       
   643 	
       
   644 	if(!$fileOpenFlag)
       
   645 	{
       
   646 		print "Error: Could not open parameter-file \"$paramFile\" for reading.\n";
       
   647 		return;
       
   648 	}
       
   649 	
       
   650 	# Parse parameter-file and collect all the parameters in an array
       
   651 	while(my $line = <FILE>)
       
   652 	{
       
   653 		# Read the line till character ';'(used for providing comments in the file) or EOL
       
   654 		$line = $1 if ($line =~ /(.*);/); 
       
   655 		
       
   656 		# Split the parameters specified in a line based on white-spaces		
       
   657 		my @paramaters = split(/(\s)/,$line);	
       
   658 		
       
   659 		my $flag = 0;
       
   660 		my $argWithQuotes='';
       
   661 
       
   662 		foreach my $value (@paramaters) 
       
   663 		{	
       
   664 			# If the parameter doesn't conatian double quotes then push it 
       
   665 			# to the list of parameters.
       
   666 			if(($value !~ /\"/) && (!$argWithQuotes)) 
       
   667 			{
       
   668 				if ($value !~ /^\s*$/) 
       
   669 				{
       
   670 					push @paramFileParamaters,$value;
       
   671 				}		
       
   672 			}
       
   673 			# If the parameter is in the form  -fm="faturedb.xml" then remove
       
   674 			# double quotes and push it to the list of parameters.
       
   675 			elsif(($value =~ /\".*\"/))
       
   676 			{
       
   677 				$value =~ s/\"//g;
       
   678 				push @paramFileParamaters,$value;
       
   679 			}
       
   680 			# If the parameter is in the form  -fm="fature  db.xml" then read
       
   681 			# the parameter starting from opening quote till the closing quote.
       
   682 			elsif( ($value =~ /\"/) && $argWithQuotes) 
       
   683 			{
       
   684 				$argWithQuotes .= $value;
       
   685 				$argWithQuotes =~ s/\"//g;
       
   686 				push @paramFileParamaters,$argWithQuotes;
       
   687 				$argWithQuotes='';		
       
   688 			}
       
   689 			else
       
   690 			{
       
   691 				$argWithQuotes .= $value;
       
   692 			}
       
   693 		}		
       
   694 	}
       
   695 
       
   696 	close FILE;	
       
   697 
       
   698 	if (!@paramFileParamaters)
       
   699 	{
       
   700 		print "Warning: No parameters specified in paramer-file \"$paramFile\".\n";		
       
   701 		return;
       
   702 	}
       
   703 	
       
   704 	my $paramFileFlag = 1;
       
   705 
       
   706 	# Invoke subroutine "process_cmdline_arguments" to process the parameters read from
       
   707 	# the parameter file.
       
   708 	&process_cmdline_arguments($paramFileFlag, @paramFileParamaters);
       
   709 
       
   710 }
       
   711 
       
   712 # Processes the command line arguments passed to buildrom tool
       
   713 
       
   714 sub process_cmdline_arguments
       
   715 {
       
   716    	my %tmpBldRomOpts;
       
   717 
       
   718 	my ($paramFileFlag, @argList); 
       
   719 
       
   720 	if (defined @_)
       
   721 	{
       
   722 		($paramFileFlag, @argList) = @_;
       
   723 	}
       
   724 	else
       
   725 	{
       
   726 		@argList = @ARGV;
       
   727 	}
       
   728 
       
   729 	if (!defined $paramFileFlag) 
       
   730 	{
       
   731 		# Enforce Feature Manager if macro SYMBIAN_FEATURE_MANAGER is defined in the HRH file.
       
   732 		my @hrhMacros = &Variant_GetMacroList;	
       
   733 		if (grep /^SYMBIAN_FEATURE_MANAGER\s*$/, @hrhMacros)
       
   734 		{
       
   735 			$enforceFeatureManager = 1;
       
   736 		}
       
   737 		
       
   738 		# Process the parameters of parameter-file if passed.
       
   739 		foreach my $arg (@argList)
       
   740 		{
       
   741 			if ($arg =~ /^-argfile=(.*)/) 
       
   742 			{
       
   743 				&parameterFileProcessor($1);				
       
   744 			}
       
   745 		}
       
   746 	}
       
   747 
       
   748 	foreach my $arg (@argList)
       
   749 	{
       
   750 	    if ($arg =~ /^-argfile=(.*)/) 
       
   751 		{
       
   752 			&parameterFileProcessor($1) if (defined $paramFileFlag);						
       
   753 			next;			
       
   754 		}
       
   755 		if ($arg =~ /^-[DI]/)
       
   756 	    {
       
   757 		$cppargs .= " $arg";
       
   758 		#Set 'udeb' for debug option 
       
   759 		if($arg =~ /^-D_FULL_DEBUG/)
       
   760 		{
       
   761 		    $tmpBldRomOpts{"BUILD_DIR"} = "udeb";
       
   762 		}
       
   763 		#Set specific platform supplied from the command option 
       
   764 		elsif($arg =~ /^-D_PLAT=(.*)/)
       
   765 		{
       
   766 		    $tmpBldRomOpts{"ABI_DIR"} = $1;
       
   767 		}
       
   768 		# Check for a Feature Variant
       
   769 		elsif ($arg =~ /^-DFEATUREVARIANT=(.*)/)
       
   770 		{
       
   771 			my $varname = $1;
       
   772 			
       
   773 			if ($varname =~ /^\.(.*)$/)
       
   774 			{
       
   775 				# for testing, locate the VAR file in the current directory
       
   776 				%featureVariant = featurevariantparser->GetVariant($1, ".");
       
   777 			}
       
   778 			else
       
   779 			{
       
   780 				%featureVariant = featurevariantparser->GetVariant($varname);
       
   781 			}
       
   782 			if (!$featureVariant{'VALID'})
       
   783 			{
       
   784 			    print "FEATUREVARIANT $varname is not VALID\n";
       
   785 				$errors++;
       
   786 			}
       
   787 			if ($featureVariant{'VIRTUAL'})
       
   788 			{
       
   789 			    print "FEATUREVARIANT $varname is VIRTUAL\n";
       
   790 				$errors++;
       
   791 			}
       
   792 			addDrivesToFeatureVariantPaths();
       
   793 		}
       
   794 		next;
       
   795 	    }
       
   796 	    if ($arg =~ /^-o(.*)/i)
       
   797 	    {
       
   798 		$opt_o = $1;
       
   799 		next;
       
   800 	    }
       
   801 	    if ($arg =~ /^-fastcompress$/i)
       
   802 	    {
       
   803 		    $opt_fastcompress = "-fastcompress";
       
   804 		    next;
       
   805 	    }
       
   806 	    if ($arg =~ /^-j(\d+)$/i)
       
   807 	    {
       
   808 		    $opt_jobs = "-j".$1;
       
   809 		    next;
       
   810 	    }
       
   811 	    if ($arg =~ /^-v$/)
       
   812 	    {
       
   813 		$opt_v =1;
       
   814 		next;
       
   815 	    }
       
   816 	    if ($arg =~ /^-s$/)
       
   817 	    {
       
   818 		$strict = 1;
       
   819 		next;
       
   820 	    }
       
   821 	    if ($arg =~ /^-w$/)
       
   822 	    {
       
   823 		$warnSelection = 1;
       
   824 		next;
       
   825 	    }
       
   826 	    if ($arg =~ /^-p$/)
       
   827 	    {
       
   828 		$preserve = 1;
       
   829 		next;
       
   830 	    }
       
   831 	    if ($arg =~ /^-nospi$/)
       
   832 	    {
       
   833 		$createspi=0;
       
   834 		$spiset=1;
       
   835 		next;
       
   836 	    }
       
   837 	    if ($arg =~ /^-spi$/)
       
   838 	    {
       
   839 		$createspi=1;
       
   840 		$spiset=1;
       
   841 		next;
       
   842 	    }	
       
   843 	    #Process External Tool
       
   844 	    if ($arg =~/^-e(.*)/)#Match to get the tool perl module files
       
   845 	    {
       
   846 		&externaltools::loadTools($1);
       
   847 		next;
       
   848 	    }
       
   849    		#Process imagecontent file 
       
   850 	    if( $arg =~ /^-i(.*)/)
       
   851 	    {
       
   852 # Disabling -i option
       
   853 		print "Warning: Ignoring invalid Option $arg \n";
       
   854 		next;
       
   855 	    }
       
   856 		#Process feature manager database xml file 
       
   857 	    if($arg =~ /^-fm=(.*)/)
       
   858 	    {
       
   859 			if (!$enforceFeatureManager) 
       
   860 			{
       
   861 				print "Unknown arg: $arg\n";
       
   862 				$errors++;
       
   863 				next;
       
   864 			}
       
   865 			$featureXml = $1;
       
   866 			$xmlrequired = 1;
       
   867 			$featuremanager = 1;
       
   868 			if ($featureXml =~ /^$/) 
       
   869 			{
       
   870 				print "Error: No filename specified with \"-fm=\" option.\n";
       
   871 			}			
       
   872 			next;
       
   873 	    }
       
   874 	    #Process ROM image compression type if it's specified through command line option.
       
   875 	    if($arg =~ /^-compress(.*)/)
       
   876 	    {
       
   877 	    	if($1 eq '')
       
   878 	    	{
       
   879 	    		$opt_compression_type = ALLSECTIONS;
       
   880 	    		print "Whole ROM image will be compressed.\n";
       
   881 	    	}
       
   882 	    	elsif($1 eq '=paged')
       
   883 	    	{
       
   884 	    		$opt_compression_type = PAGEDSECTION;
       
   885 	    		print "Paged section of the ROM image will be compressed.\n";
       
   886 	    	}
       
   887 	    	elsif($1 eq '=unpaged')
       
   888 	    	{
       
   889 	    		$opt_compression_type = UNPAGEDSECTION;
       
   890 	    		print "Unpaged section of the ROM image will be compressed.\n";
       
   891 	    	}
       
   892 	    	else
       
   893 	    	{
       
   894 	    		print "Unknown compression type: $1\n";
       
   895 	    		$errors++;
       
   896 	    	}
       
   897 	    	next;
       
   898 	    }
       
   899 		if ($arg =~ /^-nofm(=(.*))?$/)
       
   900 		{
       
   901 			if (!$enforceFeatureManager) 
       
   902 			{
       
   903 				print "Unknown arg: $arg\n";
       
   904 				$errors++;
       
   905 				next;
       
   906 			}
       
   907    			$noFeatureManager = 1;
       
   908             #DEF125375 If caller is simply giving -nofm without any parameter, a warning message will be given.
       
   909             if(!$2)
       
   910             {
       
   911                 print "Warning: No filename specified with \"-nofm=\" option, feature data file might not be included.\n";
       
   912             }
       
   913             else
       
   914             {
       
   915                 $preBuiltFeaturesDataFile = $2;						
       
   916             }
       
   917 			next;	
       
   918 		}
       
   919 		#Process feature registry database xml file 
       
   920 	    if($arg =~ /^-fr=(.*)/ || $arg =~ /^-f(.*)/)
       
   921 	    {
       
   922 			if ($enforceFeatureManager)
       
   923 			{
       
   924 				print "Error: Option \"-f|-fr\" is no longer supported.\n";
       
   925 				$errors++;
       
   926 				next;
       
   927 			}			
       
   928 			$featureXml = $1;
       
   929 			$xmlrequired = 1;			
       
   930 			if ($featureXml =~ /^$/) 
       
   931 			{
       
   932 				print "Error: No filename specified with \"-f|-fr\" option.\n";				
       
   933 			}
       
   934 			next;
       
   935 	    }
       
   936 	    if ($arg =~ /^-spiplacement$/)
       
   937 	    {
       
   938 			$spiplacement = 1;
       
   939 			next;
       
   940 	    }
       
   941 		if ($arg =~ /^-noimage$/)
       
   942 		{
       
   943 			$noimage=1;
       
   944 			next;	
       
   945 		}
       
   946 		if ($arg =~ /^-nosymbols$/)
       
   947 		{
       
   948 			$nosymbols=1;
       
   949 			next;	
       
   950 		}
       
   951 		if ($arg =~ /^-geninc$/)
       
   952 		{
       
   953 			$geninc=1;
       
   954 			next;	
       
   955 		}
       
   956 		if($arg =~ /^-gendep$/)
       
   957 		{
       
   958 			$gendep=1;
       
   959 			next;
       
   960 		}
       
   961         if($arg =~/^-c(.*)/)
       
   962         {
       
   963           if($1 eq 'none' )
       
   964           {
       
   965               $opt_compression = " -compressionmethod none";
       
   966           }
       
   967           elsif($1 eq 'inflate' )
       
   968           {
       
   969               $opt_compression = " -compressionmethod inflate";
       
   970           }
       
   971           elsif($1 eq 'bytepair' )
       
   972           {
       
   973               $opt_compression = " -compressionmethod bytepair";
       
   974           }
       
   975           else
       
   976           {
       
   977               print "Unknown compression method: $1\n";
       
   978               $errors++;
       
   979           }
       
   980           next;
       
   981         }
       
   982 		if( $arg =~ /^-loglevel\d+$/)
       
   983 		{
       
   984 			$logLevel= $arg;
       
   985 			next;
       
   986 		}
       
   987 		# get Z directory location if specified by the user.
       
   988 		# if yes, then extract directory location from the given array element. 
       
   989 		if( $arg =~ /^-z=(.*)/  || $arg =~ /^-zdrivepath=(.*)/i )
       
   990 		{
       
   991 			# check for white space in the specified folder path
       
   992 			# if "yes" then warn the user saying folder will be created under default location.
       
   993 			# else set the path specified by the user.
       
   994 			if(&datadriveimage::checkForWhiteSpace($1,"zdrive"))
       
   995 			{
       
   996 				next;
       
   997 			}
       
   998 			else
       
   999 			{
       
  1000 				$ZDirloc  = $1;
       
  1001 				if( $ZDirloc !~ m/\\(\Z)/)
       
  1002 				{ 
       
  1003 					$ZDirloc .= "\\"; 
       
  1004 				}
       
  1005 				if( $ZDirloc !~ m/:/)
       
  1006 				{
       
  1007 					print "drive letter not specified\n";
       
  1008 					$ZDirloc = &datadriveimage::setPath($ZDirloc);
       
  1009 				}
       
  1010 				print "Z Drive directory location = $ZDirloc\n";
       
  1011 				#set the location of Z Drive directory.
       
  1012 				$ZDirloc .= "zdrive";
       
  1013 			}
       
  1014 			next;
       
  1015 		}
       
  1016 		# get data directory location if specified by the user.
       
  1017 		# if yes, then extract directory location from the given array element. 
       
  1018 		if( $arg =~ /^-d=(.*)/ || $arg =~ /^-datadrivepath=(.*)/i )
       
  1019 		{
       
  1020 			# check for white space in the specified folder path
       
  1021 			# if "yes" then warn the user saying folder will be created under default location.
       
  1022 			# else set the path specified by the user.
       
  1023 			if(&datadriveimage::checkForWhiteSpace($1,"datadrive"))
       
  1024 			{
       
  1025 				next;
       
  1026 			}
       
  1027 			else
       
  1028 			{
       
  1029 				$DataDriveDirloc = $1;
       
  1030 				if( $DataDriveDirloc !~ m/\\(\Z)/)
       
  1031 				{ 
       
  1032 					$DataDriveDirloc .= "\\"; 
       
  1033 				}
       
  1034 				if( $DataDriveDirloc !~ m/:/)
       
  1035 				{
       
  1036 					print "drive not specified\n";
       
  1037 					$DataDriveDirloc = &datadriveimage::setPath($DataDriveDirloc);
       
  1038 				}
       
  1039 				print "Data Drive directory location = $DataDriveDirloc\n";
       
  1040 				#set the location of Data Drive directory.
       
  1041 				$DataDriveDirloc .= "datadrive";
       
  1042 			}
       
  1043 			next;
       
  1044 		}
       
  1045 		# get Z dive image if specified by the user.
       
  1046 		if( $arg =~ /^-zdriveimage=(.*)/i )	
       
  1047 		{
       
  1048 			my $imageName = $1;
       
  1049 			if( $imageName =~ m/\,/)
       
  1050 			{
       
  1051 				@zdriveImageName = split(/\,/,$imageName);
       
  1052 			}
       
  1053 			else
       
  1054 			{
       
  1055 				push(@zdriveImageName,$imageName);
       
  1056 			}
       
  1057 			$opt_zimage = 1;
       
  1058 			next;
       
  1059 		}
       
  1060 		# get command line arguments which needs to be passed to INTERPRETSIS, if specified by the user.
       
  1061 		if( $arg =~ /^-argforinterpretsis=(.*)/i )	
       
  1062 		{
       
  1063 			my $interpretsisOpt = $1;
       
  1064 			if( $interpretsisOpt =~ m/\,/)
       
  1065 			{
       
  1066 				@interpretsisOptList = split(/\,/,$interpretsisOpt);
       
  1067 			}
       
  1068 			else
       
  1069 			{
       
  1070 				push(@interpretsisOptList,$interpretsisOpt);
       
  1071 			}
       
  1072 			next;
       
  1073 		}
       
  1074 		if ( $arg =~ /^-k$/i || $arg =~ /^-keepgoing$/i )
       
  1075 	    {
       
  1076 			$opt_k = 1;
       
  1077 			next;
       
  1078 	    }
       
  1079 		if ( $arg =~ /^-r$/i || $arg =~ /^-retainfolder$/i )
       
  1080 	    {
       
  1081 			$opt_r = 1;
       
  1082 			next;
       
  1083 	    }
       
  1084 		if ( $arg =~ /^-pfile=(.*)/i )
       
  1085 	    {
       
  1086 			$paraFile = $1;
       
  1087 			next;
       
  1088 	    }
       
  1089 		if ( $arg =~ /^-l=(.*)/i || $arg =~ /^-logimageentry=(.*)/i )
       
  1090 	    {
       
  1091 			if( $1 =~/\\/ || $1 =~ m/:/)
       
  1092 			{
       
  1093 				print "* Warning: Invalid log file extension try filename.txt\n";
       
  1094 				next;
       
  1095 			}
       
  1096 			else
       
  1097 			{
       
  1098 				$opt_logFile = 1;
       
  1099 				$imageEntryLogFile = $1;
       
  1100 			}
       
  1101 			next;
       
  1102 	    }
       
  1103 		if ( $arg =~ /^-lowmem/i )
       
  1104 		{
       
  1105 			$lowMem = $arg;
       
  1106 			next;
       
  1107 		}
       
  1108 	    if ($arg =~ /^-/)
       
  1109 	    {
       
  1110 		print "Unknown arg: $arg\n";
       
  1111 		$errors++;
       
  1112 		next;
       
  1113 	    }
       
  1114 	    # It's an OBY file
       
  1115 	    next if (match_obyfile($arg));
       
  1116 	    next if (match_obyfile("$arg.oby"));
       
  1117 
       
  1118 	    print "Cannot find oby file: $arg\n";
       
  1119 	    $errors++;
       
  1120 	}
       
  1121 
       
  1122 	if (defined $paramFileFlag) 
       
  1123 	{
       
  1124 		return;
       
  1125 	}
       
  1126 	
       
  1127 	if (@obyfiles<1)
       
  1128 	{
       
  1129 	    print "Missing obyfile argument\n";
       
  1130 	    $errors++;
       
  1131 	}
       
  1132 
       
  1133 	if ($errors)
       
  1134 	{
       
  1135 	    print_usage();
       
  1136 	    exit 1;
       
  1137 	}
       
  1138 	
       
  1139 	if ($noFeatureManager && $featuremanager) 
       
  1140 	{
       
  1141 		print "Warning: Ignoring \"-nofm\" option, as both \"-nofm\" and \"-fm\" options are provided.\n";			
       
  1142 		$noFeatureManager = 0;
       
  1143 	}
       
  1144 
       
  1145 	# Adding variant specific macros by including a HRH file
       
  1146 	# (only required if no Feature Variant is used)
       
  1147 	if (!$featureVariant{'VALID'})
       
  1148 	{
       
  1149 	    my $variantMacroHRHFile = Variant_GetMacroHRHFile();
       
  1150 	    if($variantMacroHRHFile){
       
  1151 
       
  1152 	        my $variantFilePath = Path_Split('Path',$variantMacroHRHFile);
       
  1153 	        $cppargs .= " -I \"" . &Path_RltToWork($variantFilePath) . "\" -include \"" . &Path_RltToWork($variantMacroHRHFile) . "\""; 
       
  1154 	    }
       
  1155 	}
       
  1156 	# load the required modules if xml is required
       
  1157 	if ($xmlrequired == 1)
       
  1158 	{
       
  1159 	    my $epocToolsPath = $ENV{EPOCROOT}."epoc32\\tools\\";
       
  1160 	    Load_SetModulePath($epocToolsPath);
       
  1161 	    if (defined ($featureXml))
       
  1162 	    {
       
  1163 			load_featuresutil();
       
  1164 	    }
       
  1165 	
       
  1166 	    if ($image_content)
       
  1167 	    {
       
  1168 	    	&Load_ModuleL("ImageContentHandler");
       
  1169 	    	# some variables for ImageContentHandler may have been setup
       
  1170 	    	my ($key, $value);
       
  1171 	    	&ImageContentHandler::SetBldRomOpts; # Defaults to ARMV5 platform
       
  1172 	    	while (($key,$value) = each %tmpBldRomOpts)
       
  1173 	    	{
       
  1174 			&ImageContentHandler::SetBldRomOpts($key, $value);
       
  1175 	    	}
       
  1176 	    }
       
  1177 	    
       
  1178 	}
       
  1179 }
       
  1180 
       
  1181 #----------------------------------------------------------------------------------
       
  1182 # Preprocessing phase
       
  1183 #
       
  1184 # Concatentate the specified .oby files and pass them through cpp
       
  1185 # to get the raw ROM specification in tmp1.oby
       
  1186 
       
  1187 sub preprocessing_phase
       
  1188 {
       
  1189 	unlink "tmp1.oby";
       
  1190 
       
  1191 #	Macro "ROM_FEATURE_MANAGEMENT" is defined when "-f|fr" or "-fm" is used
       
  1192 	if (defined ($featureXml))
       
  1193 	{
       
  1194 		$cppargs .= " -DROM_FEATURE_MANAGEMENT ";
       
  1195 	}
       
  1196 
       
  1197 	# add pre-include file and include directories for feature variants
       
  1198 	if ($featureVariant{'VALID'})
       
  1199 	{
       
  1200 		$cppargs .= " -I.";
       
  1201 		my $incRef = $featureVariant{'ROM_INCLUDES'};
       
  1202 		if ($incRef)
       
  1203 		{
       
  1204 			foreach (@$incRef)
       
  1205 			{
       
  1206 		    	$cppargs .= " -I \"$_\"";
       
  1207 			}
       
  1208 		}
       
  1209 		my $HRH = $featureVariant{'VARIANT_HRH'};
       
  1210 		if ($HRH)
       
  1211 		{
       
  1212 		    $cppargs .= " -include \"$HRH\"";
       
  1213 		}
       
  1214 	}
       
  1215 	else
       
  1216 	{
       
  1217 		# no feature variant so use the standard includes
       
  1218 		$cppargs .= " -I. -I$rominclude";
       
  1219 	}
       
  1220 
       
  1221 	print "* cpp -o tmp1.oby $cppargs\n" if ($opt_v);
       
  1222 	
       
  1223 	$errors = 0;
       
  1224 	open CPP, "| cpp -o tmp1.oby $cppargs" or die "* Can't execute cpp";
       
  1225 	foreach my $arg (@obyfiles)
       
  1226 	{
       
  1227 		print CPP "\n#line 1 \"$arg\"\n";
       
  1228 	
       
  1229 		open OBY, $arg or die "* Can't open $arg";
       
  1230 		print "* reading $arg\n" if ($opt_v);
       
  1231 		while ($line=<OBY>)
       
  1232 		{
       
  1233 			print CPP $line;
       
  1234 		}
       
  1235 		close OBY;
       
  1236 	}
       
  1237 	close CPP;
       
  1238 	my $cpp_status = $?;
       
  1239 	die "* cpp failed\n" if ($cpp_status != 0 || !-f "tmp1.oby");
       
  1240 
       
  1241 	my $temp1OBYFile = "tmp1.oby";
       
  1242 	if( defined ($image_content))
       
  1243 	{
       
  1244 		#Read the OBY file that was generated by the pre-processor
       
  1245 		&ReadPreprocessedFile($temp1OBYFile);
       
  1246 
       
  1247 #		Check if the static dependencies of the OBY binaries are resolved.
       
  1248 		&ImageContentHandler::UpdateObyBinaryStaticDep();
       
  1249 		
       
  1250 		#Now append the files collected from cdfs.
       
  1251 		&ImageContentHandler::GenObyFile($temp1OBYFile);
       
  1252 	}
       
  1253 
       
  1254 	# Setup default rom configuration
       
  1255 	$romimage[0] = {xip=>1, compress=>0, extension=>0, composite=>"none",uncompress=>0 };
       
  1256 }
       
  1257 
       
  1258 sub ReadPreprocessedFile
       
  1259 {
       
  1260 #	Read the OBY file that was generated by the pre-processor. This OBY is a conglomeration of all the OBYs
       
  1261 #	passed directly to buildrom and/or the ones passed through Image Content XML.
       
  1262 #	It marks the binaries coming from OBY. This is required to be able to point out the binaries that are 
       
  1263 #	mentioned neither in the OBY nor in the CDF. Such binaries are arrived at through static dependencies
       
  1264 #	and need to be included in ROM.
       
  1265 
       
  1266 	my $temp1OBYFile = shift;
       
  1267 	my $tmpline;
       
  1268 	my $srcFileName;
       
  1269 	my $srcFilePath;
       
  1270 	my $dstFileName;
       
  1271 	my $dstFilePath;
       
  1272 	open (OBYFH, "$temp1OBYFile") or die("* Can't open $temp1OBYFile\n");
       
  1273 	while($tmpline =<OBYFH>) {
       
  1274 		if ($tmpline=~/(\S+)\s*=\s*(\S+)\s+(\S+)/) {#Get the first parameter (source File path) from oby line
       
  1275 			$srcFilePath = $2;
       
  1276 			$dstFilePath = $3;
       
  1277 
       
  1278 			if ($srcFilePath=~/.*\\(\S+)/) {
       
  1279 				$srcFileName = $1;
       
  1280 			}
       
  1281 			if ($dstFilePath=~/.*\\(\S+)/) {
       
  1282 				$dstFileName = $1;
       
  1283 			}
       
  1284 			my $binaryInfoRef = &cdfparser::GetBinaryInfo($dstFileName);
       
  1285 
       
  1286 			if(defined($binaryInfoRef)) 
       
  1287 			{
       
  1288 				#Found in CDF file
       
  1289 				if($binaryInfoRef->{IsFoundInCDF})
       
  1290 				{
       
  1291 					print "Warning: File $srcFileName mentioned in OBY as well as CDF file\n";
       
  1292 				}
       
  1293 			}
       
  1294 			else
       
  1295 			{
       
  1296 				#Found in OBY file
       
  1297 				&ImageContentHandler::AddBinaryFromOby($dstFileName, $srcFilePath);
       
  1298 			}
       
  1299 		}
       
  1300 	}
       
  1301 	close OBYFH;
       
  1302 }
       
  1303 
       
  1304 
       
  1305 #----------------------------------------------------------------------------------
       
  1306 # Substitution phase
       
  1307 #
       
  1308 # Handle the "define XXX YYY" lines, perform the substitutions.
       
  1309 # Print out any ECHO lines or ERROR lines. 
       
  1310 #
       
  1311 
       
  1312 # Predefined substitutions: 
       
  1313 #   TODAY means todays' date
       
  1314 #   RIGHT_NOW means the exact time
       
  1315 #   EPOCROOT taken from the environment
       
  1316 
       
  1317 sub substitution_phase
       
  1318 {
       
  1319 	{
       
  1320 		my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)=localtime(time);
       
  1321 		$substitutionData{"TODAY"} = sprintf("%02d/%02d/%04d", $mday, $mon+1, $year+1900);
       
  1322 		$substitutionData{"RIGHT_NOW"} = sprintf("%02d/%02d/%04d %02d:%02d:%02d", $mday, $mon+1, $year+1900, $hour, $min, $sec);
       
  1323 		$substitutionData{"EPOCROOT"} = $epocroot;
       
  1324 		@substitutionOrder = ("TODAY", "RIGHT_NOW", "EPOCROOT");
       
  1325 	}
       
  1326 
       
  1327 	
       
  1328 	open TMP1, "tmp1.oby" or die("* Can't open tmp1.oby\n");
       
  1329 	while ($line=<TMP1>)
       
  1330 	{
       
  1331 
       
  1332 		if(($line =~ /^\s*romsize\s*=/i) || ( $line=~ /^\s*rom_image/i) || ($line =~ /^\s*data_image/i))
       
  1333 		{
       
  1334 			$onlysmrimage = 0;
       
  1335 			last;
       
  1336 		}
       
  1337 	}
       
  1338 	close TMP1;	
       
  1339 	if ($enforceFeatureManager && (!$featuremanager) && (!$noFeatureManager) )
       
  1340 	{
       
  1341 		my $defaultFeatureDbFlag = 0;
       
  1342 		open TMP1, "tmp1.oby" or die("* Can't open tmp1.oby\n");
       
  1343 		while ($line=<TMP1>)
       
  1344 		{
       
  1345 			if ($line=~/^\s*defaultfeaturedb\s*=?\s*(\S+)/i)
       
  1346 			{	
       
  1347 				# Get the default value for featuredatabasefile
       
  1348                 
       
  1349 				$featureXml = "$epocroot$1";
       
  1350 				$featuremanager = 1;				
       
  1351 				$defaultFeatureDbFlag = 1;
       
  1352 				load_featuresutil();				
       
  1353 				last;
       
  1354 			}
       
  1355 		}
       
  1356 		close TMP1;
       
  1357 
       
  1358 		if(!$defaultFeatureDbFlag && !$onlysmrimage)
       
  1359 		{
       
  1360 			print "Error: Neither option \"-fm|-nofm\" nor default value for featuredatabase file is provided.\n";
       
  1361 			exit(1);			
       
  1362 		}
       
  1363 	}
       
  1364 
       
  1365 	open TMP1, "tmp1.oby" or die("* Can't open tmp1.oby\n");
       
  1366 	while ($line=<TMP1>)
       
  1367 	{
       
  1368 		track_source($line);
       
  1369 		#
       
  1370 		# Recognise keywords in lines that we process before substitution
       
  1371 		#
       
  1372 		# # lineno "file" flagno
       
  1373 		# DEFINE name replacement-with-0-spaces
       
  1374 		#
       
  1375 		if($line=~/^\s*$/)
       
  1376 		{
       
  1377 			next;
       
  1378 		}
       
  1379 		if ($line=~/^# (\d+) "(.*)" (\d+)/)
       
  1380 		{
       
  1381 			push @obydata, $line;
       
  1382 			next;
       
  1383 		}
       
  1384 
       
  1385 		if ($line=~/^\s*defaultfeaturedb\s*=?\s*(\S+)/i)
       
  1386 		{	
       
  1387 			push @obydata, "REM $line";
       
  1388 			next;
       
  1389 		}		
       
  1390 		#process the External tool invocation using IBY file
       
  1391 		if ($line=~/externaltool=(.*),?/i)
       
  1392 		{
       
  1393 			&externaltools::loadTools($1);
       
  1394 			next;
       
  1395 		}
       
  1396 
       
  1397 		#Process the patch statement
       
  1398 		if($line =~ /^\s*patchdata\s*(.*)/i)
       
  1399 		{
       
  1400 			$patchDataStmtFlag = 1;
       
  1401 			my $new_line = $1;
       
  1402  			# syntax "<DLLnamewithpath> addr <variableaddress> <variablesize> <newvalue>"
       
  1403  			# If the line matches with above syntax, just add the line into oby file.
       
  1404  			if($new_line !~ /^\s*(\S+)\s+addr\s+(\S+)\s+(\S+)\s+(\S+)\s*$/i)
       
  1405  			{
       
  1406  				if(AddDllDataInfo($new_line))
       
  1407  				{
       
  1408  					$line = "REM $line";
       
  1409  				}
       
  1410  			}
       
  1411 		}
       
  1412 
       
  1413 		if($line =~ /^\s*FEATURE\s*(.*)/i || $line =~ /^\s*EXCLUDE_FEATURE\s*(.*)/i)
       
  1414 		{
       
  1415 			# Process the feature keywords only when "-f|fr" or "-fm" is passed to buildrom
       
  1416 			if(defined ($featureXml))
       
  1417 			{
       
  1418 				push @obydata, "$line";
       
  1419 			}
       
  1420 			else
       
  1421 			{
       
  1422 				push @obydata, "REM handled $line";
       
  1423 			}
       
  1424 			next;
       
  1425 		}
       
  1426 
       
  1427 		if ($line=~/^\s*DEFINE\s+(\w+)\s+(\S+)/i)
       
  1428 		{
       
  1429 			my $key=$1;
       
  1430 			my $value=$2;
       
  1431 			foreach my $wordToSubstitute (@substitutionOrder)
       
  1432 			{
       
  1433 				my $whatToSubstituteItWith=$substitutionData{$wordToSubstitute};
       
  1434 				$value=~s/$wordToSubstitute/$whatToSubstituteItWith/g;
       
  1435 			}
       
  1436 			$value=~s/##//g;
       
  1437 			if (defined $substitutionData{$key})
       
  1438 			{
       
  1439 				# If the key is redefined, apply it at the new position rather
       
  1440 				# than the old one.
       
  1441 				push @obydata, "REM redefined $key as $value\n";# Leave a record of the definition
       
  1442 				@substitutionOrder = grep !/^$key$/, @substitutionOrder;
       
  1443 			}
       
  1444 			else
       
  1445 			{
       
  1446 				push @obydata, "REM defined $key as $value\n";	# Leave a record of the definition
       
  1447 			}
       
  1448 			$substitutionData{$key}=$value;
       
  1449 			
       
  1450 			foreach my $wordToSubstitute (@substitutionOrder)
       
  1451 		    {
       
  1452 	   	        if ($key =~ /$wordToSubstitute/)
       
  1453 	   	        {
       
  1454 				   print_source_error("Warning: $key is masked by earlier definition of $wordToSubstitute");
       
  1455 			 	}
       
  1456 			}
       
  1457 	
       
  1458 			push @substitutionOrder, $key;
       
  1459 			next;
       
  1460 		}
       
  1461 		#
       
  1462 		# Do the substitutions in strict order of definition, 
       
  1463 		# then eliminate any old-fashioned ## things which may be left
       
  1464 		#
       
  1465 		foreach my $wordToSubstitute (@substitutionOrder)
       
  1466 		{
       
  1467 			my $whatToSubstituteItWith=$substitutionData{$wordToSubstitute};
       
  1468 			$line=~s/$wordToSubstitute/$whatToSubstituteItWith/g;
       
  1469 		}
       
  1470 		$line=~s/##//g;
       
  1471 		#
       
  1472 		# Recognise keywords in lines that we process after substitution
       
  1473 		#
       
  1474 		# ECHO  anything at all
       
  1475 		# WARNING anything at all
       
  1476 		# ERROR anything at all
       
  1477 		# LANGUAGE_CODE nnn
       
  1478 		# DEFAULT_LANGUAGE nnn
       
  1479 		# ABI_DOWNGRADE from to
       
  1480 		# ROMBUILD_OPTION command-line-option
       
  1481 		# ROM_IMAGE
       
  1482 		# PlatSecEnforceSysBin on|off
       
  1483 		# ENABLE_SPI/DISABLE_SPI
       
  1484 		#
       
  1485 		if ($line=~/^\s*ECHO\s+(.*?)\s*$/i)
       
  1486 		{
       
  1487 			print "$1\n";
       
  1488 			push @obydata, "REM handled $line";
       
  1489 			next;
       
  1490 		}
       
  1491 		if ($line=~/^\s*(ERROR|WARNING)\s+(.*?)\s*$/i)
       
  1492 		{
       
  1493 			print_source_error("$1 $2");
       
  1494 			$errors++ if ($1 =~ /ERROR/i);
       
  1495 			push @obydata, "REM handled $line";
       
  1496 			next;
       
  1497 		}
       
  1498 		if ($line=~/^\s*(PlatSecEnforceSysBin)\s+(\S+)\s*$/i)
       
  1499 		{
       
  1500 			$enforceSysBin = ($2 =~ /ON/i);
       
  1501 			push @obydata, $line;
       
  1502 			next;
       
  1503 		}
       
  1504 		if ($line=~/^\s*LANGUAGE_CODE\s+(\S+)\s*/i)
       
  1505 		{
       
  1506 			my $code = $1;
       
  1507 			if ($code !~ /^\d\d+$/)
       
  1508 			{
       
  1509 				print_source_error("bad language code $code");
       
  1510 				$errors++;
       
  1511 			}
       
  1512 			else
       
  1513 			{
       
  1514 				$languageCodes{$code} = 1;
       
  1515 			}
       
  1516 			push @obydata, "REM handled $line";
       
  1517 			next;
       
  1518 		}
       
  1519 		if ($line=~/^\s*DEFAULT_LANGUAGE\s+(\S+)\s*/i)
       
  1520 		{
       
  1521 			my $code = $1;
       
  1522 			if ($code !~ /^\d\d+$/)
       
  1523 			{
       
  1524 				print_source_error("bad default language code $code");
       
  1525 				$errors++;
       
  1526 			}
       
  1527 			else
       
  1528 			{
       
  1529 				$defaultLanguageCode = $code;
       
  1530 			}
       
  1531 			push @obydata, "REM handled $line";
       
  1532 			next;
       
  1533 		}
       
  1534 		
       
  1535 		if ($line=~/^\s*ABI_DOWNGRADE\s*/i)
       
  1536 		{
       
  1537 			if ($line =~ /\s(.+)\s*->\s*(.+)\s*$/)
       
  1538 			{
       
  1539 				$abiDowngrade = "$1 $2";
       
  1540 			}
       
  1541 			else
       
  1542 			{
       
  1543 				print_source_error("bad ABI downgrade : $line");
       
  1544 				$errors++;
       
  1545 			}
       
  1546 			push @obydata, "REM handled $line";
       
  1547 			next;
       
  1548 		}
       
  1549 		if ($line=~/^\s*BINARY_SELECTION_ORDER\s*/i)
       
  1550 		{
       
  1551 	 		if ($line =~ /\s([^,]+)\s*,\s*(.+)\s*$/)
       
  1552    			{
       
  1553   				$binarySelectionOrderFlag = 1;
       
  1554  				$firstDIR = $1;
       
  1555    				# remove whitespaces
       
  1556  				$firstDIR = trim($firstDIR); 
       
  1557    				@binarySelectionOrder = split(',', $2);
       
  1558    				@binarySelectionOrder = trim(@binarySelectionOrder);
       
  1559 
       
  1560 			}
       
  1561 			else
       
  1562 			{
       
  1563 				print_source_error("bad order specified: $line");
       
  1564 				$errors++;
       
  1565 			}
       
  1566 			push @obydata, "REM handled $line";
       
  1567 			next;
       
  1568 		}
       
  1569 		
       
  1570 		if ($line=~/^\s*ROMBUILD_OPTION\s+(\S+)\s*/i)
       
  1571 		{
       
  1572 			$rombuildOptions{$1} = 1;
       
  1573 			push @obydata, "REM handled $line";
       
  1574 			next;
       
  1575 		}
       
  1576 		
       
  1577 		if ($line=~/^\s*enable_spi\s*$/i)
       
  1578 		{
       
  1579 			if(!($spiset)) {
       
  1580 				$createspi=1;
       
  1581 			}
       
  1582 			push @obydata, "REM handled $line";
       
  1583 			next;
       
  1584 		}
       
  1585 		
       
  1586 		if ($line=~/^\s*disable_spi\s*/i)
       
  1587 		{
       
  1588 			if(!($spiset)) {
       
  1589 				$createspi=0;
       
  1590 			}
       
  1591 			push @obydata, "REM handled $line";
       
  1592 			next;
       
  1593 		}
       
  1594 
       
  1595 		if ($line=~/^\s*DATA_IMAGE\s+/i)
       
  1596 		{
       
  1597 			if ($line =~ /\s+(\d+)\s+(\S+)\s+/i)
       
  1598 			{
       
  1599 				my $datadriveidx = $1;
       
  1600 				my $datadriveimagename = $2;
       
  1601 				# have a count on number of data drive images that needs to be created
       
  1602 				print "data drive partion name = $datadriveimagename\n " if($opt_v);
       
  1603 				my $dataimagesize = 0;
       
  1604 				if ($line =~ /\s+size=(\S+)\s*/i)
       
  1605 				{ 
       
  1606 					$dataimagesize=$1; 
       
  1607 				}
       
  1608 				my $fstype = "";
       
  1609 				my $compress=0;
       
  1610 				my $uncompress=0;
       
  1611 				if ($line =~ /\s+compress\s*/i)
       
  1612 				{ 
       
  1613 					$compress=1;
       
  1614 				}
       
  1615 				elsif($line =~ /\s+uncompress\s*/i)
       
  1616 				{ 
       
  1617 					$uncompress=1;
       
  1618 				}
       
  1619 				if ($line =~ /\s+fat16\s*/i)
       
  1620 				{ 
       
  1621 					$fstype = "fat16"; 
       
  1622 				}
       
  1623 				if ($line =~ /\s+fat32\s*/i)
       
  1624 				{ 
       
  1625 					$fstype = "fat32"; 
       
  1626 				}
       
  1627 				
       
  1628 				$datadriveimage[$datadriveidx] = {name=>$datadriveimagename, size=>$dataimagesize, compress=>$compress, uncompress=>$uncompress, fstype=>$fstype};
       
  1629 				print "DATA_IMAGE[$datadriveidx] $datadriveimage[$datadriveidx]{name} size=$datadriveimage[$datadriveidx]{size} compress=$compress uncompress=$uncompress fstype=$fstype\n" if ($opt_v);
       
  1630 			}
       
  1631 			else
       
  1632 			{
       
  1633 				print_source_error("bad DATA_IMAGE specification : $line");
       
  1634 				$errors++;
       
  1635 			}
       
  1636 			push @obydata, "REM handled $line";
       
  1637 			next;
       
  1638 		}
       
  1639 		if ($line=~/^\s*ROM_IMAGE\s+/i)
       
  1640 		{
       
  1641 			if ($line =~ /\s+(\d+)\s+(\S+)\s+/i)
       
  1642 			{
       
  1643 				my $romidx=$1;
       
  1644 				my $rompartitionname=$2;
       
  1645 				my $rompartitionsize=0;
       
  1646 				if ($line =~ /\s+size=(\S+)\s*/i)
       
  1647 					{ $rompartitionsize=$1; }
       
  1648 				my $xip=1;
       
  1649 				my $compress=0;
       
  1650 				my $uncompress=0;
       
  1651 				my $extend=0;
       
  1652 				my $composite="none";
       
  1653 				if ($line =~ /\s+non-xip\s*/i)
       
  1654 					{ $xip=0; }
       
  1655 				if ($line =~ /\s+compress\s*/i)
       
  1656 					{ $compress=1; }
       
  1657 				elsif($line =~ /\s+uncompress\s*/i)
       
  1658 					{ $uncompress=1;} # This option is passed to rofsbuild. For rombuild, not saying --compress means to uncompress
       
  1659 				if ($line =~ /\s+extension\s*/i)
       
  1660 					{ $extend=1; }
       
  1661 				if ($line =~ /\s+composite_primary\s*/i) # added to support new composite_primary keyword in obey files
       
  1662 				{	if (!($extend))
       
  1663 						{ $composite="composite_primary"; }
       
  1664 					else
       
  1665 						{ print "Error: composite_primary keyword must be used with a core image\n"; }
       
  1666 				}
       
  1667 				if ($line =~ /\s+composite_secondary\s*/i) # added to support new composite_secondary keyword in obey files
       
  1668 				{ if (!($extend))
       
  1669 						{ $composite="composite_secondary"; }
       
  1670 					else
       
  1671 						{ print "Error: composite_secondary keyword must be used with core image\n"; }
       
  1672 				}
       
  1673 	
       
  1674 				#	Compress and Uncompress are 2 different options and
       
  1675 				#	not mentioning one of them doesn't necessarily mean the other.
       
  1676 	
       
  1677 				$romimage[$romidx] = {name=>$rompartitionname, size=>$rompartitionsize, xip=>$xip, compress=>$compress, extension=>$extend, composite=>$composite, uncompress=>$uncompress};
       
  1678 				print "ROM_IMAGE[$romidx] $romimage[$romidx]{name} size=$romimage[$romidx]{size} xip=$xip compress=$compress extension=$extend composite=$composite uncompress=$uncompress \n" if ($opt_v);
       
  1679 				check_romimage($romidx, $line);
       
  1680 			}
       
  1681 			else
       
  1682 			{
       
  1683 				print_source_error("bad ROM_IMAGE specification : $line");
       
  1684 				$errors++;
       
  1685 			}
       
  1686 			push @obydata, "REM handled $line";
       
  1687 			next;
       
  1688 		}
       
  1689 	
       
  1690 		push @obydata, $line;
       
  1691 	}
       
  1692 
       
  1693 	close TMP1;
       
  1694 	exit(1) if ($errors);
       
  1695 	
       
  1696 	dump_obydata("tmp2.oby", "result of substitution phase") if ($opt_v);
       
  1697 }
       
  1698 
       
  1699 sub check_romimage
       
  1700 {
       
  1701 	my ($idx, $line) = @_;
       
  1702 	if ($idx gt 7)
       
  1703 	{
       
  1704 		print_source_error("too many roms : $line");
       
  1705 		$errors++;
       
  1706 	}
       
  1707 	if ($romimage[$idx]{xip} eq 0)
       
  1708 	{
       
  1709 		if ($romimage[$idx]{size} eq 0)
       
  1710 		{
       
  1711 			print_source_error("must specify a size for non-xip ROM : $line");
       
  1712 			$errors++;
       
  1713 		}
       
  1714 	}
       
  1715 	if ($romimage[$idx]{extension} ne 0)
       
  1716 	{
       
  1717 		if ($romimage[$idx-1]{extension} ne 0)
       
  1718 		{
       
  1719 			print_source_error("cannot extend ROM image multiple times : $line");
       
  1720 			$errors++;
       
  1721 		}
       
  1722 	}
       
  1723 }
       
  1724 
       
  1725 sub dump_obydata
       
  1726 {
       
  1727 	my ($dumpfile, $comment) = @_;
       
  1728 	unlink($dumpfile);
       
  1729 	open DUMPFILE, ">$dumpfile" or die("* Can't create $dumpfile\n");
       
  1730 	print "* Writing $dumpfile - $comment\n";
       
  1731 	my $line;
       
  1732 	foreach $line (@obydata)
       
  1733 	{
       
  1734 		print DUMPFILE $line;
       
  1735 	}
       
  1736 	close DUMPFILE;
       
  1737 }
       
  1738 
       
  1739 sub track_source
       
  1740 {
       
  1741 	my ($line) = @_;
       
  1742 	if ($line=~/^# (\d+) "(.*)"/)
       
  1743 	{
       
  1744 		$sourceline=$1-1;
       
  1745 		$sourcefile=$2;
       
  1746 		$sourcefile=~ s/\//\\/g;
       
  1747 		$sourcefile=~ s/\\\\/\\/g;
       
  1748 		return;
       
  1749 	}
       
  1750 	$sourceline++;
       
  1751 }
       
  1752 
       
  1753 sub print_source_error
       
  1754 {
       
  1755 	my ($message) = @_;
       
  1756 	print "$sourcefile($sourceline): $message\n";
       
  1757 }
       
  1758 
       
  1759 sub reassert_sourceline
       
  1760 {
       
  1761 	my ($offset) = @_;
       
  1762 	return sprintf "# %d \"$sourcefile\" \n", $sourceline+1+$offset;
       
  1763 }
       
  1764 
       
  1765 
       
  1766 #----------------------------------------------------------------------------------
       
  1767 # Reorganisation phase
       
  1768 #
       
  1769 # Group lines beginning with "rom_image[<id>]" and deposit them in the appropriate
       
  1770 # order.  Truncate the description at the "stop" line, if there is one.
       
  1771 
       
  1772 sub reorganize_phase
       
  1773 {
       
  1774 	
       
  1775 	undef @newobydata;
       
  1776 	my @section2;
       
  1777 	my @part3;
       
  1778 	my @part4;
       
  1779 	my @part5;
       
  1780 	my @part6;
       
  1781 	my @part7;
       
  1782 	my @part8;
       
  1783 	my @partitions = ( \@newobydata, \@section2, \@part3, \@part4, \@part5, \@part6, \@part7, \@part8 );
       
  1784 	my @currentpartition;	# partition stack
       
  1785 
       
  1786 	my @processedImageIdx;		# list of proccesed data drive image index. 
       
  1787 	my $dataDriveStartRegion = 0;
       
  1788 	my $dataDriveEndRegion = 0;
       
  1789 	my $dataDriveIdx;
       
  1790 	my @datapartition;
       
  1791 	my @linesArray;
       
  1792 	my $curlyBraceShouldFollow;
       
  1793 
       
  1794 	my $collect_section2=1;
       
  1795 	my $smrImageStartRegion = 0;
       
  1796 	my $smrImageEndRegion = 0;
       
  1797 	my $smrImageIndex = 0;
       
  1798 	
       
  1799 	foreach $line (@obydata)
       
  1800 	{
       
  1801 		track_source($line);
       
  1802 		if ($line=~/^\s*stop/i)
       
  1803 		{
       
  1804 			last;
       
  1805 		}
       
  1806 		if ($line =~ /^\s*ROM_IMAGE\[(\S+)\]\s+\{(.*)$/i)
       
  1807 		{
       
  1808 			# ROM_IMAGE[n] {
       
  1809 			my $idx=$1;
       
  1810 			my $partition=$partitions[$idx];
       
  1811 			push @currentpartition, $partition;
       
  1812 			$line="REM handled $line";
       
  1813 		}
       
  1814 		elsif( ($line =~ /^\s*DATA_IMAGE\[(\S+)\]\s*$/i) || ($line =~ /^\s*DATA_IMAGE\[(\S+)\]\s*\{\s*$/i))
       
  1815 		{
       
  1816 			# DATA_IMAGE[n] or DATA_IMAGE[n] {  is specified.
       
  1817 			# get the index.
       
  1818 			$dataDriveIdx=$1;
       
  1819  			if($line !~ /\s*\{\s*/i)
       
  1820  			{
       
  1821  				$curlyBraceShouldFollow = 1;
       
  1822  			}
       
  1823 			# make a check if dataDriveIdx exists in the processedImageIdx array.
       
  1824 			# if no, then push the dataDriveIdx on the processedImageIdx array.
       
  1825 			# if yes,then dont execute the loop.
       
  1826 			if(&datadriveimage::checkInArray(\@processedImageIdx,$dataDriveIdx))
       
  1827 			{
       
  1828 				# push the index on to the array.
       
  1829 				push(@processedImageIdx,$dataDriveIdx);
       
  1830 				# increment the image count. 
       
  1831 				++$dataImageCount;
       
  1832 			}
       
  1833 
       
  1834 			$dataIndexHash{($dataImageCount-1)} = $dataDriveIdx;
       
  1835 			# set start of the image section.
       
  1836 			$dataDriveStartRegion = 1;
       
  1837 			# set end of image section to zero.
       
  1838 			$dataDriveEndRegion = 0;
       
  1839 			push (@linesArray,"\n");
       
  1840 			$line="REM handled $line";
       
  1841 		}
       
  1842 		elsif( $line =~ /^\s*SMR_IMAGE\s*\{\s*$/i)
       
  1843 		{
       
  1844 			$smrImageStartRegion = 1;
       
  1845 			$smrImageEndRegion = 0;
       
  1846 			$needSmrImage = 1;
       
  1847 			push (@linesArray, "\n");
       
  1848 			$line="REM handled $line";
       
  1849 		}
       
  1850  		elsif((defined $curlyBraceShouldFollow) && ($line !~ /^\s*$/i))
       
  1851  		{
       
  1852 			undef $curlyBraceShouldFollow;
       
  1853  			if($line !~ /^\s*\{\s*/i)
       
  1854  			{
       
  1855  				print "Error: Symbol '{' not followed after the keyword DATA_IMAGE\[".$dataDriveIdx."\]\n";
       
  1856  				$errors++;
       
  1857  			}
       
  1858  			next;
       
  1859  		}
       
  1860 		# data drive specific keywords.
       
  1861 		elsif( $line =~/^\s*dataimagename\s*\=\s*(\S+)/i )
       
  1862 		{
       
  1863 			# set the name for the image, if image name is specified using driveimagename keyword.
       
  1864 			$datadriveimage[$dataDriveIdx]{name} = $1 if($dataDriveStartRegion && !$dataDriveEndRegion);
       
  1865 			print"datadriveimagename = $datadriveimage[$dataDriveIdx]{name}\n" if($dataDriveStartRegion && !$dataDriveEndRegion && $opt_v);
       
  1866 			# skip the line.
       
  1867 			next;
       
  1868 		}
       
  1869 		elsif( $line =~/^\s*dataimagesize\s*\=\s*(\S+)/i )
       
  1870 		{
       
  1871 			# set the size for the image, if image size is specified using driveimagesize keyword.
       
  1872 			$datadriveimage[$dataDriveIdx]{size} = $1 if($dataDriveStartRegion && !$dataDriveEndRegion);
       
  1873 			print"datadriveimagesize = $datadriveimage[$dataDriveIdx]{size}\n" if($dataDriveStartRegion && !$dataDriveEndRegion && $opt_v);
       
  1874 			# skip the line.
       
  1875 			next;
       
  1876 		}
       
  1877 		elsif( $line =~/^\s*dataimagefilesystem\s*\=\s*(\S+)/i )
       
  1878 		{
       
  1879 			# set the file system type for the image, if image file system is specified using dataimagefilesystem keyword.
       
  1880 			$datadriveimage[$dataDriveIdx]{fstype} = $1 if($dataDriveStartRegion && !$dataDriveEndRegion);
       
  1881 			print"datadriveimagefstype = $datadriveimage[$dataDriveIdx]{fstype}\n" if($dataDriveStartRegion && !$dataDriveEndRegion && $opt_v);
       
  1882 			# skip the line.
       
  1883 			next;
       
  1884 		}
       
  1885 		elsif( $line =~/^\s*compress/i )
       
  1886 		{
       
  1887 			# Compresses the resulting data drive image using the Deflate, Huffman+LZ77 algorithm.
       
  1888 			if($dataDriveStartRegion && !$dataDriveEndRegion)
       
  1889 			{
       
  1890 				$datadriveimage[$dataDriveIdx]{compress} = 1;
       
  1891 				$datadriveimage[$dataDriveIdx]{uncompress} = 0;
       
  1892 				print"datadriveimage[$dataDriveIdx] compress = $datadriveimage[$dataDriveIdx]{compress}\n" if($opt_v);
       
  1893 			}
       
  1894 		}
       
  1895 		elsif( $line =~/^\s*uncompress/i )
       
  1896 		{
       
  1897 			# Uncompresses the resulting data drive image.
       
  1898 			if($dataDriveStartRegion && !$dataDriveEndRegion)
       
  1899 			{
       
  1900 				$datadriveimage[$dataDriveIdx]{uncompress} = 1;
       
  1901 				$datadriveimage[$dataDriveIdx]{compress} = 0;
       
  1902 				print"datadriveimage[$dataDriveIdx] uncompress = $datadriveimage[$dataDriveIdx]{uncompress}\n" if($opt_v);
       
  1903 			}
       
  1904 		}
       
  1905 		elsif ($line =~ /^\s*ROM_IMAGE\[(\S+)\](.*)$/i)
       
  1906 		{
       
  1907 			# ROM_IMAGE[n] file=...
       
  1908 			my $origline=$line;
       
  1909 			$line="$2\n";	# remove the ROM_IMAGE[.] keyword
       
  1910 			my $idx=$1;
       
  1911 			my $partition=$partitions[$idx];
       
  1912 			push @$partition, reassert_sourceline(-1);
       
  1913 			push @$partition, $line;
       
  1914 			$line="REM handled $origline";
       
  1915 		}
       
  1916 		elsif ($line =~ /^\s*DATA_IMAGE\[(\S+)\](.*)$/i)
       
  1917 		{
       
  1918 			# DATA_IMAGE[n] file=...
       
  1919 			my $origline=$line;
       
  1920 			# remove the DATA_IMAGE[.] keyword
       
  1921 			$line="$2\n";
       
  1922 			# get the index value
       
  1923 			my $idx=$1;
       
  1924 			# iterate through the hash to get corresponding 
       
  1925 			# key from the value(i.e idx) 
       
  1926 			while (my($key, $value) = each(%dataIndexHash))
       
  1927 			{
       
  1928 				if ($value eq $idx ) 
       
  1929 				{
       
  1930 					$idx = $key;
       
  1931 				}
       
  1932 			}
       
  1933 			push @{$datapartition[$idx]}, reassert_sourceline(-1);
       
  1934 			push @{$datapartition[$idx]}, $line;
       
  1935 			$line="REM handled $origline";
       
  1936 		}
       
  1937 		elsif ($line =~ /^\s*\}.*$/i)
       
  1938 		{
       
  1939 			if($dataDriveStartRegion)
       
  1940 			{
       
  1941 				# since "}" brace is encountered
       
  1942 				# reset the start of DATA_IMAGE to zero.
       
  1943 				$dataDriveStartRegion = 0;
       
  1944 				# mark the the end of the DATA_IMAGE.
       
  1945 				$dataDriveEndRegion = 1;
       
  1946 				if(!$datadriveimage[$dataDriveIdx]{name})
       
  1947 				{
       
  1948 					# image name is not defined, define a default name.
       
  1949 					$datadriveimage[$dataDriveIdx]{name} = "dataImage".$dataDriveIdx;
       
  1950 				}
       
  1951 				if(!$datadriveimage[$dataDriveIdx]{fstype})
       
  1952 				{
       
  1953 					# image name is not defined, define a default name.
       
  1954 					$datadriveimage[$dataDriveIdx]{fstype} = "fat16";
       
  1955 				}
       
  1956 				foreach my $file (@linesArray)
       
  1957 				{
       
  1958 					push @{$datapartition[($dataImageCount-1)]},$file;
       
  1959 				}
       
  1960 				## if end of the DATA_IMAGE is true,
       
  1961 				## make room for next DATA_IMAGE if any.
       
  1962 				undef(@linesArray); 
       
  1963 				#un define $dataDriveIdx;
       
  1964 				undef($dataDriveIdx);
       
  1965 			}
       
  1966 			elsif($smrImageStartRegion)
       
  1967 			{
       
  1968 				$smrImageStartRegion = 0;
       
  1969 				$smrImageEndRegion = 1;
       
  1970 				foreach my $file (@linesArray)
       
  1971 				{
       
  1972 					push @{$smrPartitions{$smrImageIndex}}, $file;
       
  1973 				}
       
  1974 				undef(@linesArray);
       
  1975 				$smrImageIndex++;
       
  1976 			}
       
  1977 			elsif (scalar @currentpartition > 0)
       
  1978 			{ 
       
  1979 				pop @currentpartition; 
       
  1980 			}
       
  1981 			else
       
  1982 			{ 
       
  1983 				print "WARNING: closing '}' found with no matching 'ROM_IMAGE[<n>]/DATA_IMAGE[<n>] {'\n";
       
  1984 			}
       
  1985 			$line="REM handled $line";
       
  1986 		}
       
  1987 		elsif ($line=~/^\s*section2(.*)$/i)
       
  1988 		{
       
  1989 			my $origline=$line;
       
  1990 			$line="$1\n";	# remove the section2 keyword
       
  1991 			if ($collect_section2)
       
  1992 			{
       
  1993 				push @section2, reassert_sourceline(-1);
       
  1994 				push @section2, $line;
       
  1995 				$line="REM handled $origline";
       
  1996 			}
       
  1997 		}
       
  1998 		elsif ($line=~/^\s*section/i)
       
  1999 		{
       
  2000 			push @newobydata, $line;		# insert the section statement
       
  2001 			if (@section2 != 0)
       
  2002 			{
       
  2003 				push @newobydata, "REM accumulated section2 lines\n";
       
  2004 			}
       
  2005 			foreach $line (@section2)
       
  2006 			{
       
  2007 				push @newobydata, $line;	# insert accumulated section2 lines
       
  2008 			}
       
  2009 			$collect_section2=0;
       
  2010 			$line = reassert_sourceline();
       
  2011 		}
       
  2012 		
       
  2013 		elsif ($line=~/^\s*extensionrom/i)
       
  2014 		{
       
  2015 			# end of ROM description, so deposit accumulated lines
       
  2016 			if (@section2 != 0)
       
  2017 			{
       
  2018 				push @newobydata, "REM accumulated section2 lines\n";
       
  2019 			}
       
  2020 			foreach $line (@section2)
       
  2021 			{
       
  2022 				push @newobydata, $line;	# insert accumulated section2 lines
       
  2023 			}
       
  2024 			$collect_section2=0;
       
  2025 			push @newobydata, reassert_sourceline();
       
  2026 		}
       
  2027 		
       
  2028 		elsif ( scalar(@linesArray) )
       
  2029 		{
       
  2030 			if($dataDriveStartRegion && !$dataDriveEndRegion)
       
  2031 			{
       
  2032 				my $modifiedLine = $line;
       
  2033 				push @linesArray, $modifiedLine;
       
  2034 				$line = "REM handled $line";
       
  2035 			}
       
  2036 			elsif($smrImageStartRegion && !$smrImageEndRegion)
       
  2037 			{
       
  2038 				if($line =~ /^\s*IMAGENAME\s*=\s*(\S+)/i)
       
  2039 				{
       
  2040 					my $smrimagename = $1;
       
  2041 					$smrimagename =~s/(\.img)//i;
       
  2042 					if(exists($smrNameInfo{$smrimagename}))
       
  2043 					{
       
  2044 						$smrNameInfo{$smrimagename}++;
       
  2045 					}
       
  2046 					else
       
  2047 					{
       
  2048 						$smrNameInfo{$smrimagename} = 1;
       
  2049 					}
       
  2050 					$line =~s/(\.img)//i;
       
  2051 				}
       
  2052 				push @linesArray, $line;
       
  2053 				$line = "REM handled $line";
       
  2054 			}
       
  2055 		}
       
  2056 		elsif (scalar @currentpartition)
       
  2057 		{
       
  2058 			my $modifiedLine = $line;
       
  2059 			if ($line =~ /^\s*SPI_POSITION/i)
       
  2060 			{
       
  2061 				if(!($createspi && $spiplacement))
       
  2062 				{
       
  2063 					# comment the line if the spi placement flag is not enabled or if the spi creation is not enabled.
       
  2064 					$modifiedLine = "REM SPI creation/placement flag not enabled. Ignoring SPI_POSITION\n";
       
  2065 					print ("Warning: SPI creation/placement flag not enabled. Ignoring SPI_POSITION\n" ) if ($opt_v);
       
  2066 				}
       
  2067 			}
       
  2068 			# a partition is specified
       
  2069 			# push this line into the currently selected partition
       
  2070 			my $partition=@currentpartition[-1];
       
  2071 			push @$partition, $modifiedLine;
       
  2072 			$line="REM handled $line";
       
  2073 		}
       
  2074 		elsif ($line =~ /^\s*SPI_POSITION/i)
       
  2075 		{
       
  2076 			if(!($createspi && $spiplacement))
       
  2077 			{
       
  2078                 # comment the line if the spi placement flag is not enabled or if the spi creation is not enabled.
       
  2079                 $line = "REM SPI creation/placement flag not enabled. Ignoring SPI_POSITION\n";
       
  2080                 print ("Warning: SPI creation/placement flag not enabled. Ignoring SPI_POSITION\n" ) if ($opt_v);
       
  2081 			}
       
  2082 		}
       
  2083 		push @newobydata, $line;
       
  2084 	}
       
  2085 
       
  2086 	# output the grouped data
       
  2087 	my $partitionidx=2;
       
  2088 	if ($collect_section2)
       
  2089 		{ $partitionidx=1; } # output old "section2" if not done already
       
  2090 	for (; $partitionidx<8; $partitionidx++)
       
  2091 	{
       
  2092 		my $partition=$partitions[$partitionidx];
       
  2093 		if (@$partition != 0)
       
  2094 		{
       
  2095 			push @newobydata, "REM ROM_IMAGE[$partitionidx]\n";
       
  2096 			foreach $line (@$partition)
       
  2097 			{
       
  2098 				push @newobydata, $line;	# insert accumulated section2 lines
       
  2099 			}
       
  2100 		}
       
  2101 	}
       
  2102 	
       
  2103 	for ( my $datapartitionidx=0; $datapartitionidx < $dataImageCount; $datapartitionidx++ )
       
  2104 	{
       
  2105 		if( defined( @{ $datapartition[$datapartitionidx] } ) )
       
  2106 		{
       
  2107 			push @newobydata, "REM DATA_IMAGE[$dataIndexHash{$datapartitionidx}]\n" ;
       
  2108 			foreach my $file (@{$datapartition[$datapartitionidx]})
       
  2109 			{
       
  2110 				push @newobydata, $file;
       
  2111 			}
       
  2112 		}
       
  2113 	}
       
  2114 
       
  2115 	
       
  2116 	foreach my $imageIndex (keys(%smrPartitions))
       
  2117 	{
       
  2118 		my $imagename;
       
  2119 		my @obeyfile;
       
  2120 
       
  2121 		foreach (@{$smrPartitions{$imageIndex}})
       
  2122 		{
       
  2123 			if(/^\s*imagename\s*=\s*(\S+)/i)
       
  2124 			{
       
  2125 				$imagename = $1;
       
  2126 			}
       
  2127 			push @obeyfile, $_;
       
  2128 		}
       
  2129 		if($smrNameInfo{$imagename} == 1)
       
  2130 		{
       
  2131 			push @obeyFileList, $imagename;
       
  2132 			push @newobydata, "REM SMR_IMAGE \n";
       
  2133 			push @newobydata, @obeyfile;
       
  2134 		}
       
  2135 		if(! defined($imagename))
       
  2136 		{
       
  2137 			$smrNoImageName = 1;
       
  2138 		}
       
  2139 		undef $imagename;
       
  2140 		undef @obeyfile;
       
  2141 	}
       
  2142 
       
  2143 	@obydata = @newobydata;
       
  2144 	exit(1) if ($errors);
       
  2145 	dump_obydata("tmp3.oby", "result of reorganisation phase") if ($opt_v);
       
  2146 }
       
  2147 
       
  2148 
       
  2149 #----------------------------------------------------------------------------------
       
  2150 # Plugin phase
       
  2151 #
       
  2152 # Process any plugin annotation lines
       
  2153 # Note: This expands resource lines to include MULTI_LINGUIFY so must be done before
       
  2154 # the Multilinguify phase
       
  2155 
       
  2156 # hash of SPI file target directories is located near the start of this file, before sub match_obyfile
       
  2157 
       
  2158 sub plugin_phase
       
  2159 {
       
  2160 	undef @newobydata;
       
  2161 	foreach $line (@obydata)
       
  2162 	{
       
  2163 		track_source($line);
       
  2164 	 	if ($line =~ /^\s*REM/i)
       
  2165 		{
       
  2166 		# ignore REM statements, to avoid processing "REM ECOM_PLUGIN(xxx,yyy)"
       
  2167 		}
       
  2168 		elsif(plugin_match($line)) {
       
  2169 			$line = reassert_sourceline();		
       
  2170 		}
       
  2171 		push @newobydata, $line;
       
  2172 	}
       
  2173 		
       
  2174 	@obydata = @newobydata;
       
  2175 	dump_obydata("tmp4.oby", "result of Plugin stage") if ($opt_v);
       
  2176 }
       
  2177 
       
  2178 sub plugin_match ()
       
  2179 {
       
  2180 	my ($line) = @_;
       
  2181 	foreach my $plugintype (keys(%plugintypes)) {
       
  2182 	  if ($line =~ m/^.*__$plugintype\_PLUGIN\(\s*(\S+)\s*,\s*(\S+)\s*,\s*(\S+)\s*,\s*(\S+)\s*,\s*(\S+)\s*,\s*(\S+)\s*\)/i)
       
  2183 	  	# __<plugin-type>_PLUGIN(emulator directory, file rom dir, dataz_, resource rom dir, filename, resource filename)
       
  2184 	  {
       
  2185 		    my $emulatorDir=$1;
       
  2186 		    my $fileRomDir=$2;
       
  2187 		    my $dataz_= $3;
       
  2188 		    my $resourceDir=$4;
       
  2189 		    my $pluginFileName=$5;
       
  2190 		    my $pluginResourceName=$6;
       
  2191 		    my $spidatahide = 0;
       
  2192 			my $paged_data = "";
       
  2193   
       
  2194 			if ($line =~ m/paged\s*$/i)
       
  2195 			{
       
  2196 				$line =~ m/\s+(\S+)\s*$/;
       
  2197 				$paged_data = $1;
       
  2198 			}
       
  2199 
       
  2200 		    if ($line =~ m/^\s*(_hide)/i )
       
  2201 		    {
       
  2202 		    	$spidatahide = 1;
       
  2203 		    }
       
  2204 
       
  2205 		    # for resource files strip the .rsc or .dll from the end   (will be .dll where we use
       
  2206 		    # SYMBIAN_SECURE_ECOM and are building resources to  the same name as ecom plugin dlls)
       
  2207 		    
       
  2208 		    if ($pluginResourceName =~ m/^(.+)\./)
       
  2209 		    {
       
  2210 		      $pluginResourceName = $1;
       
  2211 		    }
       
  2212 		    else
       
  2213 		    {
       
  2214 		      print_source_error("Invalid Resource name: $pluginResourceName in " . $plugintype . "_PLUGIN :$line");
       
  2215 		      #treat as error if strict option selected;
       
  2216 		      $errors++ if ($strict);
       
  2217 		    }
       
  2218 
       
  2219 		    if ($spidatahide)
       
  2220 		    {
       
  2221 			push @newobydata, "hide=$fileRomDir\\$pluginFileName\n";
       
  2222 		    }
       
  2223 		    else
       
  2224 		    {
       
  2225 		    	push @newobydata, "file=$emulatorDir\\$pluginFileName $fileRomDir\\$pluginFileName $paged_data\n";
       
  2226 		    }
       
  2227 
       
  2228 		    if($createspi) {
       
  2229 		    	    if ($spidatahide)
       
  2230 			    {
       
  2231 			    	push @newobydata, "spidatahide=MULTI_LINGUIFY(RSC $dataz_\\$resourceDir\\$pluginResourceName $resourceDir\\$pluginResourceName) " . lc($plugintype) . "\.spi " . $plugintypes{$plugintype} . "\n";      
       
  2232 			    }
       
  2233 			    else
       
  2234 			    {
       
  2235 			    	push @newobydata, "spidata=MULTI_LINGUIFY(RSC $dataz_\\$resourceDir\\$pluginResourceName $resourceDir\\$pluginResourceName) " . lc($plugintype) . "\.spi " . $plugintypes{$plugintype} . "\n";      
       
  2236 			    }
       
  2237 		  	} else {
       
  2238 		    	    if ($spidatahide)
       
  2239 			    {
       
  2240 			    	push @newobydata, "hide=MULTI_LINGUIFY(RSC $dataz_\\$resourceDir\\$pluginResourceName $resourceDir\\$pluginResourceName)\n";
       
  2241 			    }
       
  2242 			    else
       
  2243 			    {
       
  2244 			    	push @newobydata, "data=MULTI_LINGUIFY(RSC $dataz_\\$resourceDir\\$pluginResourceName $resourceDir\\$pluginResourceName)\n";
       
  2245 			    }
       
  2246 			}
       
  2247 				return 1; #successful match
       
  2248 	   }
       
  2249      }
       
  2250 }
       
  2251 
       
  2252 
       
  2253 #----------------------------------------------------------------------------------
       
  2254 # Multilinguify phase
       
  2255 #
       
  2256 # Process the MULTILINGUIFY() lines
       
  2257 
       
  2258 sub multlinguify_phase
       
  2259 {
       
  2260 	if ((scalar keys %languageCodes) == 0)
       
  2261 	{
       
  2262 		print "* No language codes specified, defaulting to 01\n";
       
  2263 		$defaultLanguageCode = "01";
       
  2264 	}
       
  2265 	$languageCodes{$defaultLanguageCode} = 1;
       
  2266 	
       
  2267 	undef @newobydata;
       
  2268 	foreach $line (@obydata)
       
  2269 	{
       
  2270 		track_source($line);
       
  2271 		if ($line =~ /^\s*REM/i)
       
  2272 		{
       
  2273 			# ignore REM statements, to avoid processing "REM data=xxx yyy"
       
  2274 		}
       
  2275 		elsif ($line=~/^(.*?)\bMULTI_LINGUIFY\s*\(\s*(\S+)\s+(\S+)\s+(\S+)\s*\)(.*)$/i)
       
  2276 		{
       
  2277 			my $initialStuff=$1;
       
  2278 			my $defaultFileNameExtension=$2;
       
  2279 			my $sourceFileNameWithoutExtension=$3;
       
  2280 			my $targetFileNameWithoutExtension=$4;
       
  2281 			my $finalStuff=$5;
       
  2282 			my $spidataflag = 0;
       
  2283 			my $spidatahide = 0;
       
  2284 			my $datahide = 0;
       
  2285 
       
  2286 			if ($initialStuff=~/\w$/)
       
  2287 			{
       
  2288 				$initialStuff.=" ";
       
  2289 			}
       
  2290 			if ($finalStuff=~/^\w/)
       
  2291 			{
       
  2292 				$finalStuff=" ".$finalStuff;
       
  2293 			}
       
  2294 			if ($initialStuff =~ /^\s*spidata/i)
       
  2295 			{
       
  2296 				$spidataflag = 1;
       
  2297 			}
       
  2298 			if ($initialStuff =~ /^\s*spidatahide/i)
       
  2299 			{
       
  2300 				$spidataflag = 1;
       
  2301 				$spidatahide = 1;
       
  2302 			}
       
  2303 			if ($initialStuff =~ /^\s*hide/i)
       
  2304 			{
       
  2305 				$datahide = 1;
       
  2306 			}
       
  2307 
       
  2308 
       
  2309 # ecom.spi should contain the .RSC files
       
  2310 			if ($spidataflag)
       
  2311 			{
       
  2312 				my $sourceFileNameExtension = $defaultFileNameExtension;
       
  2313 				my $targetFileNameExtension = $defaultFileNameExtension;
       
  2314 				if (-e "$sourceFileNameWithoutExtension.$sourceFileNameExtension")
       
  2315 				{
       
  2316 					if ($spidatahide)
       
  2317 					{
       
  2318 						push @newobydata, "$initialStuff$sourceFileNameWithoutExtension.$sourceFileNameExtension$finalStuff\n";
       
  2319 					}
       
  2320 					else
       
  2321 					{
       
  2322 						push @newobydata, "$initialStuff$sourceFileNameWithoutExtension.$sourceFileNameExtension $targetFileNameWithoutExtension.$targetFileNameExtension$finalStuff\n";
       
  2323 					}
       
  2324 				}
       
  2325 			}
       
  2326 			my $useDefaultFileNameExtension=1;
       
  2327 			foreach my $languageCode (keys %languageCodes) {
       
  2328 				my $sourceFileNameExtension=$defaultFileNameExtension;
       
  2329 				$sourceFileNameExtension=~s/^(.*).{2}$/$1$languageCode/;
       
  2330 				if (! -e "$sourceFileNameWithoutExtension.$sourceFileNameExtension")
       
  2331 				{
       
  2332 					if (!$spidataflag)
       
  2333 					{
       
  2334 						next if (!$useDefaultFileNameExtension);
       
  2335 						next if (defined $defaultLanguageCode and !($languageCode eq $defaultLanguageCode));
       
  2336 						$useDefaultFileNameExtension=0;
       
  2337 						if (!$datahide)
       
  2338 						{
       
  2339 							print "Converting >$sourceFileNameWithoutExtension.$sourceFileNameExtension< to $defaultFileNameExtension\n";
       
  2340 							$sourceFileNameExtension=$defaultFileNameExtension;
       
  2341 						}
       
  2342 					}
       
  2343 					else
       
  2344 					{
       
  2345 						next;
       
  2346 					}
       
  2347 				}
       
  2348 
       
  2349 				my $targetFileNameExtension;
       
  2350 # ecom.sNN should contain the corresponding language code .RNN files
       
  2351 				if(!$spidataflag and (defined $defaultLanguageCode and ($languageCode eq $defaultLanguageCode)))
       
  2352 				{
       
  2353 					$targetFileNameExtension = $defaultFileNameExtension;
       
  2354 				}
       
  2355 				else
       
  2356 				{
       
  2357 					$targetFileNameExtension = $sourceFileNameExtension;
       
  2358 				}
       
  2359 				my $modifiedfinalStuff = $finalStuff;
       
  2360 				$modifiedfinalStuff =~ s/\.spi/\.s$languageCode/i;
       
  2361 
       
  2362 				if ($spidatahide)
       
  2363 				{
       
  2364 					push @newobydata, "$initialStuff$sourceFileNameWithoutExtension.$sourceFileNameExtension$modifiedfinalStuff\n";
       
  2365 				}
       
  2366 				elsif ($datahide)
       
  2367 				{
       
  2368 					push @newobydata, "$initialStuff$targetFileNameWithoutExtension.$targetFileNameExtension$modifiedfinalStuff\n";
       
  2369 					if(!($sourceFileNameExtension eq $targetFileNameExtension))
       
  2370 					{
       
  2371 						push @newobydata, "$initialStuff$targetFileNameWithoutExtension.$sourceFileNameExtension$modifiedfinalStuff\n";
       
  2372 					}
       
  2373 				}
       
  2374 				else
       
  2375 				{
       
  2376 					push @newobydata, "$initialStuff$sourceFileNameWithoutExtension.$sourceFileNameExtension $targetFileNameWithoutExtension.$sourceFileNameExtension$modifiedfinalStuff\n";
       
  2377 					if(!($sourceFileNameExtension eq $targetFileNameExtension))
       
  2378 					{
       
  2379 						push @newobydata, "alias $targetFileNameWithoutExtension.$sourceFileNameExtension $targetFileNameWithoutExtension.$targetFileNameExtension $modifiedfinalStuff\n";
       
  2380 						$multiLinguifyAlias{"$targetFileNameWithoutExtension.$sourceFileNameExtension"} = 1;
       
  2381 					}
       
  2382 				}
       
  2383 			}
       
  2384 			$line = reassert_sourceline();
       
  2385 		}
       
  2386 		push @newobydata, $line;
       
  2387 	}
       
  2388 		
       
  2389 	@obydata = @newobydata;
       
  2390 	dump_obydata("tmp5.oby", "result of choosing language-specific files") if ($opt_v);
       
  2391 	undef @newobydata;
       
  2392 
       
  2393 }
       
  2394 
       
  2395 my @featurefilearray; #2d array storing names and locations of feature files in each rom image
       
  2396 my @featureslist; #array of hashes, stores all the features which are to go into the feature files
       
  2397 my $featurefilecount=0; #counts number of feature files in each rom image
       
  2398 my $featurescount=0; #counts number of features
       
  2399 my $dir; # Stores the ROM image location of features.dat/featreg.cfg files
       
  2400 my $featurefilename; # Stores the name of feature file to be generated(i.e. "features.dat" or "featreg.cfg")
       
  2401 my @spiarray; #2d array storing names and locations of spi files in each rom image
       
  2402 my @datafiles; #array of hashes, stores all the data files which are to go into the spi files
       
  2403 my @hidedatafiles; #array of hashes, stores all the data files which are to be hidden in the spi files
       
  2404 my $spicount=0; #counts number of spi files in each rom image
       
  2405 my $filescount=0; #counts number of data files
       
  2406 my $hidefilescount=0; #counts number of data files to be hidden
       
  2407 my $romimage=0; #number of rom image currently working with
       
  2408 
       
  2409 sub locateexisting 
       
  2410 { # if an SPI file of this type exists in a base image then returns name of SPI file from the array
       
  2411 	my ($romimage, $spifile, $base) =@_;
       
  2412 	my $i=0;
       
  2413 	while(defined $spiarray[$base][$i]) {
       
  2414 		if($spiarray[$base][$i]{spi} eq $spiarray[$romimage][$spifile]{spi}) {
       
  2415 			my $spiname;
       
  2416 			my $spiextension;
       
  2417 			if($spiarray[$base][$i]{spifile} =~ /(.*)\.(.*)$/) {
       
  2418 				$spiname=$1;
       
  2419 				$spiextension=$2;
       
  2420 			}
       
  2421 			if(-e "$spiname-$base-$i\.$spiextension") {
       
  2422 					return "$spiname-$base-$i\.$spiextension";
       
  2423 			}
       
  2424 		}
       
  2425 		$i++;
       
  2426 	}
       
  2427 	return "";
       
  2428 }
       
  2429 
       
  2430 sub create 
       
  2431 { #called to create SPI file and store in specified directory
       
  2432 	my ($romimage, $spifile, $base) =@_; #$romimage = current rom image number, $spifile = current spifile number, $base=number of rom image basing on
       
  2433 	my $existingspi = "";
       
  2434 	if(defined($base)) { # checks core image for an existing SPI file of this type, if an existing file exists then $existingspi is set to -i<name of existing spi file> which will later be passed to spitool.pm
       
  2435 		$existingspi = locateexisting($romimage, $spifile, $base);
       
  2436 		if($existingspi ne "") {
       
  2437 			$existingspi = "-i$existingspi";
       
  2438 			
       
  2439 		}
       
  2440 	}
       
  2441 	if($spiarray[$romimage][$spifile]{spifile} =~ /(.+)\.(.*)$/) {
       
  2442 		my $targetspi="$1-$romimage-$spifile\.$2"; #add romimage number and identifier for spi file to spi file name to distinguish from other spi files
       
  2443 		my @dataforspi; # array to store names of data files to include in spi file
       
  2444 		my @hidedatainspi; # array to store names of data files that are to be hidden in spi file
       
  2445 		for(my $k=0;$k<scalar @datafiles;$k++) {
       
  2446 			if($datafiles[$k]{rom}==$romimage && $datafiles[$k]{spifile} == $spifile) {
       
  2447 				push @dataforspi, $datafiles[$k]{data}; #push name of data file onto array if correct romimage and spi type
       
  2448 			}
       
  2449 		}
       
  2450 
       
  2451 		for(my $j=0;$j<scalar @hidedatafiles;$j++) {
       
  2452 			if($hidedatafiles[$j]{rom}==$romimage && $hidedatafiles[$j]{spifile} == $spifile)
       
  2453 			{
       
  2454 				push @hidedatainspi, $hidedatafiles[$j]{data}; #push name of data file to be hidden onto array if correct romimage and spi type
       
  2455 			}
       
  2456 		}
       
  2457 		my @spiargs; #arguments passed to createSpi
       
  2458 		push @spiargs, ("-t$targetspi", "-d\\$thisdir", "-hide@hidedatainspi");
       
  2459 		if($existingspi ne "") { push @spiargs, $existingspi; }
       
  2460 		&spitool::createSpi(@spiargs, @dataforspi); # external call to 
       
  2461 	}
       
  2462 }
       
  2463 
       
  2464 #----------------------------------------------------------------------------------
       
  2465 # SPI file creation phase
       
  2466 #
       
  2467 # If SPI files for resource (.rsc) are required then creates SPI files for each ROM image
       
  2468 #
       
  2469 sub spi_creation_phase
       
  2470 {
       
  2471 	my $composite_secondary=-1;
       
  2472 	if($createspi) { 
       
  2473 		my $secondary=0;
       
  2474 		for (my $i=1; $i<8; $i++)
       
  2475 		{
       
  2476 			if($romimage[$i]{composite} eq "composite_secondary") 
       
  2477 				{ $secondary++; }
       
  2478 		}
       
  2479 		if(!$secondary) 
       
  2480 			{ $romimage[0]{composite} = "composite_secondary"; }
       
  2481 		if($secondary>1)
       
  2482 			{ print "Warning, more than one composite_primary specified, using image with lowest ROM_IMAGE number\n"; }
       
  2483 	
       
  2484 		foreach $line (@obydata)
       
  2485 		{
       
  2486 			if ($line=~/^\s*REM \s*ROM_IMAGE\[(\d)\]/) # specify which romimage following lines are part of
       
  2487 			{
       
  2488 				$romimage=$1;
       
  2489 				$spicount=0;
       
  2490 			}	elsif ($line =~ /^\s*REM/i)
       
  2491 			{
       
  2492 				# ignore any other REM statements
       
  2493 			} elsif ($line=~/^\s*spidata\s*=\s*(\S+)\s+(\S+)\s+(\S+)\s(\S+)\s*$/)	{
       
  2494 				#spidata=\epoc32\data\Z\Resource\Plugins\Obexclasscontroller.RSC Resource\Plugins\Obexclasscontroller.RSC ecom.spi \private\10003a3f\
       
  2495 				my $targetspi=$4.$3;
       
  2496 				my $flag=1;
       
  2497 				my $i;
       
  2498 				for($i=0;$i<$spicount && $flag;$i++) { #loop to see if name of spi file already added to this romimage in array
       
  2499 					if($spiarray[$romimage][$i]{spi} eq $targetspi) {
       
  2500 						$flag=0;
       
  2501 					}
       
  2502 				}
       
  2503 			
       
  2504 				if($flag) { # adds spi file if not yet listed for this romimage in array
       
  2505 					$spiarray[$romimage][$spicount++]={spifile=>$3, spidir=>$4, spi=>$4.$3};
       
  2506 					$i=$spicount;
       
  2507 				}
       
  2508 					$datafiles[$filescount++]= {data=>$1, rom=>$romimage, spifile=>$i-1}; 
       
  2509                         } elsif ($spiplacement && $line =~/^\s*SPI_POSITION/i){
       
  2510         			# mark the image index at which the SPI_POSITION keyword has occured in order to avoid writing duplicate
       
  2511         			# entries of the spi file.
       
  2512         			$spipositionflag{$romimage} = 1;
       
  2513         		} elsif ($line=~/^\s*spidatahide\s*=\s*(\S+)\s+(\S+)\s(\S+)\s*$/)	{
       
  2514 				#spidatahide=\epoc32\data\Z\Resource\Plugins\Obexclasscontroller.RSC ecom.spi \private\10003a3f\
       
  2515 				my $targetspi=$3.$2;
       
  2516 				my $flag=1;
       
  2517 				my $i;
       
  2518 				for($i=0;$i<$spicount && $flag;$i++) { #loop to see if name of spi file already added to this romimage in array
       
  2519 					if($spiarray[$romimage][$i]{spi} eq $targetspi) {
       
  2520 						$flag=0;
       
  2521 					}
       
  2522 				}
       
  2523 			
       
  2524 				if($flag) { # adds spi file if not yet listed for this romimage in array
       
  2525 					$spiarray[$romimage][$spicount++]={spifile=>$2, spidir=>$3, spi=>$3.$2};
       
  2526 					$i=$spicount;
       
  2527 				}
       
  2528 					$hidedatafiles[$hidefilescount++]= {data=>$1, rom=>$romimage, spifile=>$i-1}; 
       
  2529 			}
       
  2530 
       
  2531 		}
       
  2532 		
       
  2533 		for(my $i=0;$i<8 && $composite_secondary<0;$i++) { # loop to set $composite_secondary value
       
  2534 			if($romimage[$i]{composite} eq "composite_secondary") {
       
  2535 				$composite_secondary=$i;
       
  2536 			}
       
  2537 		}	
       
  2538 	
       
  2539 		for(my $i=0;$i<8;$i++) { #loop to add any spi files to composite_primary roms which are present in composite_secondary rom. spi files in secondary ROMs must be present in primary ROMS, this check rules out the possibility of the spi file in the primary rom not being created because it has no data files to add
       
  2540 			if($romimage[$i]{composite} eq "composite_primary") {
       
  2541 				my $j=0;
       
  2542 				while(defined $spiarray[$composite_secondary][$j]) {
       
  2543 					my $flag=1;
       
  2544 					my $k=0;
       
  2545 					while(defined $spiarray[$i][$k] && $flag) {
       
  2546 						if($spiarray[$composite_secondary][$j]{spi} eq $spiarray[$i][$k]{spi}) {
       
  2547 							$flag=0;
       
  2548 						}
       
  2549 						$k++;
       
  2550 					}
       
  2551 					if($flag) {
       
  2552 						$spiarray[$i][$k]{spifile}=$spiarray[$composite_secondary][$j]{spifile};
       
  2553 						$spiarray[$i][$k]{spidir}=$spiarray[$composite_secondary][$j]{spidir};
       
  2554 						$spiarray[$i][$k]{spi}=$spiarray[$composite_secondary][$j]{spi};
       
  2555 					}
       
  2556 					$j++;
       
  2557 				}
       
  2558 			}
       
  2559 		}
       
  2560 		
       
  2561 		for(my $i=0;$i<8;$i++) { #loop to add any spi files to extension roms which are present in core rom, same situation as in previous loop could potentially occur here
       
  2562 			if($romimage[$i]{extension}) {
       
  2563 				my $j=0;
       
  2564 				while(defined $spiarray[$i-1][$j]) {
       
  2565 					my $flag=1;
       
  2566 					my $k=0;
       
  2567 					while(defined $spiarray[$i][$k] && $flag) {
       
  2568 						if($spiarray[$i-1][$j]{spi} eq $spiarray[$i][$k]{spi}) {
       
  2569 							$flag=0;
       
  2570 						}
       
  2571 						$k++;
       
  2572 					}
       
  2573 					if($flag) {
       
  2574 						$spiarray[$i][$k]{spifile}=$spiarray[$i-1][$j]{spifile};
       
  2575 						$spiarray[$i][$k]{spidir}=$spiarray[$i-1][$j]{spidir};
       
  2576 						$spiarray[$i][$k]{spi}=$spiarray[$i-1][$j]{spi};
       
  2577 					}
       
  2578 					$j++;
       
  2579 				}
       
  2580 			}
       
  2581 		}
       
  2582 	
       
  2583 		for(my $i=0;$i<scalar @spiarray;$i++) { #create SPI files for ROMs which are neither composite_primary nor extensions
       
  2584 			if(!($romimage[$i]{extension}) && $romimage[$i]{composite} ne "composite_primary") {
       
  2585 				my $j=0;
       
  2586 				while(defined $spiarray[$i][$j]) { 
       
  2587 					create($i,$j++);
       
  2588 				}
       
  2589 			}
       
  2590 		}	
       
  2591 	
       
  2592 		for(my $i=0;$i<8;$i++) { #create SPI files for ROMs marked as composite_primary
       
  2593 			if($romimage[$i]{composite} eq "composite_primary") {
       
  2594 				my $j=0;
       
  2595 				while(defined $spiarray[$i][$j]) {
       
  2596 					create($i,$j++,$composite_secondary);
       
  2597 				}
       
  2598 			}
       
  2599 		}	
       
  2600 		for(my $i=0;$i<8;$i++) { #create SPI files for ROMs marked as extension
       
  2601 			if($romimage[$i]{extension}) {
       
  2602 				my $j=0;
       
  2603 				while(defined $spiarray[$i][$j]) {
       
  2604 					create($i,$j++,$i-1);
       
  2605 				}
       
  2606 			}
       
  2607 		}
       
  2608 			
       
  2609 		undef @newobydata;
       
  2610 		my $flag=1;
       
  2611         	my $imageIdx=0;
       
  2612 		foreach $line (@obydata) { #add SPI files to ROM image, adds lines to obey file to specify existing locations of SPI files and target locations.
       
  2613 
       
  2614                         if($spiplacement){
       
  2615                                 $flag = 0;	# Reset the flag since the spi file must be added to the final OBY only on finding SPI_POSITION 
       
  2616                                                         # keyword when the spiplacement flag is set. If the spiplacement flag is set but SPI_POSITION
       
  2617                                                         # is not found in the oby files, then no spi entry is emitted.
       
  2618                                 if($line =~ /^\s*SPI_POSITION/i){
       
  2619                                         next if (!$spipositionflag{$imageIdx});#This spi has already been entered into OBY.
       
  2620                                         my $spiIdx=0;
       
  2621                                         while(defined $spiarray[$imageIdx][$spiIdx]) {
       
  2622                                                 if($spiarray[$imageIdx][$spiIdx]{spifile} =~ /(.+)\.(.*)$/) {
       
  2623                                                         my $targetspi="$1-$imageIdx-$spiIdx\.$2";
       
  2624                                                         push @newobydata, "data=" . "\\$thisdir" . $targetspi . " \"" . $spiarray[$imageIdx][$spiIdx]{spi} . "\"\n";
       
  2625                                                 }
       
  2626                                                 $spiIdx++;
       
  2627                                         }
       
  2628                                         if($spiIdx == 0){
       
  2629                                                 # If there is no plugin in this image, the SPI_POSITION statement is ignore.
       
  2630                                                 print ("Warning: statement SPI_POSTION ignored as no plugin was found at ROM_IMAGE[${imageIdx}]\n");
       
  2631                                         }
       
  2632                                         $spipositionflag{$imageIdx} = 0;
       
  2633                                 }
       
  2634                                 elsif( $line =~ /REM ROM_IMAGE\[(\d)\]/i){
       
  2635                                         $imageIdx = $1;
       
  2636                                         push @newobydata, $line;
       
  2637                                 }
       
  2638                                 elsif($line =~ /^\s*spidata/i) {
       
  2639                                 } else {
       
  2640                                         push @newobydata, $line;
       
  2641                                 }
       
  2642                         }
       
  2643 			elsif($line =~/REM ROM_IMAGE\[(\d)\]/) {
       
  2644 				my $romimage=$1;
       
  2645 				if($flag) { #put in SPI files for ROM_IMAGE[0]
       
  2646 					$flag=0;
       
  2647 					my $k=0;
       
  2648 					while(defined $spiarray[0][$k]) {
       
  2649 						if($spiarray[0][$k]{spifile} =~ /(.+)\.(.*)$/) {
       
  2650 							my $targetspi="$1-0-$k\.$2";
       
  2651 							push @newobydata, "data=" . "\\$thisdir" . $targetspi . " \"" . $spiarray[0][$k]{spidir} . $targetspi .  "\"\n";
       
  2652 						}
       
  2653 						$k++;
       
  2654 					}
       
  2655 				}
       
  2656 				my $j=0;
       
  2657 				push @newobydata, "\n" . $line . "\n";			
       
  2658 				while(defined $spiarray[$romimage][$j]) { #put in SPI files for current ROM_IMAGE
       
  2659 					if($spiarray[$romimage][$j]{spifile} =~ /(.+)\.(.*)$/) {
       
  2660 						my $targetspi="$1-$romimage-$j\.$2";
       
  2661 						push @newobydata, "data=" . "\\$thisdir" . $targetspi . " \"" . $spiarray[$romimage][$j]{spidir} . $targetspi .  "\"\n";
       
  2662 					}
       
  2663 					$j++;
       
  2664 				}
       
  2665 			} elsif($line =~ /^\s*extensionrom/i) {
       
  2666 				if($flag) { #put in SPI files
       
  2667 					my $k=0;
       
  2668 					while(defined $spiarray[0][$k]) {
       
  2669 						if($spiarray[0][$k]{spifile} =~ /(.+)\.(.*)$/) {
       
  2670 							my $targetspi="$1-0-$k\.$2";
       
  2671 							push @newobydata, "data=" . "\\$thisdir" . $targetspi . " \"" . $spiarray[0][$k]{spidir} . $targetspi . "\"\n";
       
  2672 						}
       
  2673 						$k++;
       
  2674 					}
       
  2675 					$flag = 0;
       
  2676 				}
       
  2677 				push @newobydata, $line;
       
  2678 			} elsif($line =~ /^\s*spidata/i) {;
       
  2679 			} else {
       
  2680 				push @newobydata, $line;
       
  2681 			}
       
  2682 		}
       
  2683 		if($flag) { #put in SPI files for ROM_IMAGE[0] if it is the only ROM_IMAGE
       
  2684 			my $k=0;
       
  2685 			while(defined $spiarray[0][$k]) {
       
  2686 				if($spiarray[0][$k]{spifile} =~ /(.+)\.(.*)$/) {
       
  2687 					my $targetspi="$1-0-$k\.$2";
       
  2688 					push @newobydata, "data=" . "\\$thisdir" . $targetspi . " \"" . $spiarray[0][$k]{spidir} . $targetspi . "\"\n";
       
  2689 				}
       
  2690 				$k++;
       
  2691 			}
       
  2692 		}
       
  2693 		@obydata=@newobydata;
       
  2694 	}	
       
  2695 	dump_obydata("tmp6.oby", "result of SPI stage") if ($opt_v);
       
  2696 }
       
  2697 
       
  2698 sub load_featuresutil
       
  2699 {
       
  2700 	&Load_ModuleL("featuresutil");
       
  2701 			
       
  2702 	# Parse the feature database XML file
       
  2703 	if(!&featuresutil::parseXMLDatabase($featureXml, $featuremanager, $strict))
       
  2704 	{
       
  2705 		$featureXml = undef;
       
  2706 		exit(1) if($strict);
       
  2707 	}
       
  2708 }
       
  2709 
       
  2710 #----------------------------------------------------------------------------------
       
  2711 # Feature registry configuration file/Features data file generation phase
       
  2712 #
       
  2713 # If feature registry configuration files/features data files are required then creates these files for
       
  2714 # each ROM/ROFS image
       
  2715 #
       
  2716 sub featurefile_creation_phase
       
  2717 {
       
  2718 	if($onlysmrimage)
       
  2719 	{
       
  2720 		return;
       
  2721 	}
       
  2722 	# Set the name and Rom Image location of feature file.
       
  2723 	if ($enforceFeatureManager) 
       
  2724 	{
       
  2725 		# features data file location
       
  2726 		$dir = "private\\10205054\\";
       
  2727 		$featurefilename = "features.dat";
       
  2728 	}
       
  2729 	else
       
  2730 	{
       
  2731 		# feature registry configuration file location
       
  2732 		$dir = "private\\102744CA\\"; 
       
  2733 		$featurefilename = "featreg.cfg";
       
  2734 	}		
       
  2735 	if (defined ($featureXml)) 
       
  2736 	{
       
  2737 		my $featurefilecount=0;
       
  2738 		my $romimage=0;
       
  2739 
       
  2740 		foreach $line (@obydata)
       
  2741 		{
       
  2742 			# specify which romimage following lines are part of
       
  2743 			if ($line=~/^\s*REM \s*ROM_IMAGE\[(\d)\]/) 
       
  2744 			{
       
  2745 				$romimage=$1;
       
  2746 				$featurefilecount=0;
       
  2747 			}
       
  2748 			elsif ($line =~ /^\s*REM/i)
       
  2749 			{
       
  2750 				# ignore any other REM statements
       
  2751 			}
       
  2752 			elsif($line =~ /^\s*(FEATURE)\s*(\S*)\s*(.*)/i
       
  2753 					|| $line =~ /^\s*(EXCLUDE_FEATURE)\s*(\S*)\s*(.*)/i)
       
  2754 			{				
       
  2755 				# FEATURE  <feature_name>  [ SF  <status falgs> ] [ UD  <user data> ]
       
  2756 				my $feature = $1;
       
  2757 				my $featurevalue = $2;
       
  2758 				my $featureargs = $3;
       
  2759 				my $reservedbit = 0;
       
  2760 				my %featureflags=();				
       
  2761 				
       
  2762 				# Options 'SF' and 'UD' will be supported only for "-fm" option
       
  2763 				if ($featuremanager) 
       
  2764 				{
       
  2765 					# [ SF  <status falgs> ] [ UD  <user data> ]
       
  2766 					$featureargs =~	/(\S*)\s*(\S*)\s*(\S*)\s*(\S*)\s*/ ;
       
  2767 
       
  2768 					# Store the values of 'SF' and 'UD', or any invalid option, if provided					
       
  2769 					if ($1) 
       
  2770 					{	
       
  2771 						$featureflags{uc($1)} = $2;						
       
  2772 					}
       
  2773 					if ($3) 
       
  2774 					{
       
  2775 						$featureflags{uc($3)} = $4;									
       
  2776 					}
       
  2777 
       
  2778 					# Generate a warning if the option provided with Feature/Exclude_Feature keyword is  
       
  2779 					# not 'SF' or 'UD'.
       
  2780 					foreach my $Key (keys %featureflags)
       
  2781 					{						
       
  2782 						if ($Key !~ /^(SF|UD)$/)
       
  2783 						{
       
  2784 							print "Warning: Invalid argument \"$Key\" specified for feature $featurevalue\n";
       
  2785 							delete $featureflags{$Key};
       
  2786 							next;
       
  2787 						}						
       
  2788 					}							
       
  2789 				}				
       
  2790 				# In verbose mode, generate warning if "SF|UD" arguments or invalid arguments are specified
       
  2791 				# for "-f|fr" option.
       
  2792 				elsif ($featureargs && $opt_v)
       
  2793 				{
       
  2794 					print "Invalid argument(s) \"$featureargs\" provided for feature \"$featurevalue\"\n";
       
  2795 					foreach my $Key (keys %featureflags)
       
  2796 					{
       
  2797 						delete $featureflags{$Key};
       
  2798 					}
       
  2799 				}				
       
  2800 				
       
  2801 				# The feature file name is of the format featreg.cfg[x-y] or features.dat[x-y] 
       
  2802 				# where x is the romimage id, y is always 0, reserved for future use.
       
  2803 				my $targetfeaturefile;
       
  2804 				if (($romimage == 0) && ($reservedbit == 0))
       
  2805 				{
       
  2806 
       
  2807 					# Core image will not have the mangled name
       
  2808 				 	$targetfeaturefile = $featurefilename;
       
  2809 				}
       
  2810 				else
       
  2811 				{
       
  2812 				 	$targetfeaturefile = $featurefilename . "\[". $romimage . "\-$reservedbit\]";
       
  2813 				}
       
  2814 				my $flag=1;
       
  2815 				my $featureflag;
       
  2816 				if ($feature =~ /^FEATURE$/i)
       
  2817 				{
       
  2818 					$featureflag = 1;
       
  2819 				}
       
  2820 				else
       
  2821 				{
       
  2822 					$featureflag = 0;
       
  2823 				}
       
  2824 
       
  2825 				my $i;
       
  2826  				# loop to see if name of feature file already added to this romimage in array
       
  2827 				for($i=0;$i<$featurefilecount && $flag;$i++)
       
  2828 				{
       
  2829 					if($featurefilearray[$romimage][$i]{cfgfile} eq $targetfeaturefile)
       
  2830 					{
       
  2831 						$flag=0;
       
  2832 					}
       
  2833 				}
       
  2834 			
       
  2835 				if($flag) { # adds feature file if not yet listed for this romimage in array
       
  2836 					$featurefilearray[$romimage][$featurefilecount++]={cfgfile=>$targetfeaturefile, cfgdir=>$dir};
       
  2837 					$i=$featurefilecount;
       
  2838 				}
       
  2839 
       
  2840 				$featureslist[$featurescount]= {feature=>$featurevalue, include=>$featureflag, rom=>$romimage, cfgfile=>$i-1};
       
  2841 				
       
  2842 				# Store the value of 'SF' in 'featureslist' array
       
  2843 				if (defined $featureflags{SF}) 
       
  2844 				{
       
  2845 					$featureslist[$featurescount]->{SF} = $featureflags{SF};						
       
  2846 				}
       
  2847 				# Store the value of 'UD' in 'featureslist' array
       
  2848 				if (defined $featureflags{UD}) 
       
  2849 				{
       
  2850 					$featureslist[$featurescount]->{UD} = $featureflags{UD};
       
  2851 				}				
       
  2852 				$featurescount++;
       
  2853 			}
       
  2854 		}
       
  2855 
       
  2856 		# Create Feature File
       
  2857 		for(my $i=0;$i<scalar @featurefilearray;$i++)
       
  2858 		{
       
  2859 			my $j=0;
       
  2860 			while(defined $featurefilearray[$i][$j])
       
  2861 			{
       
  2862 				my $targetfeaturefile = $featurefilearray[$i][$j]{cfgfile};
       
  2863 				if (!(&featuresutil::createFeatureFile($i,$j,$targetfeaturefile,\@featureslist,$featuremanager))) 
       
  2864 				{
       
  2865 					$featurefilearray[$i][$j]{cfgfile}= undef;
       
  2866 					exit(1) if($strict);					
       
  2867 				}
       
  2868 				$j++;
       
  2869 			}
       
  2870 		}
       
  2871 	
       
  2872 		undef @newobydata;
       
  2873 		my $flag=1;
       
  2874         	my $imageIdx=0;
       
  2875 
       
  2876 		# Add feature files to ROM image, adds lines to obey file to specify existing locations
       
  2877 		# of feature files and target locations.
       
  2878 		foreach $line (@obydata)
       
  2879 		{
       
  2880 			if($line =~/REM ROM_IMAGE\[(\d)\]/i)
       
  2881 			{
       
  2882 				my $romimage=$1;
       
  2883 				if($flag)
       
  2884 				{
       
  2885 					# Put in feature files for ROM_IMAGE[0]
       
  2886 					$flag=0;
       
  2887 					my $k=0;
       
  2888 					while(defined $featurefilearray[0][$k])
       
  2889 					{
       
  2890 						my $targetfeaturefile=$featurefilearray[0][$k]{cfgfile};
       
  2891 						if (defined $targetfeaturefile) 
       
  2892 						{
       
  2893 							push @newobydata, "data=" . "\\$thisdir" . $targetfeaturefile . " \"" . $featurefilearray[0][$k]{cfgdir} . $targetfeaturefile .  "\"\n";							
       
  2894 						}
       
  2895 						$k++;
       
  2896 					}
       
  2897 				}
       
  2898 				push @newobydata, "\n" . $line . "\n";			
       
  2899 
       
  2900 				my $j=0;
       
  2901 				while(defined $featurefilearray[$romimage][$j])
       
  2902 				{
       
  2903 					# Put in feature files for current ROM_IMAGE
       
  2904 					my $targetfeaturefile=$featurefilearray[$romimage][$j]{cfgfile};
       
  2905 					
       
  2906 					# Rom images will not have mangled name for feature files
       
  2907 				 	my $destinationfeaturefile = $featurefilename;
       
  2908 					
       
  2909 					# Rofsbuild will set attribute 'exattrib=U' in the entry record when this field is used.
       
  2910 					# File Server when asked for a directory listing would notice the attribute and will return the 
       
  2911 					# list with mangled names. Hence, mangled name for feature files should not be put in ROM_IMAGE.
       
  2912 					my $exattribute = "exattrib=U";
       
  2913 
       
  2914 					if (defined $targetfeaturefile)
       
  2915 					{
       
  2916 						push @newobydata, "data=" . "\\$thisdir" . $targetfeaturefile . " \"" . $featurefilearray[$romimage][$j]{cfgdir} . $destinationfeaturefile .  "\"\t\t" . $exattribute . "\n";
       
  2917 					}
       
  2918 					$j++;
       
  2919 				}
       
  2920 			}
       
  2921 			elsif($line !~ /^\s*(FEATURE)\s*/i && $line !~ /^\s*(EXCLUDE_FEATURE)\s*/i)
       
  2922 			{
       
  2923 				# Put in all other lines except the FEATURE and EXCLUDE_FEATURE keywords
       
  2924 				push @newobydata, $line;
       
  2925 			}
       
  2926 		}
       
  2927 
       
  2928 		if($flag)
       
  2929 		{ 
       
  2930 			# Put in feature files for ROM_IMAGE[0] if it is the only ROM_IMAGE
       
  2931 			my $k=0;
       
  2932 			while(defined $featurefilearray[0][$k])
       
  2933 			{
       
  2934 				my $targetfeaturefile = $featurefilearray[0][$k]{cfgfile};
       
  2935 				if (defined $targetfeaturefile)
       
  2936 				{
       
  2937 					push @newobydata, "data=" . "\\$thisdir" . $targetfeaturefile . " \"" . $featurefilearray[0][$k]{cfgdir} . $targetfeaturefile . "\"\n";
       
  2938 				}
       
  2939 				$k++;
       
  2940 			}
       
  2941 		}
       
  2942 		@obydata=@newobydata;
       
  2943 	}
       
  2944 	elsif ($enforceFeatureManager && $noFeatureManager && $preBuiltFeaturesDataFile)
       
  2945 	{
       
  2946         print "Valid: $preBuiltFeaturesDataFile\n";
       
  2947 		if (-e $preBuiltFeaturesDataFile) 
       
  2948 		{			
       
  2949 			my @newobydata = ();
       
  2950 			my $flag = 1;
       
  2951 			foreach my $line (@obydata)
       
  2952 			{
       
  2953 				# Put in the pre-built features data file in ROM_IMAGE[0] 
       
  2954 				if($line =~/REM ROM_IMAGE\[1\]/i)
       
  2955 				{
       
  2956 					push @newobydata, "data=$preBuiltFeaturesDataFile" . " \"" . $dir . $featurefilename . "\"\n";
       
  2957 					$flag =0;
       
  2958 				}
       
  2959 				push @newobydata, $line;
       
  2960 			}
       
  2961 			if($flag)
       
  2962 			{ 
       
  2963 				# Put in the pre-built features data file in ROM_IMAGE[0] if it is the only ROM_IMAGE
       
  2964 				push @newobydata, "data=$preBuiltFeaturesDataFile" . " \"" . $dir . $featurefilename . "\"\n";
       
  2965 			}
       
  2966 			@obydata =  @newobydata;
       
  2967 		}
       
  2968 		else
       
  2969 		{
       
  2970 			print "Error: File \"$preBuiltFeaturesDataFile\" doesn't exist.\n";
       
  2971 			exit(1);
       
  2972 		}
       
  2973 	}
       
  2974 	elsif ($enforceFeatureManager)
       
  2975 	{
       
  2976 	    print "Error: no feature data file or pre-built feature data file is provided!";
       
  2977 	    exit(1);
       
  2978 	}
       
  2979 }
       
  2980 my ($fromABI,$toABI) = split / /,$abiDowngrade;
       
  2981 
       
  2982 #----------------------------------------------------------------------------------
       
  2983 # Problem suppression phase
       
  2984 #
       
  2985 # Downgrade files which don't exist for the ABI (if a downgrade path is specified)
       
  2986 # Comment out missing files or report errors if strict option enabled
       
  2987 #
       
  2988 # Detect any references to Feature Variant binaries and substitute in the
       
  2989 # correct source binary name using the VMAP file mechanism.
       
  2990 
       
  2991 sub suppress_phase
       
  2992 {
       
  2993 	undef @newobydata;
       
  2994 	Plat_Init($PerlLibPath);
       
  2995 
       
  2996 	# use the "default" feature variant by default.
       
  2997 	my $varname = $featureVariant{'VALID'} ? $featureVariant{'NAME'} : "default";
       
  2998 
       
  2999 	foreach $line (@obydata)
       
  3000 	{
       
  3001 		track_source($line);
       
  3002 		if ($line =~ /^\s*REM/i)
       
  3003 		{
       
  3004 			# ignore REM statements, to avoid processing "REM data=xxx yyy"
       
  3005 		}
       
  3006 		# 
       
  3007 		# thing=some\file 
       
  3008 		#
       
  3009 		elsif ($line =~ /(\S+)\s*=\s*"?(\S+\\\S+)"?/)
       
  3010 		{
       
  3011 			my $what = $1;
       
  3012 			my $filename = $2;
       
  3013 			if ($line =~ /(\S+)\s*=\s*"([^"]+)"/)
       
  3014 			{
       
  3015 				$filename = $2;
       
  3016 			}
       
  3017 			my $normedFilename = &Genutl_NormaliseVersionedName($filename);
       
  3018 
       
  3019 			# find all the alternative file locations
       
  3020 			my @alternatives = fallback($normedFilename);
       
  3021 			# test the original location first
       
  3022 			unshift(@alternatives, $normedFilename);
       
  3023 
       
  3024 			# choose the first file location that actually exists
       
  3025 			my $fileExists = 0;
       
  3026 			foreach my $altFile (@alternatives)
       
  3027 			{
       
  3028 			    my $tmpPath;
       
  3029 			    my $tmpFile;
       
  3030 				if($altFile =~ /"?(.*\\arm\w+_?\w+)\\([^"]+)/i)
       
  3031 				{
       
  3032 					$tmpPath = $1;
       
  3033 					$tmpFile = $2;
       
  3034 				}
       
  3035 				$tmpPath .= "\.$varname";
       
  3036 				if (-d $tmpPath){
       
  3037 				  if (-e $tmpPath ."\\$tmpFile"){
       
  3038 				   $fileExists = $tmpPath . "\\$tmpFile";
       
  3039 				  }
       
  3040 				  elsif (-e $altFile){
       
  3041 				   $fileExists = $altFile;
       
  3042 				  }
       
  3043 				}
       
  3044 				else {
       
  3045 				  $fileExists = featurevariantmap->Find($altFile, $varname);
       
  3046 				}
       
  3047 				last if $fileExists;
       
  3048 			}
       
  3049 
       
  3050 			# edit the OBY line to use the actual file name which we found.
       
  3051 			# (maybe) warn if an alternative to the original was selected.
       
  3052 			if ($fileExists)
       
  3053 			{
       
  3054 				my $from = $filename;
       
  3055 				$from =~ s/\\/\\\\/g;		# need to escape backslashes
       
  3056 				$from =~ s/(\[|\])/\\$1/g;	# need to escape square brackets for file names like "featreg.cfg[x-y]",etc.
       
  3057 				my $into = $fileExists;
       
  3058 
       
  3059  				$line =~ s/$from/$into/;
       
  3060 
       
  3061  				if ($warnSelection && ($fileExists ne $normedFilename))
       
  3062 				{
       
  3063 			    	print "replaced $filename with $fileExists\n";
       
  3064 				}
       
  3065 			}
       
  3066 			else
       
  3067 			{
       
  3068    				# No suitable alternative was found, so comment out the line unless
       
  3069 				# it is a manatory ROMBUILD keyword, in which case it is better
       
  3070 				# to let ROMBUILD report the missing file rather than report the
       
  3071 				# missing keyword.
       
  3072    				if ($what !~ /^bootbinary|variant|primary|secondary|hide/i)
       
  3073 				{
       
  3074    					$line = "REM MISSING " . $line;
       
  3075    					print_source_error("Missing file: '$filename' in statement '$what='");
       
  3076 					print "\ttried @alternatives\n"  if ($opt_v && @alternatives > 1);
       
  3077    					# treat as an error if the strict option is selected.
       
  3078    					$errors++ if ($strict);
       
  3079 				}
       
  3080 			}
       
  3081 
       
  3082 			# Once the binary is located in the appropriate ABI directory (e.g.,following the binary 
       
  3083 			# selection order), check if the binary has been used in a patch dll statement. This is
       
  3084 			# required to find out the source file. In ABIv1, the source file is required to find the
       
  3085 			# .map file, while, in ABIv2, the destination file gives the dso file name.
       
  3086 			if($line =~ /(\S+)\s*=\s*(\S+)\s+(\S+)\s*(.*)?/)
       
  3087 			{
       
  3088 				my $aSrcfile = $2;
       
  3089 				my $dstFile = $3;
       
  3090 				my $dstPath = "";
       
  3091 
       
  3092 				if($aSrcfile =~ /"?([^"]+)/){
       
  3093 				$aSrcfile = $1;
       
  3094 				}
       
  3095 
       
  3096 				$aSrcfile = &Genutl_NormaliseVersionedName($aSrcfile);
       
  3097 				if($dstFile =~ /"?(.*)\\([^"]+)/)
       
  3098 				{
       
  3099 					$dstPath = $1;
       
  3100 					$dstFile = $2;
       
  3101 				}
       
  3102 				my $dllMapKey = lc ($dstFile);
       
  3103 				if(exists $DllDataMap{$dllMapKey}) {
       
  3104 					my $dllSymInfo = \%{$DllDataMap{$dllMapKey}};
       
  3105 					$dllSymInfo->{srcfile} = $aSrcfile;
       
  3106 					$dllSymInfo->{dstpath} = $dstPath;
       
  3107 				}
       
  3108 			}
       
  3109 
       
  3110 		}
       
  3111 		push @newobydata, $line;
       
  3112 	}
       
  3113 	@obydata = @newobydata;
       
  3114 	dump_obydata("tmp7.oby", "result of problem-suppression phase") if ($opt_v);
       
  3115 	die "ERROR: $errors missing file(s) detected\n" if ($strict && $errors );
       
  3116 }
       
  3117 
       
  3118 # Remove leading and trailing whitespaces from a list of strings or a single string
       
  3119 sub trim 
       
  3120 {
       
  3121 	my @out = @_;
       
  3122 	for (@out) {
       
  3123 		s/^\s+//;
       
  3124 		s/\s+$//;
       
  3125 	}
       
  3126 	return wantarray ? @out : $out[0];
       
  3127 }
       
  3128 
       
  3129 # Generate a list of alternative locations for the given filename
       
  3130 sub fallback
       
  3131 {
       
  3132    	my $file = shift;
       
  3133    	my @alternatives = CheckCustomization($file);
       
  3134  
       
  3135  	# If BINARY_SELECTION_ORDER macro is specified in the oby file
       
  3136  	if ($binarySelectionOrderFlag)
       
  3137    	{
       
  3138  		# Search in the specified binary order 
       
  3139  		if(!defined(@Global_PlatList))
       
  3140 		{
       
  3141 			@Global_PlatList = Plat_List();
       
  3142 		}
       
  3143  		my $b;
       
  3144  		my $e;
       
  3145  		foreach my $plat (@Global_PlatList) 
       
  3146   		{
       
  3147   			if ($file =~ /^(.*)\\$plat\\(.*)$/i) 
       
  3148   			{
       
  3149   				$b = $1;
       
  3150   				$e = $2;
       
  3151  				last;
       
  3152  			}
       
  3153  		}
       
  3154  		push(@alternatives, "$b\\$firstDIR\\$e");
       
  3155  			
       
  3156  		foreach my $toDIR (@binarySelectionOrder)
       
  3157    		{
       
  3158  			push(@alternatives, "$b\\$toDIR\\$e");
       
  3159    		}
       
  3160    	}
       
  3161   	
       
  3162  	# If the file is not found in the specified ABIV2 platform, then select from ARMV5 directory.
       
  3163  	# This is necessary as some of the runtime DLLs will be present only in ARMV5 directory. 
       
  3164 	# Add the BPABI Platforms to be added
       
  3165 	if(!defined(@Global_BPABIPlats))
       
  3166 	{
       
  3167 		@Global_BPABIPlats = &BPABIutl_Plat_List;
       
  3168 	}
       
  3169 
       
  3170  	foreach my $BpabiPlat (@Global_BPABIPlats)
       
  3171  	{
       
  3172  		if ($fromABI eq "" && $file =~ /^(.*)\\$BpabiPlat\\(.*)$/)
       
  3173    		{
       
  3174  			push(@alternatives, "$1\\armv5\\$2");
       
  3175    		}
       
  3176    	}
       
  3177 
       
  3178 	if ($customizedPlat && $fromABI eq "" && $file =~ /^(.*)\\$customizedPlat\\(.*)$/)
       
  3179 	{
       
  3180 		my $b = $1;
       
  3181 		my $e = $2;
       
  3182 		# if platform customization 
       
  3183 		my $rootPlat = Plat_Root($customizedPlat);		
       
  3184         
       
  3185    		#Check in ARMV7 folder for binaries in case GCCEV7 is used [DEF128457 ]
       
  3186    		if($customizedPlat == "GCCEV7")
       
  3187    		{
       
  3188    			push(@alternatives,"$b\\armv7\\$e");
       
  3189    		}
       
  3190 
       
  3191 		if( grep /$rootPlat/, @Global_BPABIPlats)
       
  3192 		{
       
  3193  			push(@alternatives, "$b\\armv5\\$e");
       
  3194 		}
       
  3195 	}
       
  3196 
       
  3197 	if ($fromABI eq "" && $file =~ /^(.*)\\ARMV5_ABIV1\\(.*)$/i)
       
  3198    	{
       
  3199  		push(@alternatives, "$1\\armv5\\$2");
       
  3200    	}
       
  3201   		
       
  3202    	if ($fromABI ne "" && $file =~ /^(.*)\\$fromABI\\(.*)$/)
       
  3203 	{
       
  3204  		push(@alternatives, "$1\\$toABI\\$2");
       
  3205 	}
       
  3206    
       
  3207    	return @alternatives;
       
  3208 }
       
  3209 
       
  3210 # Generate a list of alternative locations for the given filename which
       
  3211 # result from the possible platform customizations.
       
  3212 sub CheckCustomization
       
  3213 {
       
  3214  	my $file = shift;
       
  3215  	my @alternatives;
       
  3216 	$customizedPlat = undef;	# global (used in feedback)
       
  3217 
       
  3218  	if(!defined(@Global_PlatList))
       
  3219 	{
       
  3220 		@Global_PlatList = Plat_List();
       
  3221 	}
       
  3222  	foreach my $plat (@Global_PlatList) 
       
  3223 	{
       
  3224  		if ($file =~ /^(.*)\\$plat\\(.*)$/i) 
       
  3225 		{
       
  3226  			my $b = $1;
       
  3227  			my $e = $2;
       
  3228  			my $root = Plat_Customizes($plat);
       
  3229  			if ($root) 
       
  3230 			{
       
  3231 				# Preserve the plat that is customized
       
  3232 				$customizedPlat = $plat;
       
  3233 
       
  3234 				# If a BSF platform customizes another BSF platform (i.e. a
       
  3235 				# BSF hierarchy exists), look for the file starting from the
       
  3236 				# child BSF platform and working back to the root BSF platform
       
  3237 				while ($root)
       
  3238 				{
       
  3239 					push(@alternatives, "$b\\$root\\$e");
       
  3240 
       
  3241 					# Temporary special case for ARMV5_ABIV1 and ARMV5_ABIV2
       
  3242 					if ($root =~ /^armv5_abiv[12]$/i)
       
  3243 					{
       
  3244 						push(@alternatives, "$b\\armv5\\$e");
       
  3245  					}
       
  3246 
       
  3247 					$root = Plat_Customizes($root);
       
  3248 				}
       
  3249  			}
       
  3250 			return @alternatives;
       
  3251  		}
       
  3252  	}
       
  3253 	return @alternatives;
       
  3254 }		
       
  3255    
       
  3256 #----------------------------------------------------------------------------------
       
  3257 # Bitmap and aif conversion phase
       
  3258 #
       
  3259 # Convert any "bitmap=" or "compressed-bitmap=" files into ROM format bitmaps
       
  3260 # Convert any "auto-bitmap=" to handle bitmap appropriately for xip and non-xip images
       
  3261 # Convert "aif=" files appropriately for xip and non-xip images
       
  3262 sub bitmap_aif_converison_phase
       
  3263 {
       
  3264 	my $is_xip=1;
       
  3265 	undef @newobydata;
       
  3266 	foreach $line (@obydata)
       
  3267 	{
       
  3268 		track_source($line);
       
  3269 		# keep track of the XIP-ness of this rom partition
       
  3270 		if ($line =~ /^\s*REM ROM_IMAGE\[(\d+)\]\s+(.*)$/i)
       
  3271 		{ $is_xip=$romimage[$1]{xip}; }
       
  3272 		#
       
  3273 		# aif=source dest 
       
  3274 		# include aif file - use XIP version for XIP roms if it exists, otherwise use the file specified
       
  3275 		#
       
  3276 		if ($line =~ /^\s*aif=/i)
       
  3277 		{
       
  3278 			my $xip="_xip";
       
  3279 			my @aif= split(/\s+/,$line);
       
  3280 			my $path=Path_Split('Path',"$aif[0]");
       
  3281 			my $base=Path_Split('Base',"$aif[0]");
       
  3282 			$path =~ s/^....//;
       
  3283 			my $ext=Path_Split('Ext',"$aif[0]");
       
  3284 			if ($is_xip && (-e "$path$base$xip$ext"))
       
  3285 			{ $line="data=$path$base$xip$ext\t\t$aif[1]\n"; }
       
  3286 			else
       
  3287 			{ $line="data=$path$base$ext\t\t$aif[1]\n"; }
       
  3288 		}
       
  3289 		#
       
  3290 		# auto-bitmap=
       
  3291 		#
       
  3292 		# if currently in XIP image, then use a compressed-bitmap
       
  3293 		# otherwise use a RAM format bitmap
       
  3294 		#
       
  3295 		if ($line =~ /^\s*auto-bitmap=/i)
       
  3296 		{
       
  3297 			if ($is_xip)
       
  3298 			{ $line =~ s/auto-bitmap=/compressed-bitmap=/i }
       
  3299 			else
       
  3300 			{ $line =~ s/auto-bitmap=/data=/i }
       
  3301 		}
       
  3302 		#
       
  3303 		# uncompressed-bitmap
       
  3304 		#
       
  3305 		# this is currently just a synonym for 'bitmap'
       
  3306 		$line =~ s/uncompressed-bitmap=/bitmap=/i;
       
  3307 	
       
  3308 		# 
       
  3309 		# bitmap=source dest 
       
  3310 		#
       
  3311 		if ($line =~ /^\s*bitmap=\s*"?(\S+)"?\s+"?(\S+)"?/i)
       
  3312 		{
       
  3313 			my $mbm = $1;
       
  3314 			my $dest = $2;
       
  3315 			my $rom_mbm = "$1_rom";
       
  3316 			if ($is_xip eq 0)
       
  3317 			{
       
  3318 				# non-XIP rom - just include the mbm file
       
  3319 				$line = "data=\"$mbm\"\t\"$dest\"\n";
       
  3320 			}
       
  3321 			else
       
  3322 			{	
       
  3323 		        if (! -e $rom_mbm || -M $rom_mbm >= -M $mbm)
       
  3324 			    {
       
  3325 				    system "bmconv /q /r $rom_mbm /m$mbm";
       
  3326 				    my $bmconv_status = $?;
       
  3327 				    die "* bmconv failed\n" if ($bmconv_status != 0 || !-f $rom_mbm);
       
  3328 			    }
       
  3329 				$line = "data=\"$rom_mbm\"\t\"$dest\"\n";
       
  3330 				push @tempfiles, $rom_mbm;
       
  3331 			}
       
  3332 		}
       
  3333 		#
       
  3334 		# compressed-bitmap=
       
  3335 		#
       
  3336 		# if file is a compressed ROM image file
       
  3337 		elsif ($line =~ /^\s*compressed-bitmap=\s*"?(\S+)"?\s+"?(\S+)"?/i)
       
  3338 		{
       
  3339 			my $mbm = $1;
       
  3340 			my $dest = $2;
       
  3341 			my $cmprssd_rom_mbm = "$1_rom";
       
  3342 			if ($is_xip eq 0)
       
  3343 			{
       
  3344 				# non-XIP rom - just include the mbm file
       
  3345 				$line = "data=\"$mbm\"\t\"$dest\"\n";
       
  3346 			}
       
  3347 			else
       
  3348 			{
       
  3349 				if (! -e $cmprssd_rom_mbm || -M $cmprssd_rom_mbm >= -M $mbm)
       
  3350 			    {
       
  3351 				    system "bmconv /q /s $cmprssd_rom_mbm /m$mbm";
       
  3352 				    my $bmconv_status = $?;
       
  3353 				    die "* bmconv failed\n" if ($bmconv_status != 0 || !-f $cmprssd_rom_mbm);
       
  3354 				}
       
  3355 				$line = "data=\"$cmprssd_rom_mbm\"\t\"$dest\"\n";
       
  3356 				push @tempfiles, $cmprssd_rom_mbm;			    
       
  3357 			}
       
  3358 		}
       
  3359 		push @newobydata, $line;
       
  3360 	}
       
  3361 	@obydata = @newobydata;
       
  3362 	dump_obydata("tmp8.oby", "result of bitmap conversion phase") if ($opt_v);
       
  3363 }
       
  3364 
       
  3365 
       
  3366 sub reformat_line($)
       
  3367 {
       
  3368 	my ($line) = @_;
       
  3369 	my $type = "";
       
  3370 	my $variant = "";
       
  3371 	my $pcfile = "";
       
  3372 	my $romfile = "";
       
  3373 	my $tail = "";
       
  3374 	
       
  3375 	# time=21/07/1999 12:00:00
       
  3376 	# primary[0x09080004]   =\epoc32\release\misa\udeb\ekern.exe
       
  3377 	# data=\epoc32\wins\C\System\Alarms\churchbell.snd    "System\Alarms\Church bell"
       
  3378 	# file[0x07060001]=\epoc32\release\MAWD\urel\cAkyb1.dll          System\Libs\EKeyb.dll
       
  3379 	# file=\epoc32\release\marm\urel\eikcore.dll 			System\Libs\Eikcore.dll
       
  3380 	# alias \System\Bin\DRTRVCT2_2.dll 			\System\Bin\DRTRVCT2_1.dll
       
  3381 	#
       
  3382 	if ($line =~ /^\s*TIME\s*=\s*/i)
       
  3383 	{
       
  3384 		return $line;
       
  3385 	}
       
  3386   	elsif($line =~ /^\s*volume\s*=.*/i)
       
  3387   	{
       
  3388   		return $line;		
       
  3389   	}
       
  3390 	elsif($line =~ /^\s*kerneltrace\s*=.*/i)
       
  3391 	{
       
  3392 		return $line;
       
  3393 	}
       
  3394 	if ($line =~ /^\s*(\S+)\s*=\s*(\S+)\s+"\\?(.*)"(.*)$/)
       
  3395 	{
       
  3396 		$type = $1;
       
  3397 		$variant = "";
       
  3398 		$pcfile = $2;
       
  3399 		$romfile = $3;
       
  3400 		$tail = $4;
       
  3401 	}
       
  3402 	elsif ($line =~ /^\s*(\S+)(\[\S+\])\s*=\s*(\S+)\s+\\?(\S+)(.*)$/)
       
  3403 	{
       
  3404 		$type = $1;
       
  3405 		$variant = $2;
       
  3406 		$pcfile = $3;
       
  3407 		$romfile = $4;
       
  3408 		$tail = $5;
       
  3409 	}
       
  3410 	elsif ($line =~ /(\S+)\s*=\s*"([^"]+)"\s+"\\?(.*)"(.*)$/)
       
  3411 	{
       
  3412 		if ($line !~ /^REM MISSING/i)
       
  3413 		{
       
  3414 			$type = $1;
       
  3415 			$variant = "";
       
  3416 			$pcfile = "\"$2\"";
       
  3417 			$romfile = $3;
       
  3418 			$tail = $4;
       
  3419 		}
       
  3420 		else{
       
  3421 			return $line;
       
  3422 		}
       
  3423 	}
       
  3424 	elsif ($line =~ /^\s*(\S+)\s*=\s*(\S+)\s+\\?(\S+)(.*)$/)
       
  3425 	{
       
  3426 		$type = $1;
       
  3427 		$variant = "";
       
  3428 		$pcfile = $2;
       
  3429 		$romfile = $3;
       
  3430 		$tail = $4;
       
  3431 	}
       
  3432 	elsif($line =~ /^\s*(patchdata)\s*(\S+)\s*\@\s*(\S+)\s+(\S+)/i)
       
  3433 	{
       
  3434 		# Reformat the patchdata statement
       
  3435 		my $romfilename = $2;
       
  3436 		my $patchdlldatamap_key = lc ($romfilename);
       
  3437 		my $symbolname = $3;
       
  3438 		my $value = $4;
       
  3439 		my ($index, $elementSize);		# For when the symbol is an array, and we're patching one element
       
  3440 		my $scalarSize;
       
  3441 		
       
  3442 		if(!defined $DllDataMap{$patchdlldatamap_key}->{dstpath}){
       
  3443 			print_source_error(" File $romfilename has not been included into ROM image");
       
  3444 			$errors++ if($strict);
       
  3445 			$line = "REM $line\n";
       
  3446 			return $line;
       
  3447 		}
       
  3448 	
       
  3449 		if ($enforceSysBin)
       
  3450 		{
       
  3451 			if ($DllDataMap{$patchdlldatamap_key}->{dstpath} !~ /^sys\\bin/i 
       
  3452 			 && $DllDataMap{$patchdlldatamap_key}->{dstpath} !~ /^sys\/bin/i)
       
  3453 			{
       
  3454 				$DllDataMap{$patchdlldatamap_key}->{dstpath} = "sys\\bin";
       
  3455 			}
       
  3456 		}
       
  3457 		
       
  3458 		my $dllfile = $DllDataMap{$patchdlldatamap_key}->{dstpath} . "\\". $romfilename;
       
  3459 		
       
  3460 		$line = "$1  ";
       
  3461 		$line .= "$dllfile ";
       
  3462  
       
  3463 		# Convert value into decimal (used to be done in AddDllDataInfo, but that limited us to
       
  3464 		# one value per symbol, and we now support patching arrays, e.g. the Hal's InitialValue[],
       
  3465 		# so we can't do it that way any more.)
       
  3466 		if ($value =~ /^0x([0-9a-f]+)$/i) {
       
  3467 			$value = hex($1);
       
  3468 		}
       
  3469 		elsif ($value =~ /^(-?\d+)$/) {
       
  3470 			$value = $1;
       
  3471 		}
       
  3472 		else {
       
  3473 			print_source_error("Attempt to set $symbolname to illegal value $value");
       
  3474 			$errors++ if($strict);
       
  3475 			$line = "REM $line\n";
       
  3476 			return $line;
       
  3477 		}
       
  3478 
       
  3479 		if ($symbolname =~ s/:(\d+)\[((0x)?[0-9a-f]+)\]$//i) {
       
  3480 			($index, $elementSize) = ($2, $1);
       
  3481 			$index = hex($index) if $index =~ /^0x/i;
       
  3482 		}
       
  3483 
       
  3484 		my $DllSymInfoRef = $DllDataMap{$patchdlldatamap_key}->{$symbolname};
       
  3485  
       
  3486 		if (!defined($DllSymInfoRef->{size})) {
       
  3487 			print_source_error("Size for symbol $symbolname not found");
       
  3488 			$errors++ if($strict);
       
  3489 			$line = "REM $line\n";
       
  3490 			return $line;
       
  3491 		}
       
  3492 
       
  3493 		if (defined($elementSize)) {
       
  3494 			$scalarSize = $elementSize / 8;
       
  3495 			if ($scalarSize != 1 && $scalarSize != 2 && $scalarSize != 4) {
       
  3496 				print_source_error("Invalid bit size $elementSize for array $symbolname in $romfilename");
       
  3497 				$errors++ if($strict);
       
  3498 				$line = "REM $line\n";
       
  3499 				return $line;
       
  3500 			}
       
  3501 			if (($index + 1) * $scalarSize > $DllSymInfoRef->{size}) {
       
  3502 				print_source_error("Invalid index $index into array $symbolname in $romfilename");
       
  3503 				$errors++ if($strict);
       
  3504 				$line = "REM $line\n";
       
  3505 				return $line;
       
  3506 			}
       
  3507 		} else {
       
  3508 			$scalarSize = $DllSymInfoRef->{size};
       
  3509 		}
       
  3510 
       
  3511 		my $max_value = 0xffffffff;
       
  3512 
       
  3513 		if ($scalarSize == 1) {
       
  3514 			$max_value = 0xff;
       
  3515 		}
       
  3516 		elsif ($scalarSize == 2) {
       
  3517 			$max_value = 0xffff;
       
  3518 		}
       
  3519 
       
  3520 		if ($value > $max_value) {
       
  3521 			$value &= $max_value;
       
  3522 			print "$DllSymInfoRef->{obyfilename}($DllSymInfoRef->{lineno}): Warning:Value overflow of $symbolname\n";
       
  3523 			$errors++ if($strict);
       
  3524 		}
       
  3525 
       
  3526 		if(defined $DllSymInfoRef->{ordinal}) {
       
  3527 			if (defined($elementSize)) {
       
  3528 				my $ord = $DllSymInfoRef->{ordinal};
       
  3529 				my $offset = $index * $scalarSize;
       
  3530 				$line .= "ordinal $ord+$offset ";
       
  3531 			} else {
       
  3532 				$line .= "ordinal ";
       
  3533 				$line .= $DllSymInfoRef->{ordinal} . " ";
       
  3534 			}
       
  3535 		}
       
  3536 		elsif(defined $DllSymInfoRef->{dataAddr}) {
       
  3537 			if (defined($elementSize)) {
       
  3538 				my $addr = $DllSymInfoRef->{dataAddr};
       
  3539 				$addr = hex($addr) if $addr =~ /^0x/i;
       
  3540 				$addr = sprintf("0x%08x", $addr + $index * $scalarSize);
       
  3541 				$line .= "addr $addr ";
       
  3542 			} else {
       
  3543 				$line .= "addr ";
       
  3544 				$line .= $DllSymInfoRef->{dataAddr} . " ";
       
  3545 			}
       
  3546 		}
       
  3547 		else
       
  3548 		{
       
  3549 			print_source_error("Ordinal or Address for exported symbol $symbolname in $romfilename couldn't be located");
       
  3550 			$errors++ if($strict);
       
  3551 			$line = "REM $line\n";
       
  3552 			return $line;
       
  3553 		};
       
  3554 		
       
  3555 		$line .= "$scalarSize $value\n";
       
  3556 
       
  3557 		return $line;
       
  3558 	}
       
  3559 	elsif ($line =~ /^\s*(\S+)\s*(\S+)\s+\\?(\S+)(.*)$/)
       
  3560 	{
       
  3561 		$type = $1;
       
  3562 		$variant = "";
       
  3563 		$pcfile = $2;
       
  3564 		$romfile = $3;
       
  3565 		$tail = $4;
       
  3566 
       
  3567 		if ($type !~ /^(alias)$/i)
       
  3568 		{
       
  3569 			# Return now, if it is not an 'alias'.
       
  3570 			return $line;
       
  3571 		}
       
  3572 		else
       
  3573 		{
       
  3574 			# There is no substitution needed for SysBin 'alias'es.
       
  3575 			if ($romfile =~ /^sys\\bin\\/i
       
  3576 			  ||$romfile =~ /^sys\/bin/i)
       
  3577 			{
       
  3578 				return $line;
       
  3579 			}
       
  3580 		}
       
  3581 	}
       
  3582 	else
       
  3583 	{
       
  3584 		return $line;
       
  3585 	}
       
  3586  	# Buildrom should generate warning when destination path provided for a file 
       
  3587  	# is not a standard path(as per platsec) and "PlatSecEnforceSysBin" is turned off. 
       
  3588  	my $warnFlag = 1;
       
  3589 	my $mustBeSysBin = $enforceSysBin;
       
  3590 	if ($type =~ /^(data|compress|nocompress)$/i
       
  3591 		&& $romfile !~ /^system\\(bin|libs|programs)\\/i)
       
  3592 	{
       
  3593 		$mustBeSysBin = 0;
       
  3594  		$warnFlag = 0;
       
  3595 	}
       
  3596 	
       
  3597 	if ($mustBeSysBin)
       
  3598 	{
       
  3599 		if ($type =~ /^(alias)$/i
       
  3600 			&& $romfile !~ /^sys\\bin\\/i
       
  3601 			&& $romfile !~ /^sys\/bin/i)
       
  3602 		{
       
  3603 			# for multilinguify 'alias'es (generally resource files) 'MustBeSysBin' should not be enforced.
       
  3604 			if(defined($multiLinguifyAlias{$pcfile})) {
       
  3605 				return $line;  
       
  3606 			}
       
  3607 
       
  3608 			my $filename = "\\$romfile";	# in case no path is specified
       
  3609 			$filename = substr $filename, rindex($filename, "\\");
       
  3610 			$romfile = "sys\\bin".$filename;
       
  3611 
       
  3612 			if ($pcfile !~ /^sys\\bin\\/i
       
  3613 			    && $pcfile !~ /^sys\/bin/i)
       
  3614 			{
       
  3615 				my $pcfilename = "\\$pcfile";	# in case no path is specified
       
  3616 				$pcfilename = substr $pcfilename, rindex($pcfilename, "\\");
       
  3617 				$pcfile = "sys\\bin".$pcfilename;
       
  3618 			}
       
  3619 			return "$type$variant $pcfile \t$romfile$tail\n";
       
  3620 		}
       
  3621 
       
  3622 		if ($romfile !~ /^sys\\bin\\/i
       
  3623 		    && $romfile !~ /^sys\/bin/i)
       
  3624 		{
       
  3625 			my $filename = "\\$romfile";	# in case no path is specified
       
  3626 			$filename = substr $filename, rindex($filename, "\\");
       
  3627 			$romfile = "sys\\bin".$filename;
       
  3628 		}
       
  3629 	}
       
  3630 	else
       
  3631 	{
       
  3632  		if ($warnFlag && $romfile !~ /^sys\\bin\\/i && $romfile !~ /^sys\/bin/i)
       
  3633  		{
       
  3634  			print "Warning: Outside standard path at \"$line\"\n";
       
  3635  		}
       
  3636 		if ($type =~ /^(alias)$/i)
       
  3637 		{
       
  3638 			# Return the line as it is for non-MustBeSysBin 'alias'es.
       
  3639 			return $line;
       
  3640 		}
       
  3641 	}
       
  3642 	$romfiles{$romfile} = $variant.$pcfile;
       
  3643 	return "$type$variant=$pcfile \t\"$romfile\"$tail\n";
       
  3644 }
       
  3645 
       
  3646 my @hidearray;
       
  3647 
       
  3648 sub mark
       
  3649 { # function to mark files in ROMs as hidden
       
  3650 	my ($base,$ext) = @_;
       
  3651 	my $i=0;
       
  3652 	my @coreimagerange = (-1,-1); #coreimagerange stores the places within @hidearray where the $base files start and end
       
  3653 	my @extensionimagerange = (-1,-1); #extensionimagerange stores the places within @hidearray where the $ext files start and end
       
  3654 	for(my $i=0;$i<scalar @hidearray;$i++) { #loop sets values in @coreimagerange and in @extensionimagerange
       
  3655 		if($hidearray[$i]{rom}==$base) {
       
  3656 			if($coreimagerange[0]<0) {
       
  3657 				$coreimagerange[0]=$i;
       
  3658 				$coreimagerange[1]=$i;
       
  3659 			} else {
       
  3660 				$coreimagerange[1]=$i;
       
  3661 			}
       
  3662 		} elsif($hidearray[$i]{rom}==$ext) {
       
  3663 			if($extensionimagerange[0]<0) {
       
  3664 				$extensionimagerange[0]=$i;
       
  3665 				$extensionimagerange[1]=$i;
       
  3666 			} else {
       
  3667 				$extensionimagerange[1]=$i;
       
  3668 			}
       
  3669 		}
       
  3670 	}
       
  3671 	
       
  3672 	for(my $i=$extensionimagerange[0];$i<=$extensionimagerange[1];$i++) { #loop marks files which need to be hidden based on the values in @coreimagerange and in @extensionimagerange
       
  3673 		for(my $j=$coreimagerange[0];$j<=$coreimagerange[1];$j++) {
       
  3674 			if($hidearray[$i]{dest} eq $hidearray[$j]{dest}) {
       
  3675 				$hidearray[$i]{hide}=1;
       
  3676 			}
       
  3677 		}
       
  3678 	}
       
  3679 }
       
  3680 
       
  3681 
       
  3682 #----------------------------------------------------------------------------------
       
  3683 # Cleaning phase
       
  3684 #
       
  3685 # Remove "REM defined", "REM handled"
       
  3686 # Remove the "# lineno" information
       
  3687 # Collapse multiple blank lines
       
  3688 # Apply the PlatSecEnforceSysBin setting
       
  3689 # Produce ROM directory listing
       
  3690 # Identify the ROM image name
       
  3691 sub cleaning_phase
       
  3692 {	
       
  3693 	my $romname;
       
  3694 	my $skippingBlanks=0;
       
  3695 	undef @newobydata;
       
  3696 	
       
  3697     if($opt_v)
       
  3698     {
       
  3699 	  my $logWin = "logwin.oby";
       
  3700 	  my $logLinux = "loglinux.oby";
       
  3701 	  unlink($logWin);
       
  3702 	  unlink($logLinux);
       
  3703 	  open LOGWIN, ">$logWin" or die("* Can't create $logWin\n");
       
  3704 	  open LOGLINUX, ">$logLinux" or die("* Can't create $logLinux\n");
       
  3705     }	
       
  3706 
       
  3707 	foreach $line (@obydata)
       
  3708 	{
       
  3709 		track_source($line);
       
  3710 		if ($line=~/^REM (defined|handled)/)
       
  3711 		{
       
  3712 			next;
       
  3713 		}
       
  3714 		if ($line=~/^# (\d+) "(.*)"/)
       
  3715 		{
       
  3716 			next;
       
  3717 		}
       
  3718 		#
       
  3719 		# Blank line compression
       
  3720 		#
       
  3721 		if ($line=~/^\s*$/)
       
  3722 		{
       
  3723 			if ($skippingBlanks==1)
       
  3724 			{
       
  3725 				next;
       
  3726 			}
       
  3727 			$skippingBlanks=1;
       
  3728 		}
       
  3729 		else
       
  3730 		{
       
  3731 			$skippingBlanks=0;
       
  3732 		}
       
  3733 		#
       
  3734 		# Track ROMNAME, allowing overrides
       
  3735 		#
       
  3736 		if ($line=~/romname\s*=\s*"?(\S+)\.(\S+)"?\s*/i)
       
  3737 		{
       
  3738 			if ($romname ne "" && $opt_o eq "")
       
  3739 			{
       
  3740 				print_source_error("Overrides previous ROM name $romname");
       
  3741 			}
       
  3742 			$rombasename = $1;
       
  3743 			$romname = "$1.$2";
       
  3744 			next;
       
  3745 		}
       
  3746 		#
       
  3747 		# ROM directory listing
       
  3748 		#
       
  3749 		    my $newline = reformat_line($line);
       
  3750 	    if( ($newline !~ /^\s*TIME\s*=\s*/i)
       
  3751   	      &&($newline !~ /^\s*volume\s*=.*/i)
       
  3752 	      &&($newline !~ /^\s*kerneltrace\s*=.*/i))
       
  3753 	    {
       
  3754 	        my $tmpline = $newline;
       
  3755 	        if($^O =~ /^MSWin32$/i)
       
  3756 	        {
       
  3757 	          $newline =~ s-\/-\\-go;
       
  3758 	          if($opt_v)
       
  3759 	          {
       
  3760                 print LOGWIN $newline;
       
  3761 	            $tmpline =~ s-\\-\/-go;
       
  3762 	            print LOGLINUX $tmpline;
       
  3763 	          }
       
  3764 	        }else #unix os
       
  3765 	        {
       
  3766 	          $newline =~ s-\\-\/-go;
       
  3767 	          if($opt_v)
       
  3768 	          {
       
  3769 	            print LOGLINUX $newline;
       
  3770 	            $tmpline =~ s-\/-\\-go;
       
  3771 	            print LOGWIN $tmpline;
       
  3772 	          }
       
  3773 	        }
       
  3774 	    }
       
  3775 	    
       
  3776 		push @newobydata, $newline;
       
  3777 	}
       
  3778 	if($opt_v)
       
  3779 	{
       
  3780 	  close LOGWIN;
       
  3781 	  close LOGLINUX;
       
  3782 	}
       
  3783 	
       
  3784 	exit(1) if($errors && $strict);
       
  3785 
       
  3786 	# Handle ROMNAME and possible -o override
       
  3787 	if ($opt_o ne "")
       
  3788 	{
       
  3789 		$romname=$opt_o;
       
  3790 		if ($opt_o=~/(\S+)\.(\S+)/)
       
  3791 		{
       
  3792 			$rombasename=$1;
       
  3793 		}
       
  3794 		else
       
  3795 		{
       
  3796 			$rombasename=$romname;
       
  3797 		}
       
  3798 	}
       
  3799 	if(!$onlysmrimage)
       
  3800 	{
       
  3801 		unshift @newobydata, "romname=$romname\n";	# first line of final OBY file
       
  3802 	}
       
  3803 	@obydata = @newobydata;
       
  3804 	
       
  3805 	print "* Removing previous image and logs...\n";
       
  3806 	unlink glob("$rombasename.*");
       
  3807 	
       
  3808 	my $obyrecordline;
       
  3809 	if($createspi) {# section added to mark SPI files in core images as hidden (if appropriate) if extension ROMs are being produced
       
  3810 		my $imagenum=0;
       
  3811 		my $count=0;
       
  3812 		foreach my $line (@obydata) { # fill @hidearray with all file= or data= entries from @obydata, recording which image they are in and their target destination
       
  3813 			if($line =~/^\s*(file|data)\s*=\s*(\S+)\s+(\S+)\s*$/gi) {
       
  3814 				$hidearray[$count] = {rom=>$imagenum, type=>$1, dest=>$3};
       
  3815 				$hidearray[$count]{dest} =~s/\"//g;
       
  3816 				$count++;
       
  3817 			} elsif($line =~/^\s*REM\s+ROM_IMAGE\[(\d)\]\s*$/i ) {
       
  3818 				$imagenum=$1;
       
  3819 			}
       
  3820 		}
       
  3821 		for(my $i=0;$i<8;$i++) { #loop to mark files in @hidearray as hidden, does not add the hide= lines to the obey files
       
  3822 			if($romimage[$i]{extension}) {
       
  3823 				mark($i-1,$i);
       
  3824 			}
       
  3825 		}
       
  3826 		undef @newobydata;
       
  3827 	
       
  3828 		my $hideflag=0; # is set to 1 if there are files which need to be hidden, determines whether to run next section of code 
       
  3829 		for(my $i=0;$i<scalar @hidearray;$i++) {
       
  3830 			if($hidearray[$i]{hide}==1) {
       
  3831 				$hideflag=1;
       
  3832 			}
       
  3833 		}
       
  3834 	
       
  3835 		my $obeyrom=0;	
       
  3836 		if($hideflag) { #if there exist files which need hiding
       
  3837 			my $i=0;
       
  3838 			my $exitflag=0;
       
  3839 			$obyrecordline=0;
       
  3840 			for(;$obyrecordline<scalar @obydata && !$exitflag;) { # nested for loops produce new obey file in @newobydata, including hide= lines
       
  3841 				print "Line = $obyrecordline $i " . scalar @hidearray . "\n";
       
  3842 				if($i==scalar @hidearray) {
       
  3843 					$exitflag=1;
       
  3844 				}
       
  3845 				for(;$i<scalar @hidearray;$i++) {
       
  3846 					if($hidearray[$i]{hide}==1) {
       
  3847 						my $rom=$hidearray[$i]{rom};
       
  3848 						my $destination=$hidearray[$i]{dest};
       
  3849 						while($obeyrom<$rom && $obyrecordline<scalar @obydata) { #pushes lines to @newobydata until specified rom is reached
       
  3850 							push @newobydata, $obydata[$obyrecordline];
       
  3851 							if($obydata[$obyrecordline] =~/^\s*REM\s+ROM_IMAGE\[(\d)\]\s*$/i){
       
  3852 								$obeyrom=$1;
       
  3853 							}
       
  3854 							$obyrecordline++;
       
  3855 						}
       
  3856 						my $flag=1; #get to here when $obeyrom==$rom
       
  3857 						while($flag && $obyrecordline<scalar @obydata) {
       
  3858 							$destination=~s|\\|/|g;
       
  3859 							my $obyline=$obydata[$obyrecordline];
       
  3860 							$obyline=~s|\\|/|g;			
       
  3861 							if($obyline=~m/$destination/) { # if the line in the obeyfile matches the destination of the specified spi file then a hide= line is added before the spi file's data= line
       
  3862 								push @newobydata, "hide=$hidearray[$i]{dest}\n$obydata[$obyrecordline]";
       
  3863 								$obyrecordline++;
       
  3864 								$flag=0;
       
  3865 							} else {
       
  3866 								push @newobydata, $obydata[$obyrecordline++];
       
  3867 							}
       
  3868 						}
       
  3869 					}
       
  3870 				}
       
  3871 			}		
       
  3872 		}		
       
  3873 		while($obyrecordline< scalar @obydata) { # add the rest of the lines from @obydata to @newobydata
       
  3874 			push @newobydata, $obydata[$obyrecordline++];
       
  3875 		}
       
  3876 		@obydata=@newobydata;
       
  3877 		undef @newobydata;	
       
  3878 	}
       
  3879 	dump_obydata("tmp9.oby", "result of cleaning phase") if ($opt_v);
       
  3880 }
       
  3881 
       
  3882 
       
  3883 #----------------------------------------------------------------------------------
       
  3884 #
       
  3885 # Divide the oby file into multiple sections - one for each rom image - ready
       
  3886 # for the appropriate rom builder.
       
  3887 #
       
  3888 
       
  3889 sub generate_romheader
       
  3890 {
       
  3891 	my ($idx) = @_;
       
  3892 	if ($romimage[$idx]{xip} ne 0)
       
  3893 	{ 
       
  3894 		my $header = "\n";
       
  3895 		if ($romimage[$idx]{extension})
       
  3896 		{
       
  3897 			$header = "extensionrom=$rombasename.$romimage[$idx]{name}.img\n";
       
  3898 			$header .= "romsize=$romimage[$idx]{size}\n\n";
       
  3899 		}
       
  3900 		return $header; 
       
  3901 	}
       
  3902 	# non-xip
       
  3903 	my $header;
       
  3904 	if ($romimage[$idx]{extension})
       
  3905 	{
       
  3906 		$header =  "extensionrofs=$rombasename.$romimage[$idx]{name}.img\n";
       
  3907 		$header .= "rofssize=$romimage[$idx]{size}\n\n";
       
  3908 	}
       
  3909 	else
       
  3910 	{
       
  3911 		$header="rofsname=$rombasename.$romimage[$idx]{name}.img\n";
       
  3912 		$header .= "rofssize=$romimage[$idx]{size}\n\n";
       
  3913 	}
       
  3914 	return $header;
       
  3915 }
       
  3916 
       
  3917 #----------------------------------------------------------------------------------
       
  3918 # Dump OBY file.
       
  3919 #
       
  3920 # Creates final OBY file.
       
  3921 #
       
  3922 sub create_dumpfile
       
  3923 {
       
  3924 	my $romimageidx;
       
  3925 	my $smrimageidx = 0;
       
  3926 	my $dumpfile="$rombasename";
       
  3927 	$romimage[0]{obeyfile}=$dumpfile;
       
  3928 	$dumpfile .= ".oby";
       
  3929 	unlink($dumpfile);
       
  3930 	if($rombasename && !$onlysmrimage)
       
  3931 	{
       
  3932 		open DUMPFILE, ">$dumpfile" or die("* Can't create $dumpfile\n");
       
  3933 		print "* Writing $dumpfile - final OBY file\n";
       
  3934 		$romimageidx=0;
       
  3935 		print DUMPFILE generate_romheader($romimageidx);
       
  3936 	}
       
  3937 	foreach $line (@obydata)
       
  3938 	{
       
  3939 		if ($line =~ /^\s*REM ROM_IMAGE\[(\d+)\]\s+(.*)$/i)
       
  3940 		{
       
  3941 			$romimageidx=$1;
       
  3942 			if ($romimage[$romimageidx]{extension} eq '0')
       
  3943 			{ # next rom oby file
       
  3944 				close DUMPFILE;
       
  3945 				$dumpfile="$rombasename.$romimage[$romimageidx]{name}";
       
  3946 				$romimage[$romimageidx]{obeyfile}=$dumpfile;
       
  3947 				$dumpfile .= ".oby";
       
  3948 				open DUMPFILE, ">$dumpfile" or die("* Can't create $dumpfile\n");		
       
  3949 				print "* Writing $dumpfile - final OBY file\n";
       
  3950 				# header
       
  3951 				print DUMPFILE $line;
       
  3952 				print DUMPFILE generate_romheader($romimageidx);
       
  3953 				next;
       
  3954 			}
       
  3955 			else
       
  3956 			{ # extension
       
  3957 				# header
       
  3958 				print DUMPFILE $line;
       
  3959 				print DUMPFILE generate_romheader($romimageidx);
       
  3960 				next;
       
  3961 			}
       
  3962 		}
       
  3963 		# write data drive oby file.
       
  3964 		elsif ($line =~ /^\s*REM DATA_IMAGE\[(\d+)\]\s+(.*)$/i)
       
  3965 		{
       
  3966 				my $dataimageidx=$1;
       
  3967 				close DUMPFILE;
       
  3968 				$dumpfile="$datadriveimage[$dataimageidx]{name}";
       
  3969 				$datadriveimage[$dataimageidx]{obeyfile}=$dumpfile;
       
  3970 				$dumpfile .= ".oby";
       
  3971 				open DUMPFILE, ">$dumpfile" or die("* Can't create $dumpfile\n");		
       
  3972 				print "* Writing $dumpfile - intermediate OBY file\n";
       
  3973 				# header
       
  3974 				print DUMPFILE $line;
       
  3975 				print DUMPFILE generate_datadriveheader($dataimageidx,\@datadriveimage);
       
  3976 				push(@dataDriveFileList,$dumpfile);
       
  3977 				next;
       
  3978 		}
       
  3979 		elsif ($line =~ /^\s*REM SMR_IMAGE\s*$/i)
       
  3980 		{
       
  3981 			close DUMPFILE;
       
  3982 			$dumpfile = $obeyFileList[$smrimageidx];
       
  3983 			$smrimageidx++;
       
  3984 			$dumpfile .= ".oby";
       
  3985 			open DUMPFILE, ">$dumpfile" or die("* Can't create $dumpfile\n");
       
  3986 			print "*Writing $dumpfile - intermediate OBY file\n";
       
  3987 			print DUMPFILE $line;
       
  3988 			push(@smrImageFileList, $dumpfile);
       
  3989 			next;
       
  3990 		}
       
  3991 		print DUMPFILE $line;
       
  3992 	}
       
  3993 	close DUMPFILE;
       
  3994 }
       
  3995 
       
  3996 #----------------------------------------------------------------------------------
       
  3997 #
       
  3998 # Full ROM directory listing - use case-insensitive sort
       
  3999 #
       
  4000 sub create_dirlisting
       
  4001 {
       
  4002 	if($rombasename)
       
  4003 	{
       
  4004 		print "* Writing $rombasename.dir - ROM directory listing\n";
       
  4005 		open DIRFILE, ">$rombasename.dir" or die("* Can't create ROM directory listing\n");
       
  4006 	
       
  4007 		my $file;
       
  4008 		my $prevdir = "";
       
  4009 		foreach $file (sort {uc($a) cmp uc($b)} keys %romfiles)
       
  4010 		{
       
  4011 			my $dir = substr $file,0,rindex($file, "\\");
       
  4012 			if (uc $dir ne uc $prevdir)
       
  4013 			{
       
  4014 				$prevdir = $dir;
       
  4015 				print DIRFILE "\n";
       
  4016 			}
       
  4017 	
       
  4018 			my @sources = split /\n/,$romfiles{$file};
       
  4019 			printf DIRFILE "%-40s\t%s\n", $file, shift @sources;
       
  4020 			while (@sources)
       
  4021 			{
       
  4022 				printf DIRFILE "%39s+\t%s\n", "", shift @sources;
       
  4023 			}
       
  4024 		}
       
  4025 		close DIRFILE;
       
  4026 	}
       
  4027 }
       
  4028 
       
  4029 #----------------------------------------------------------------------------------
       
  4030 #
       
  4031 # Suppress Rom/Rofs/DataDrive Image creation if "-noimage" option is provided.
       
  4032 #
       
  4033 
       
  4034 sub suppress_image_generation
       
  4035 {
       
  4036 	if($noimage) 
       
  4037 	{
       
  4038 		&tidy_exit;		
       
  4039 	}
       
  4040 }
       
  4041 
       
  4042 #----------------------------------------------------------------------------------
       
  4043 # Execute rombuild & maksym for each final XIP OBY file
       
  4044 # Execute rofsbuild for each non-XIP oby file
       
  4045 #
       
  4046 
       
  4047 sub run_rombuilder
       
  4048 {
       
  4049 	my ($command, $obeyfile, $logfile) = @_;
       
  4050 	$command .= " $obeyfile.oby";
       
  4051 	#CR1258 test cases are depending on the following output.
       
  4052 	print "* Executing $command\n" if ($opt_v);
       
  4053 
       
  4054 	open DATA, "$command 2>&1 |"   or die "Couldn't execute command: $command";
       
  4055 	while ( defined( my $line = <DATA> ) ) {
       
  4056 	chomp($line);
       
  4057 	print "$line\n";
       
  4058 	}
       
  4059 	close DATA;
       
  4060 
       
  4061 	if ($? != 0)
       
  4062 	{
       
  4063 		$errors++;
       
  4064 		$command =~ /^\s*(\S+)\s+-slog/;
       
  4065 		print "* $1 failed\n";
       
  4066 	}
       
  4067 	else
       
  4068 	{
       
  4069 		push(@romImages,$obeyfile.".img");
       
  4070 	}
       
  4071 	print "\n";
       
  4072 	rename "$logfile","$obeyfile.log" or die("* Can't rename $logfile\n");
       
  4073 	exit(1) if ($errors);
       
  4074 }
       
  4075 
       
  4076 #----------------------------------------------------------------------------------
       
  4077 # ROMBUILD AND ROFSBUILD
       
  4078 #
       
  4079 # Invokes rombuild and rofsbuild.
       
  4080 # Creates .log, .symbol files.
       
  4081 #
       
  4082 sub invoke_rombuild
       
  4083 {
       
  4084 	#For CR1258, -compress command line option is introduced, and it's being handled as following
       
  4085 	my $rom_compression_type;
       
  4086 	if($opt_compression_type eq ALLSECTIONS)
       
  4087 	{
       
  4088 		$rom_compression_type = "-compress";
       
  4089 	}
       
  4090 	elsif($opt_compression_type eq PAGEDSECTION)
       
  4091 	{
       
  4092 		$rom_compression_type = "-compress=paged";
       
  4093 	}
       
  4094 	elsif($opt_compression_type eq UNPAGEDSECTION)
       
  4095 	{
       
  4096 		$rom_compression_type = "-compress=unpaged";
       
  4097 	}
       
  4098 	else
       
  4099 	{
       
  4100 		$rom_compression_type = "";
       
  4101 	}
       
  4102 	
       
  4103 	my $rombuild;
       
  4104 	if(!$geninc)
       
  4105 	{
       
  4106 		$rombuild = "rombuild -slog $rom_compression_type $logLevel $lowMem $opt_fastcompress $opt_jobs";
       
  4107 	}
       
  4108 	else
       
  4109 	{
       
  4110 		$rombuild = "rombuild -slog $rom_compression_type -geninc $logLevel $lowMem $opt_fastcompress $opt_jobs";
       
  4111 	}
       
  4112 	if($gendep)
       
  4113 	{
       
  4114 		$rombuild .= " -gendep";
       
  4115 	}
       
  4116 	my $rofsbuild = "rofsbuild -slog $logLevel $lowMem $opt_fastcompress $opt_jobs";
       
  4117 	foreach my $arg (keys %rombuildOptions)
       
  4118 	{
       
  4119 		$rombuild .= " $arg";
       
  4120 	}
       
  4121 	        
       
  4122 	for (my $romidx=0; $romidx<8; $romidx++)
       
  4123 	{
       
  4124 		my $obeyfile=$romimage[$romidx]{obeyfile};
       
  4125 		my $xip=$romimage[$romidx]{xip};
       
  4126 		my $compress=$romimage[$romidx]{compress};
       
  4127 		my $uncompress=$romimage[$romidx]{uncompress};
       
  4128 		if ($obeyfile)
       
  4129 		{
       
  4130 			if(!defined $opt_compression)
       
  4131 			{
       
  4132 				if ($compress ne 0)
       
  4133 				{
       
  4134 					$compress=" -compress";
       
  4135 				}
       
  4136 				elsif($uncompress ne 0)
       
  4137 				{
       
  4138 					$compress=" -uncompress";
       
  4139 				}
       
  4140  				elsif($compress eq 0)
       
  4141  				{
       
  4142  					$compress=" ";
       
  4143 				}
       
  4144 			}
       
  4145 			else
       
  4146 			{
       
  4147 				$compress = $opt_compression;
       
  4148 				$compress =~m/\s-(compression)(method)\s(none|inflate|bytepair)/;
       
  4149 				print "* ".$1." ".$2.": ".$3;
       
  4150 			}                        
       
  4151 			if ($xip)
       
  4152 			{
       
  4153 				run_rombuilder($rombuild.$compress, $obeyfile, "ROMBUILD.LOG");
       
  4154 				if(!$nosymbols){
       
  4155 				print "* Writing $obeyfile.symbol - ROM symbol file\n";
       
  4156 				print "* Executing maksym $obeyfile.log $obeyfile.symbol\n" if ($opt_v);
       
  4157 				system("maksym $obeyfile.log $obeyfile.symbol >maksym.out");
       
  4158 				exit(1) if (!-e "$obeyfile.symbol");
       
  4159 				}
       
  4160 			}
       
  4161 			else
       
  4162 			{
       
  4163 				# efficient_rom_paging.pm can move everything to core rom.
       
  4164 				# If that is the case, don't run rofsbuild at all to avoid errors.
       
  4165 				use constant TRUE => 1;
       
  4166 				use constant FALSE => 0;
       
  4167 				my $run_rofs_build = FALSE;
       
  4168 				
       
  4169 				open OBYFILE, "$obeyfile.oby";
       
  4170 				for (<OBYFILE>)
       
  4171 				{
       
  4172 					if (is_oby_statement($_))
       
  4173 					{
       
  4174 						$run_rofs_build = TRUE;
       
  4175 						last;
       
  4176 					}
       
  4177 				}
       
  4178 				close OBYFILE;
       
  4179 				if ($run_rofs_build)
       
  4180 				{
       
  4181 					run_rombuilder($rofsbuild.$compress, $obeyfile, "ROFSBUILD.LOG");
       
  4182 					if(!$nosymbols){
       
  4183 					print "* Writing $obeyfile.symbol - ROFS symbol file\n";
       
  4184 					print "* Executing maksymrofs $obeyfile.log $obeyfile.symbol\n" if ($opt_v);
       
  4185 					system("maksymrofs $obeyfile.log $obeyfile.symbol >maksym.out");
       
  4186 					exit(1) if (!-e "$obeyfile.symbol" );
       
  4187 					}			
       
  4188 				}
       
  4189 			}
       
  4190 			unlink "rombuild.log";
       
  4191 			unlink "maksym.out";
       
  4192 		}
       
  4193 	}
       
  4194 }
       
  4195 
       
  4196 #-------------------------------------------------------
       
  4197 # Subroutine: check if current statement is a valid oby statement
       
  4198 #
       
  4199 sub is_oby_statement
       
  4200 {
       
  4201 	my ($li) = @_;
       
  4202 	if ($li =~ /\s*data\s*=/) { return 1;}
       
  4203 	if ($li =~ /\s*file\s*=/) { return 1;}
       
  4204 	if ($li =~ /\s*dll\s*=/) { return 1;}
       
  4205 	if ($li =~ /\s*secondary\s*=/) { return 1;}
       
  4206 
       
  4207 	return 0;
       
  4208 }
       
  4209 
       
  4210 #-------------------------------------------------------
       
  4211 # Subroutine: convert possibly absolute path into relative path
       
  4212 #
       
  4213 
       
  4214 sub relative_path
       
  4215 {
       
  4216     my ($arg) = @_;
       
  4217     return $arg if ($arg !~ /^\\/);	# not an absolute path
       
  4218     if ($uppath eq "x")
       
  4219 	{
       
  4220 		$uppath=cwd;
       
  4221 		$uppath=~s-/-\\-go;		    # separator from Perl 5.005_02+ is forward slash
       
  4222 		$uppath=~s-^(.*[^\\])$-$1\\-o;	    # ensure path ends with a backslash
       
  4223 		$uppath=~s-\\([^\\]+)-\\..-og;	    # convert directories into ..
       
  4224 		$uppath=~s-^.:\\--o;		    # remove drive letter and leading backslash
       
  4225 	}
       
  4226     $arg=~s-^\\--o;	# remove leading backslash from original path
       
  4227     return "$uppath$arg";
       
  4228 }
       
  4229 
       
  4230 # Returns the global @obydata reference to support external tool invocation.
       
  4231 sub getOBYDataRef{
       
  4232 	return \@obydata;
       
  4233 }
       
  4234 
       
  4235 #Match the blank or the comment
       
  4236 sub isobystatement
       
  4237 {
       
  4238 	my ($l) = @_;
       
  4239 	if ($l !~ /=/) { 
       
  4240 		return 0;
       
  4241 	}
       
  4242 	return 1;
       
  4243 }
       
  4244 
       
  4245 #Match the data statements
       
  4246 sub isdatastatement {
       
  4247 	my ($l) = @_;
       
  4248 	if ($l !~ /data=/) 
       
  4249 	{ 
       
  4250 		return 0;
       
  4251 	}
       
  4252 	return 1;
       
  4253 }
       
  4254 
       
  4255 #Match the spidata statements
       
  4256 sub isspidatastatement {
       
  4257 	my ($l) = @_;
       
  4258 	if ($l !~ /spidata=/) { 
       
  4259 		return 0;
       
  4260 	}
       
  4261 	return 1;
       
  4262 }
       
  4263 
       
  4264 #Match the executable statements
       
  4265 sub isexecutablefile {
       
  4266 	my ($l) = @_;
       
  4267 	if (($l=~/file=/)||($l=~/dll=/)||($l=~/primary=/)||($l=~/secondary=/)||($l=~/variant=/)||($l=~/device=/)||($l=~/extension=/)){ 
       
  4268 		return 1;
       
  4269 	}
       
  4270 	return 0;
       
  4271 }
       
  4272 
       
  4273 #Match the directory metadata statements
       
  4274 sub isdirectorymetadata {
       
  4275 	my ($l) = @_;
       
  4276 	if (($l=~/hide=/) || ($l=~/rename=/) || ($l=~/alias=/)){ 
       
  4277 		return 1;
       
  4278 	}
       
  4279 	return 0;
       
  4280 }
       
  4281 
       
  4282 #Match the bitmap statements
       
  4283 sub isbitmap {
       
  4284 	my ($l) = @_;
       
  4285 	if ($l=~/bitmap=/){ 
       
  4286 		return 1;
       
  4287 	}
       
  4288 	return 0;
       
  4289 }
       
  4290 
       
  4291 
       
  4292 #Match the aif file
       
  4293 sub isaif {
       
  4294 	my ($l) = @_;
       
  4295 	if ($l=~/(.*)\.aif/){ 
       
  4296 		return 1;
       
  4297 	}
       
  4298 	return 0;
       
  4299 }
       
  4300 
       
  4301 
       
  4302 #Match the resource file
       
  4303 sub isresource {
       
  4304 	my ($l) = @_;
       
  4305 	if ($l=~/(.*)\.rsc/){ 
       
  4306 		return 1;
       
  4307 	}
       
  4308 	return 0;
       
  4309 }
       
  4310 
       
  4311 #Returns the executable extensions
       
  4312 sub executableextension {
       
  4313 	my ($l) = @_;
       
  4314 	if ($l=~/file=(.*)\.exe$/){ 
       
  4315 		return "exe";
       
  4316 	}
       
  4317 	elsif ($l=~/file=(.*)\.dll$/){ 
       
  4318 		return "dll";
       
  4319 	}
       
  4320 	elsif ($l=~/file=(.*)\.ldd$/){ 
       
  4321 		return "ldd";
       
  4322 	}
       
  4323 	elsif ($l=~/file=(.*)\.fsy$/){ 
       
  4324 		return "fsy";
       
  4325 	}
       
  4326 }
       
  4327 
       
  4328 
       
  4329 #Returns all 3 UIDS
       
  4330 sub executabletype {
       
  4331 	my ($l) = @_;
       
  4332 	my $uid1;
       
  4333 	my $uid2;
       
  4334 	my $uid3;
       
  4335 	if ($l=~/uid1\s(0x[\d]*)/){ 
       
  4336 		$uid1=$1;
       
  4337 	}
       
  4338 	if ($l=~/uid2\s(0x[\d]*)/){ 
       
  4339 		$uid2=$1;
       
  4340 	}
       
  4341 	if ($l=~/uid3\s(0x[\d]*)/){ 
       
  4342 		$uid3=$1;
       
  4343 	}
       
  4344 	
       
  4345 	return $uid1." ".$uid2." ".$uid3."\n";
       
  4346 }
       
  4347 
       
  4348 
       
  4349 #Return source file name
       
  4350 sub getSourceFile {
       
  4351 	my ($line) = shift;
       
  4352 	if ($line=~/(\w*=)(\S*\s+\S*)\s+(\S*)\s+(\S*)?/) {
       
  4353 		return $2;
       
  4354 	}
       
  4355 }
       
  4356 
       
  4357 #Return destination file name
       
  4358 sub getDestFile{
       
  4359 	my ($line) = shift;
       
  4360 	if ($line=~/(\w*=)(\S*\s+\S*)\s+(\S*)\s+(\S*)?/) {
       
  4361 		return $3;
       
  4362 	}
       
  4363 }
       
  4364 
       
  4365 #Return the obycommand attributes
       
  4366 sub getOBYAttributes{
       
  4367 	my ($line) = shift;
       
  4368 	if ($line=~/(\w*=)(\S*\s+\S*)\s+(\S*)\s+(\S*)?/) {
       
  4369 		return $4;
       
  4370 	}
       
  4371 }
       
  4372 
       
  4373 #Return the hardware variant delimiter
       
  4374 sub getHardwareVariant{
       
  4375 	my ($line) = shift;
       
  4376 	if ($line=~/(\w*[0x[\d]*]=)/) {
       
  4377 		return $1;
       
  4378 	}
       
  4379 }
       
  4380 
       
  4381 #Return the hardware variant delimiter
       
  4382 sub getObyCommand{
       
  4383 	my ($line) = shift;
       
  4384 	if ($line=~/^[data=]/) {
       
  4385 		return "data";
       
  4386 	}
       
  4387 
       
  4388 	if ($line=~/^[file=]/) {
       
  4389 		return "file";
       
  4390 	}
       
  4391 
       
  4392 	if ($line=~/^[dll=]/) {
       
  4393 		return "dll";
       
  4394 	}
       
  4395 }
       
  4396 
       
  4397 # Initialize the symbol info within the given DLL.
       
  4398 sub AddDllDataInfo
       
  4399 {
       
  4400 	my ($line) = @_;
       
  4401 	# syntax "<DLLname>@<symbolname> <newvalue>"
       
  4402 	if($line =~ /^\s*(\S+)\s*\@\s*(\S+)\s+(\S+)\s*$/)
       
  4403 	{
       
  4404 		my $dllName = lc ($1);
       
  4405 		my $symbolname = $2;
       
  4406 		my $intVal = $3;
       
  4407 		my $newVal = 0;
       
  4408 		if($intVal =~ /^0x([0-9a-fA-F]+)$/){
       
  4409 		$newVal = hex($1);
       
  4410 		}
       
  4411 		elsif($intVal =~ /^(-\d+)$/ or $intVal =~ /^(\d+)$/){		
       
  4412 			$newVal = $1;
       
  4413 		}
       
  4414 		else{
       
  4415  			print "ERROR: Invalid patchable value at \"$line\"\n";
       
  4416  			$errors++ if($strict);
       
  4417  			return 1;
       
  4418 		}
       
  4419 		$symbolname =~ s/:(\d+)\[(0x)?[0-9a-f]+\]$//i;	# Remove array element specification (:ELEMENT_BIT_SIZE[INDEX]) to get symbol name
       
  4420 
       
  4421 		my $DllMapRef = \%{$DllDataMap{$dllName}};
       
  4422 
       
  4423 		my %DllSymInfo = ();
       
  4424 		$DllSymInfo{ordinal}	= undef;
       
  4425 		$DllSymInfo{dataAddr}	= undef;
       
  4426 		$DllSymInfo{size}		= undef;
       
  4427 		# We don't store the value here, since patchdata can be used on an array,
       
  4428 		# in which case we'll create another one of these, and lose the value.
       
  4429 		# Instead, the value is retrieved by re-parsing the command line later.
       
  4430 		$DllSymInfo{lineno}		= $sourceline;
       
  4431 		$DllSymInfo{obyfilename}= $sourcefile;
       
  4432 
       
  4433 		$DllMapRef->{$symbolname} = \%DllSymInfo;
       
  4434 		return 0;
       
  4435 	}
       
  4436 		return 1;
       
  4437 }
       
  4438 
       
  4439 sub process_dlldata
       
  4440 {
       
  4441 	if(!$patchDataStmtFlag){
       
  4442 		return;
       
  4443 	}
       
  4444 	my $symbolTblEntry;
       
  4445 
       
  4446 	foreach my $dll (keys %DllDataMap){
       
  4447 		my $DllMapRef = $DllDataMap{$dll};
       
  4448 		if(!$DllMapRef->{srcfile}){
       
  4449 		next;
       
  4450 		}
       
  4451 		my $aDllFile = $DllMapRef->{srcfile};
       
  4452 		my $SymbolCount = scalar ( keys %{$DllMapRef}) - 2; #The map has 'srcfile' and 'dstpath' special keys besides the symbols.
       
  4453 
       
  4454 		my $DllSymMapRef;
       
  4455 
       
  4456 		my @BPABIPlats = &BPABIutl_Plat_List;
       
  4457 		my $matchedSymbols = 0;
       
  4458 		my $globalSyms = 0;
       
  4459 		my @platlist = &Plat_List();
       
  4460 		my $platName;
       
  4461 		my $rootPlatName;
       
  4462 		my $plat = "ARMV5";				
       
  4463 		$plat = &Variant_GetMacro() ? $plat."_ABIV1" : $plat."_ABIV2";		
       
  4464 
       
  4465 		foreach my $plat(@platlist) 
       
  4466 		{
       
  4467 			if(($aDllFile =~ /\\($plat)\\/i) or ($aDllFile =~ /\\($plat\.\w+)\\/i ))
       
  4468 			{
       
  4469 				$platName = $1;
       
  4470 				last;
       
  4471 			}
       
  4472 		}		
       
  4473 		$rootPlatName =	&Plat_Customizes($platName) ? &Plat_Root($platName) : $platName;
       
  4474 		
       
  4475 		# Map files will be referred for all ARM platforms, 
       
  4476 		# and for BSF platforms which cutomizes ARM platforms.
       
  4477 		if($rootPlatName =~ /^ARMV5|$plat$/i){
       
  4478 			my $mapfile = "${aDllFile}.map";
       
  4479 			
       
  4480 			open MAPFILE, "$mapfile" or die "Can't open $mapfile\n";
       
  4481 			while(<MAPFILE>){
       
  4482 			my $line = $_;
       
  4483 
       
  4484 				#Ignore Local symbols.
       
  4485 				if(!$globalSyms){
       
  4486 					if($line =~ /Global Symbols/){
       
  4487 						$globalSyms = 1;
       
  4488 						next;
       
  4489 					}
       
  4490 					else{
       
  4491 						next;
       
  4492 					}
       
  4493 				}
       
  4494 
       
  4495 				$symbolTblEntry = $line;
       
  4496 				if($symbolTblEntry =~ /\s*(\S+)(?:\s+\(EXPORTED\))?\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)/){
       
  4497 					my $symbol		= $1;
       
  4498 					my $symbolValue = $2;
       
  4499 					my $data		= $3;
       
  4500 					my $symbolSz	= $4;
       
  4501 					if(!exists $DllMapRef->{$symbol}){
       
  4502 						next;
       
  4503 					}
       
  4504 					$DllSymMapRef = $DllMapRef->{$symbol};
       
  4505 					if($data =~ /Data/){
       
  4506 					# Valid
       
  4507 					}
       
  4508 					else {
       
  4509 					#	Invalid to patch a code symbol.
       
  4510 						print( "$DllSymMapRef->{obyfilename}($DllSymMapRef->{lineno}): Warning: $symbol is not a data Symbol.Ignoring patch statement.\n");
       
  4511 						$errors++ if($strict);
       
  4512 						$DllMapRef->{$symbol} = undef;
       
  4513 						next;
       
  4514 					}
       
  4515 
       
  4516 					
       
  4517 					# Record the address and the size of the symbol.
       
  4518 					$DllSymMapRef->{dataAddr} = $symbolValue;
       
  4519 					$DllSymMapRef->{size} = $symbolSz;
       
  4520 
       
  4521 					$matchedSymbols++;
       
  4522 					if( $matchedSymbols >= $SymbolCount){
       
  4523 						last;
       
  4524 					}
       
  4525 				}
       
  4526 			}
       
  4527 			close MAPFILE;
       
  4528 		}
       
  4529 		# DSO files will be referred for BPABI platforms(excluding ARM platforms),
       
  4530 		# and for BSF platforms which cutomizes BPABI platforms.
       
  4531 		else {
       
  4532 			my $abiDir = undef;
       
  4533 			foreach my $bpabi (@BPABIPlats){
       
  4534 				if($rootPlatName =~ /^$bpabi$/i){
       
  4535 					$abiDir = $platName;
       
  4536 					last;
       
  4537 				}
       
  4538 			}
       
  4539 
       
  4540 			if(!defined $abiDir){
       
  4541 				print("Can't locate the map or proxy dso file for $aDllFile\n");
       
  4542 				$errors++ if($strict);
       
  4543 				next; #go to the next patch dll data statement
       
  4544 			}
       
  4545 			if( $aDllFile =~ /(.*)\.[^.]+$/ ){
       
  4546 				my $proxydsofile = "$1.dso";
       
  4547 				$proxydsofile =~ s/$abiDir\\(.*)\\/ARMV5\\LIB\\/ig;
       
  4548 				open PIPE, "getexports -d $proxydsofile|" or die "Can't open file $proxydsofile\n";
       
  4549 				while (<PIPE>){
       
  4550 					my $line = $_;
       
  4551 					if($line =~ /\s*(\S+)\s+(\d+)\s+((\S+)\s+(\d+))?/){
       
  4552 						my $symbol = $1;
       
  4553 						my $ordinal = $2;
       
  4554 						my $data = $3;
       
  4555 						my $symbolSz = $5;
       
  4556 
       
  4557 						if(!$data){
       
  4558 							next;
       
  4559 						}
       
  4560 						if(!exists $DllMapRef->{$symbol}){
       
  4561 							next;
       
  4562 						}
       
  4563 
       
  4564 						$DllSymMapRef = $DllMapRef->{$symbol};
       
  4565 
       
  4566 						# Record the ordinal and the size of the symbol.
       
  4567 						$DllSymMapRef->{ordinal} = $ordinal;
       
  4568 						$DllSymMapRef->{size} = $symbolSz;
       
  4569 						$matchedSymbols++;
       
  4570 						if( $matchedSymbols >= $SymbolCount){
       
  4571 						last;
       
  4572 						}
       
  4573 					}
       
  4574 				}
       
  4575 
       
  4576 				close PIPE;
       
  4577 			}
       
  4578 		}
       
  4579 	}
       
  4580 	exit(1) if ($errors && $strict ) ;
       
  4581 }
       
  4582 
       
  4583 # make sure that all the absolute feature variant paths include a
       
  4584 # drive letter. This is required because cpp will not work with
       
  4585 # absolute paths starting with slashes.
       
  4586 sub addDrivesToFeatureVariantPaths
       
  4587 {
       
  4588 	return unless $featureVariant{'VALID'};
       
  4589 
       
  4590 	my $current = cwd();
       
  4591 	my $drive = $1 if ($current =~ /^(.:)/);
       
  4592 
       
  4593 	# pre-include file
       
  4594 	my $HRH = $featureVariant{'VARIANT_HRH'};
       
  4595 	$featureVariant{'VARIANT_HRH'} = $drive . $HRH if ($HRH =~ /^[\\\/]/);
       
  4596 
       
  4597 	# ROM include path
       
  4598 	my $dirRef = $featureVariant{'ROM_INCLUDES'};
       
  4599 	return unless $dirRef;
       
  4600 	my $i = 0;
       
  4601 
       
  4602 	foreach my $dir (@$dirRef)
       
  4603 	{
       
  4604 		$$dirRef[$i] = $drive . $dir if ($dir =~ /^[\\\/]/);
       
  4605 		$i++;
       
  4606 	}
       
  4607 }
       
  4608 sub create_smrimage
       
  4609 {
       
  4610 	if($needSmrImage)
       
  4611 	{
       
  4612 		foreach my $oby (@obeyFileList)
       
  4613 		{
       
  4614 			my $command = "rofsbuild -slog -smr=$oby.oby";
       
  4615 			print "* Executing $command\n" if($opt_v);
       
  4616 			system($command);
       
  4617 			if($? != 0)
       
  4618 			{
       
  4619 				print("* ROFSBUILD failed to generate SMR IMAGE\n") if($opt_v);
       
  4620 			}
       
  4621 			else
       
  4622 			{
       
  4623 				push(@smrImageFileList, $oby.".img");
       
  4624 			}
       
  4625 		}
       
  4626 	}
       
  4627 	if(@smrImageFileList)
       
  4628 	{
       
  4629 		print "\n";
       
  4630 		print "-------------------------------------------------------\n";
       
  4631 		print "| List of file(s) generated pertaining to SMR image |\n";
       
  4632 		print "-------------------------------------------------------\n";
       
  4633 		my $arraySize = scalar(@smrImageFileList);
       
  4634 		for(my $i=0; $i < $arraySize; $i++)
       
  4635 		{
       
  4636 			my $element = shift(@smrImageFileList);
       
  4637 			my $size = -s $element;
       
  4638 			print "Size = ".$size." bytes"."\t"."File = ".$element."\n";
       
  4639 		}
       
  4640 	}
       
  4641 	foreach my $errSmr (keys(%smrNameInfo))
       
  4642 	{
       
  4643 		if($smrNameInfo{$errSmr} > 1)
       
  4644 		{
       
  4645 			print "\n SMR image: $errSmr.img creating error for duplicated names!\n";
       
  4646 		}
       
  4647 	}
       
  4648 	if($smrNoImageName)
       
  4649 	{
       
  4650 		print "\n SMR image creating error for empty image name!\n";
       
  4651 	}
       
  4652 }
       
  4653 
       
  4654 1;