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