tools/buildrom.pm
changeset 9 b5c893269cd5
child 52 8e8f3d664437
equal deleted inserted replaced
8:36cb9eb36988 9:b5c893269cd5
       
     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 	  print STDERR "Failed to parse feature database XML file $featureXml\n";
       
  2711 		$featureXml = undef;
       
  2712 		exit(1) if($strict);
       
  2713 	}
       
  2714 }
       
  2715 
       
  2716 #----------------------------------------------------------------------------------
       
  2717 # Feature registry configuration file/Features data file generation phase
       
  2718 #
       
  2719 # If feature registry configuration files/features data files are required then creates these files for
       
  2720 # each ROM/ROFS image
       
  2721 #
       
  2722 sub featurefile_creation_phase
       
  2723 {
       
  2724 	if($onlysmrimage)
       
  2725 	{
       
  2726 		return;
       
  2727 	}
       
  2728 	# Set the name and Rom Image location of feature file.
       
  2729 	if ($enforceFeatureManager) 
       
  2730 	{
       
  2731 		# features data file location
       
  2732 		$dir = "private\\10205054\\";
       
  2733 		$featurefilename = "features.dat";
       
  2734 	}
       
  2735 	else
       
  2736 	{
       
  2737 		# feature registry configuration file location
       
  2738 		$dir = "private\\102744CA\\"; 
       
  2739 		$featurefilename = "featreg.cfg";
       
  2740 	}		
       
  2741 	if (defined ($featureXml)) 
       
  2742 	{
       
  2743 		my $featurefilecount=0;
       
  2744 		my $romimage=0;
       
  2745 
       
  2746 		foreach $line (@obydata)
       
  2747 		{
       
  2748 			# specify which romimage following lines are part of
       
  2749 			if ($line=~/^\s*REM \s*ROM_IMAGE\[(\d)\]/) 
       
  2750 			{
       
  2751 				$romimage=$1;
       
  2752 				$featurefilecount=0;
       
  2753 			}
       
  2754 			elsif ($line =~ /^\s*REM/i)
       
  2755 			{
       
  2756 				# ignore any other REM statements
       
  2757 			}
       
  2758 			elsif($line =~ /^\s*(FEATURE)\s*(\S*)\s*(.*)/i
       
  2759 					|| $line =~ /^\s*(EXCLUDE_FEATURE)\s*(\S*)\s*(.*)/i)
       
  2760 			{				
       
  2761 				# FEATURE  <feature_name>  [ SF  <status falgs> ] [ UD  <user data> ]
       
  2762 				my $feature = $1;
       
  2763 				my $featurevalue = $2;
       
  2764 				my $featureargs = $3;
       
  2765 				my $reservedbit = 0;
       
  2766 				my %featureflags=();				
       
  2767 				
       
  2768 				# Options 'SF' and 'UD' will be supported only for "-fm" option
       
  2769 				if ($featuremanager) 
       
  2770 				{
       
  2771 					# [ SF  <status falgs> ] [ UD  <user data> ]
       
  2772 					$featureargs =~	/(\S*)\s*(\S*)\s*(\S*)\s*(\S*)\s*/ ;
       
  2773 
       
  2774 					# Store the values of 'SF' and 'UD', or any invalid option, if provided					
       
  2775 					if ($1) 
       
  2776 					{	
       
  2777 						$featureflags{uc($1)} = $2;						
       
  2778 					}
       
  2779 					if ($3) 
       
  2780 					{
       
  2781 						$featureflags{uc($3)} = $4;									
       
  2782 					}
       
  2783 
       
  2784 					# Generate a warning if the option provided with Feature/Exclude_Feature keyword is  
       
  2785 					# not 'SF' or 'UD'.
       
  2786 					foreach my $Key (keys %featureflags)
       
  2787 					{						
       
  2788 						if ($Key !~ /^(SF|UD)$/)
       
  2789 						{
       
  2790 							print "Warning: Invalid argument \"$Key\" specified for feature $featurevalue\n";
       
  2791 							delete $featureflags{$Key};
       
  2792 							next;
       
  2793 						}						
       
  2794 					}							
       
  2795 				}				
       
  2796 				# In verbose mode, generate warning if "SF|UD" arguments or invalid arguments are specified
       
  2797 				# for "-f|fr" option.
       
  2798 				elsif ($featureargs && $opt_v)
       
  2799 				{
       
  2800 					print "Invalid argument(s) \"$featureargs\" provided for feature \"$featurevalue\"\n";
       
  2801 					foreach my $Key (keys %featureflags)
       
  2802 					{
       
  2803 						delete $featureflags{$Key};
       
  2804 					}
       
  2805 				}				
       
  2806 				
       
  2807 				# The feature file name is of the format featreg.cfg[x-y] or features.dat[x-y] 
       
  2808 				# where x is the romimage id, y is always 0, reserved for future use.
       
  2809 				my $targetfeaturefile;
       
  2810 				if (($romimage == 0) && ($reservedbit == 0))
       
  2811 				{
       
  2812 
       
  2813 					# Core image will not have the mangled name
       
  2814 				 	$targetfeaturefile = $featurefilename;
       
  2815 				}
       
  2816 				else
       
  2817 				{
       
  2818 				 	$targetfeaturefile = $featurefilename . "\[". $romimage . "\-$reservedbit\]";
       
  2819 				}
       
  2820 				my $flag=1;
       
  2821 				my $featureflag;
       
  2822 				if ($feature =~ /^FEATURE$/i)
       
  2823 				{
       
  2824 					$featureflag = 1;
       
  2825 				}
       
  2826 				else
       
  2827 				{
       
  2828 					$featureflag = 0;
       
  2829 				}
       
  2830 
       
  2831 				my $i;
       
  2832  				# loop to see if name of feature file already added to this romimage in array
       
  2833 				for($i=0;$i<$featurefilecount && $flag;$i++)
       
  2834 				{
       
  2835 					if($featurefilearray[$romimage][$i]{cfgfile} eq $targetfeaturefile)
       
  2836 					{
       
  2837 						$flag=0;
       
  2838 					}
       
  2839 				}
       
  2840 			
       
  2841 				if($flag) { # adds feature file if not yet listed for this romimage in array
       
  2842 					$featurefilearray[$romimage][$featurefilecount++]={cfgfile=>$targetfeaturefile, cfgdir=>$dir};
       
  2843 					$i=$featurefilecount;
       
  2844 				}
       
  2845 
       
  2846 				$featureslist[$featurescount]= {feature=>$featurevalue, include=>$featureflag, rom=>$romimage, cfgfile=>$i-1};
       
  2847 				
       
  2848 				# Store the value of 'SF' in 'featureslist' array
       
  2849 				if (defined $featureflags{SF}) 
       
  2850 				{
       
  2851 					$featureslist[$featurescount]->{SF} = $featureflags{SF};						
       
  2852 				}
       
  2853 				# Store the value of 'UD' in 'featureslist' array
       
  2854 				if (defined $featureflags{UD}) 
       
  2855 				{
       
  2856 					$featureslist[$featurescount]->{UD} = $featureflags{UD};
       
  2857 				}				
       
  2858 				$featurescount++;
       
  2859 			}
       
  2860 		}
       
  2861 
       
  2862 		# Create Feature File
       
  2863 		for(my $i=0;$i<scalar @featurefilearray;$i++)
       
  2864 		{
       
  2865 			my $j=0;
       
  2866 			while(defined $featurefilearray[$i][$j])
       
  2867 			{
       
  2868 				my $targetfeaturefile = $featurefilearray[$i][$j]{cfgfile};
       
  2869 				if (!(&featuresutil::createFeatureFile($i,$j,$targetfeaturefile,\@featureslist,$featuremanager))) 
       
  2870 				{
       
  2871 					print STDERR "Failed to create Feature file $targetfeaturefile\n";
       
  2872 					$featurefilearray[$i][$j]{cfgfile}= undef;
       
  2873 					exit(1) if($strict);					
       
  2874 				}
       
  2875 				$j++;
       
  2876 			}
       
  2877 		}
       
  2878 	
       
  2879 		undef @newobydata;
       
  2880 		my $flag=1;
       
  2881         	my $imageIdx=0;
       
  2882 
       
  2883 		# Add feature files to ROM image, adds lines to obey file to specify existing locations
       
  2884 		# of feature files and target locations.
       
  2885 		foreach $line (@obydata)
       
  2886 		{
       
  2887 			if($line =~/REM ROM_IMAGE\[(\d)\]/i)
       
  2888 			{
       
  2889 				my $romimage=$1;
       
  2890 				if($flag)
       
  2891 				{
       
  2892 					# Put in feature files for ROM_IMAGE[0]
       
  2893 					$flag=0;
       
  2894 					my $k=0;
       
  2895 					while(defined $featurefilearray[0][$k])
       
  2896 					{
       
  2897 						my $targetfeaturefile=$featurefilearray[0][$k]{cfgfile};
       
  2898 						if (defined $targetfeaturefile) 
       
  2899 						{
       
  2900 							push @newobydata, "data=" . "\\$thisdir" . $targetfeaturefile . " \"" . $featurefilearray[0][$k]{cfgdir} . $targetfeaturefile .  "\"\n";							
       
  2901 						}
       
  2902 						$k++;
       
  2903 					}
       
  2904 				}
       
  2905 				push @newobydata, "\n" . $line . "\n";			
       
  2906 
       
  2907 				my $j=0;
       
  2908 				while(defined $featurefilearray[$romimage][$j])
       
  2909 				{
       
  2910 					# Put in feature files for current ROM_IMAGE
       
  2911 					my $targetfeaturefile=$featurefilearray[$romimage][$j]{cfgfile};
       
  2912 					
       
  2913 					# Rom images will not have mangled name for feature files
       
  2914 				 	my $destinationfeaturefile = $featurefilename;
       
  2915 					
       
  2916 					# Rofsbuild will set attribute 'exattrib=U' in the entry record when this field is used.
       
  2917 					# File Server when asked for a directory listing would notice the attribute and will return the 
       
  2918 					# list with mangled names. Hence, mangled name for feature files should not be put in ROM_IMAGE.
       
  2919 					my $exattribute = "exattrib=U";
       
  2920 
       
  2921 					if (defined $targetfeaturefile)
       
  2922 					{
       
  2923 						push @newobydata, "data=" . "\\$thisdir" . $targetfeaturefile . " \"" . $featurefilearray[$romimage][$j]{cfgdir} . $destinationfeaturefile .  "\"\t\t" . $exattribute . "\n";
       
  2924 					}
       
  2925 					$j++;
       
  2926 				}
       
  2927 			}
       
  2928 			elsif($line !~ /^\s*(FEATURE)\s*/i && $line !~ /^\s*(EXCLUDE_FEATURE)\s*/i)
       
  2929 			{
       
  2930 				# Put in all other lines except the FEATURE and EXCLUDE_FEATURE keywords
       
  2931 				push @newobydata, $line;
       
  2932 			}
       
  2933 		}
       
  2934 
       
  2935 		if($flag)
       
  2936 		{ 
       
  2937 			# Put in feature files for ROM_IMAGE[0] if it is the only ROM_IMAGE
       
  2938 			my $k=0;
       
  2939 			while(defined $featurefilearray[0][$k])
       
  2940 			{
       
  2941 				my $targetfeaturefile = $featurefilearray[0][$k]{cfgfile};
       
  2942 				if (defined $targetfeaturefile)
       
  2943 				{
       
  2944 					push @newobydata, "data=" . "\\$thisdir" . $targetfeaturefile . " \"" . $featurefilearray[0][$k]{cfgdir} . $targetfeaturefile . "\"\n";
       
  2945 				}
       
  2946 				$k++;
       
  2947 			}
       
  2948 		}
       
  2949 		@obydata=@newobydata;
       
  2950 	}
       
  2951 	elsif ($enforceFeatureManager && $noFeatureManager && $preBuiltFeaturesDataFile)
       
  2952 	{
       
  2953         print "Valid: $preBuiltFeaturesDataFile\n";
       
  2954 		if (-e $preBuiltFeaturesDataFile) 
       
  2955 		{			
       
  2956 			my @newobydata = ();
       
  2957 			my $flag = 1;
       
  2958 			foreach my $line (@obydata)
       
  2959 			{
       
  2960 				# Put in the pre-built features data file in ROM_IMAGE[0] 
       
  2961 				if($line =~/REM ROM_IMAGE\[1\]/i)
       
  2962 				{
       
  2963 					push @newobydata, "data=$preBuiltFeaturesDataFile" . " \"" . $dir . $featurefilename . "\"\n";
       
  2964 					$flag =0;
       
  2965 				}
       
  2966 				push @newobydata, $line;
       
  2967 			}
       
  2968 			if($flag)
       
  2969 			{ 
       
  2970 				# Put in the pre-built features data file in ROM_IMAGE[0] if it is the only ROM_IMAGE
       
  2971 				push @newobydata, "data=$preBuiltFeaturesDataFile" . " \"" . $dir . $featurefilename . "\"\n";
       
  2972 			}
       
  2973 			@obydata =  @newobydata;
       
  2974 		}
       
  2975 		else
       
  2976 		{
       
  2977 			print "Error: File \"$preBuiltFeaturesDataFile\" doesn't exist.\n";
       
  2978 			exit(1);
       
  2979 		}
       
  2980 	}
       
  2981 	elsif ($enforceFeatureManager)
       
  2982 	{
       
  2983 	    print "Error: no feature data file or pre-built feature data file is provided!";
       
  2984 	    exit(1);
       
  2985 	}
       
  2986 }
       
  2987 my ($fromABI,$toABI) = split / /,$abiDowngrade;
       
  2988 
       
  2989 #----------------------------------------------------------------------------------
       
  2990 # Problem suppression phase
       
  2991 #
       
  2992 # Downgrade files which don't exist for the ABI (if a downgrade path is specified)
       
  2993 # Comment out missing files or report errors if strict option enabled
       
  2994 #
       
  2995 # Detect any references to Feature Variant binaries and substitute in the
       
  2996 # correct source binary name using the VMAP file mechanism.
       
  2997 
       
  2998 sub suppress_phase
       
  2999 {
       
  3000 	undef @newobydata;
       
  3001 	Plat_Init($PerlLibPath);
       
  3002 
       
  3003 	# use the "default" feature variant by default.
       
  3004 	my $varname = $featureVariant{'VALID'} ? $featureVariant{'NAME'} : "default";
       
  3005 
       
  3006 	foreach $line (@obydata)
       
  3007 	{
       
  3008 		track_source($line);
       
  3009 		if ($line =~ /^\s*REM/i)
       
  3010 		{
       
  3011 			# ignore REM statements, to avoid processing "REM data=xxx yyy"
       
  3012 		}
       
  3013 		# 
       
  3014 		# thing=some\file 
       
  3015 		#
       
  3016 		elsif ($line =~ /(\S+)\s*=\s*"?(\S+\\\S+)"?/)
       
  3017 		{
       
  3018 			my $what = $1;
       
  3019 			my $filename = $2;
       
  3020 			if ($line =~ /(\S+)\s*=\s*"([^"]+)"/)
       
  3021 			{
       
  3022 				$filename = $2;
       
  3023 			}
       
  3024 			my $normedFilename = &Genutl_NormaliseVersionedName($filename);
       
  3025 
       
  3026 			# find all the alternative file locations
       
  3027 			my @alternatives = fallback($normedFilename);
       
  3028 			# test the original location first
       
  3029 			unshift(@alternatives, $normedFilename);
       
  3030 
       
  3031 			# choose the first file location that actually exists
       
  3032 			my $fileExists = 0;
       
  3033 			foreach my $altFile (@alternatives)
       
  3034 			{
       
  3035 			    my $tmpPath;
       
  3036 			    my $tmpFile;
       
  3037 				if($altFile =~ /"?(.*\\arm\w+_?\w+)\\([^"]+)/i)
       
  3038 				{
       
  3039 					$tmpPath = $1;
       
  3040 					$tmpFile = $2;
       
  3041 				}
       
  3042 				$tmpPath .= "\.$varname";
       
  3043 				if (-d $tmpPath){
       
  3044 				  if (-e $tmpPath ."\\$tmpFile"){
       
  3045 				   $fileExists = $tmpPath . "\\$tmpFile";
       
  3046 				  }
       
  3047 				  elsif (-e $altFile){
       
  3048 				   $fileExists = $altFile;
       
  3049 				  }
       
  3050 				}
       
  3051 				else {
       
  3052 				  $fileExists = featurevariantmap->Find($altFile, $varname);
       
  3053 				}
       
  3054 				last if $fileExists;
       
  3055 			}
       
  3056 
       
  3057 			# edit the OBY line to use the actual file name which we found.
       
  3058 			# (maybe) warn if an alternative to the original was selected.
       
  3059 			if ($fileExists)
       
  3060 			{
       
  3061 				my $from = $filename;
       
  3062 				$from =~ s/\\/\\\\/g;		# need to escape backslashes
       
  3063 				$from =~ s/(\[|\])/\\$1/g;	# need to escape square brackets for file names like "featreg.cfg[x-y]",etc.
       
  3064 				my $into = $fileExists;
       
  3065 
       
  3066  				$line =~ s/$from/$into/;
       
  3067 
       
  3068  				if ($warnSelection && ($fileExists ne $normedFilename))
       
  3069 				{
       
  3070 			    	print "replaced $filename with $fileExists\n";
       
  3071 				}
       
  3072 			}
       
  3073 			else
       
  3074 			{
       
  3075    				# No suitable alternative was found, so comment out the line unless
       
  3076 				# it is a manatory ROMBUILD keyword, in which case it is better
       
  3077 				# to let ROMBUILD report the missing file rather than report the
       
  3078 				# missing keyword.
       
  3079    				if ($what !~ /^bootbinary|variant|primary|secondary|hide/i)
       
  3080 				{
       
  3081    					$line = "REM MISSING " . $line;
       
  3082    					print_source_error("Missing file: '$filename' in statement '$what='");
       
  3083 					print "\ttried @alternatives\n"  if ($opt_v && @alternatives > 1);
       
  3084    					# treat as an error if the strict option is selected.
       
  3085    					$errors++ if ($strict);
       
  3086 				}
       
  3087 			}
       
  3088 
       
  3089 			# Once the binary is located in the appropriate ABI directory (e.g.,following the binary 
       
  3090 			# selection order), check if the binary has been used in a patch dll statement. This is
       
  3091 			# required to find out the source file. In ABIv1, the source file is required to find the
       
  3092 			# .map file, while, in ABIv2, the destination file gives the dso file name.
       
  3093 			if($line =~ /(\S+)\s*=\s*(\S+)\s+(\S+)\s*(.*)?/)
       
  3094 			{
       
  3095 				my $aSrcfile = $2;
       
  3096 				my $dstFile = $3;
       
  3097 				my $dstPath = "";
       
  3098 
       
  3099 				if($aSrcfile =~ /"?([^"]+)/){
       
  3100 				$aSrcfile = $1;
       
  3101 				}
       
  3102 
       
  3103 				$aSrcfile = &Genutl_NormaliseVersionedName($aSrcfile);
       
  3104 				if($dstFile =~ /"?(.*)\\([^"]+)/)
       
  3105 				{
       
  3106 					$dstPath = $1;
       
  3107 					$dstFile = $2;
       
  3108 				}
       
  3109 				my $dllMapKey = lc ($dstFile);
       
  3110 				if(exists $DllDataMap{$dllMapKey}) {
       
  3111 					my $dllSymInfo = \%{$DllDataMap{$dllMapKey}};
       
  3112 					$dllSymInfo->{srcfile} = $aSrcfile;
       
  3113 					$dllSymInfo->{dstpath} = $dstPath;
       
  3114 				}
       
  3115 			}
       
  3116 
       
  3117 		}
       
  3118 		push @newobydata, $line;
       
  3119 	}
       
  3120 	@obydata = @newobydata;
       
  3121 	dump_obydata("tmp7.oby", "result of problem-suppression phase") if ($opt_v);
       
  3122 	die "ERROR: $errors missing file(s) detected\n" if ($strict && $errors );
       
  3123 }
       
  3124 
       
  3125 # Remove leading and trailing whitespaces from a list of strings or a single string
       
  3126 sub trim 
       
  3127 {
       
  3128 	my @out = @_;
       
  3129 	for (@out) {
       
  3130 		s/^\s+//;
       
  3131 		s/\s+$//;
       
  3132 	}
       
  3133 	return wantarray ? @out : $out[0];
       
  3134 }
       
  3135 
       
  3136 # Generate a list of alternative locations for the given filename
       
  3137 sub fallback
       
  3138 {
       
  3139    	my $file = shift;
       
  3140    	my @alternatives = CheckCustomization($file);
       
  3141  
       
  3142  	# If BINARY_SELECTION_ORDER macro is specified in the oby file
       
  3143  	if ($binarySelectionOrderFlag)
       
  3144    	{
       
  3145  		# Search in the specified binary order 
       
  3146  		if(!@Global_PlatList)
       
  3147 		{
       
  3148 			@Global_PlatList = Plat_List();
       
  3149 		}
       
  3150  		my $b;
       
  3151  		my $e;
       
  3152  		foreach my $plat (@Global_PlatList) 
       
  3153   		{
       
  3154   			if ($file =~ /^(.*)\\$plat\\(.*)$/i) 
       
  3155   			{
       
  3156   				$b = $1;
       
  3157   				$e = $2;
       
  3158  				last;
       
  3159  			}
       
  3160  		}
       
  3161  		push(@alternatives, "$b\\$firstDIR\\$e");
       
  3162  			
       
  3163  		foreach my $toDIR (@binarySelectionOrder)
       
  3164    		{
       
  3165  			push(@alternatives, "$b\\$toDIR\\$e");
       
  3166    		}
       
  3167    	}
       
  3168   	
       
  3169  	# If the file is not found in the specified ABIV2 platform, then select from ARMV5 directory.
       
  3170  	# This is necessary as some of the runtime DLLs will be present only in ARMV5 directory. 
       
  3171 	# Add the BPABI Platforms to be added
       
  3172 	if(!@Global_BPABIPlats)
       
  3173 	{
       
  3174 		@Global_BPABIPlats = &BPABIutl_Plat_List;
       
  3175 	}
       
  3176 
       
  3177  	foreach my $BpabiPlat (@Global_BPABIPlats)
       
  3178  	{
       
  3179  		if ($fromABI eq "" && $file =~ /^(.*)\\$BpabiPlat\\(.*)$/)
       
  3180    		{
       
  3181  			push(@alternatives, "$1\\armv5\\$2");
       
  3182    		}
       
  3183    	}
       
  3184 
       
  3185 	if ($customizedPlat && $fromABI eq "" && $file =~ /^(.*)\\$customizedPlat\\(.*)$/)
       
  3186 	{
       
  3187 		my $b = $1;
       
  3188 		my $e = $2;
       
  3189 		# if platform customization 
       
  3190 		my $rootPlat = Plat_Root($customizedPlat);		
       
  3191         
       
  3192    		#Check in ARMV7 folder for binaries in case GCCEV7 is used [DEF128457 ]
       
  3193    		if($customizedPlat == "GCCEV7")
       
  3194    		{
       
  3195    			push(@alternatives,"$b\\armv7\\$e");
       
  3196    		}
       
  3197 
       
  3198 		if( grep /$rootPlat/, @Global_BPABIPlats)
       
  3199 		{
       
  3200  			push(@alternatives, "$b\\armv5\\$e");
       
  3201 		}
       
  3202 	}
       
  3203 
       
  3204 	if ($fromABI eq "" && $file =~ /^(.*)\\ARMV5_ABIV1\\(.*)$/i)
       
  3205    	{
       
  3206  		push(@alternatives, "$1\\armv5\\$2");
       
  3207    	}
       
  3208   		
       
  3209    	if ($fromABI ne "" && $file =~ /^(.*)\\$fromABI\\(.*)$/)
       
  3210 	{
       
  3211  		push(@alternatives, "$1\\$toABI\\$2");
       
  3212 	}
       
  3213    
       
  3214    	return @alternatives;
       
  3215 }
       
  3216 
       
  3217 # Generate a list of alternative locations for the given filename which
       
  3218 # result from the possible platform customizations.
       
  3219 sub CheckCustomization
       
  3220 {
       
  3221  	my $file = shift;
       
  3222  	my @alternatives;
       
  3223 	$customizedPlat = undef;	# global (used in feedback)
       
  3224 
       
  3225  	if(!@Global_PlatList)
       
  3226 	{
       
  3227 		@Global_PlatList = Plat_List();
       
  3228 	}
       
  3229  	foreach my $plat (@Global_PlatList) 
       
  3230 	{
       
  3231  		if ($file =~ /^(.*)\\$plat\\(.*)$/i) 
       
  3232 		{
       
  3233  			my $b = $1;
       
  3234  			my $e = $2;
       
  3235  			my $root = Plat_Customizes($plat);
       
  3236  			if ($root) 
       
  3237 			{
       
  3238 				# Preserve the plat that is customized
       
  3239 				$customizedPlat = $plat;
       
  3240 
       
  3241 				# If a BSF platform customizes another BSF platform (i.e. a
       
  3242 				# BSF hierarchy exists), look for the file starting from the
       
  3243 				# child BSF platform and working back to the root BSF platform
       
  3244 				while ($root)
       
  3245 				{
       
  3246 					push(@alternatives, "$b\\$root\\$e");
       
  3247 
       
  3248 					# Temporary special case for ARMV5_ABIV1 and ARMV5_ABIV2
       
  3249 					if ($root =~ /^armv5_abiv[12]$/i)
       
  3250 					{
       
  3251 						push(@alternatives, "$b\\armv5\\$e");
       
  3252  					}
       
  3253 
       
  3254 					$root = Plat_Customizes($root);
       
  3255 				}
       
  3256  			}
       
  3257 			return @alternatives;
       
  3258  		}
       
  3259  	}
       
  3260 	return @alternatives;
       
  3261 }		
       
  3262    
       
  3263 #----------------------------------------------------------------------------------
       
  3264 # Bitmap and aif conversion phase
       
  3265 #
       
  3266 # Convert any "bitmap=" or "compressed-bitmap=" files into ROM format bitmaps
       
  3267 # Convert any "auto-bitmap=" to handle bitmap appropriately for xip and non-xip images
       
  3268 # Convert "aif=" files appropriately for xip and non-xip images
       
  3269 sub bitmap_aif_converison_phase
       
  3270 {
       
  3271 	my $is_xip=1;
       
  3272 	undef @newobydata;
       
  3273 	foreach $line (@obydata)
       
  3274 	{
       
  3275 		track_source($line);
       
  3276 		# keep track of the XIP-ness of this rom partition
       
  3277 		if ($line =~ /^\s*REM ROM_IMAGE\[(\d+)\]\s+(.*)$/i)
       
  3278 		{ $is_xip=$romimage[$1]{xip}; }
       
  3279 		#
       
  3280 		# aif=source dest 
       
  3281 		# include aif file - use XIP version for XIP roms if it exists, otherwise use the file specified
       
  3282 		#
       
  3283 		if ($line =~ /^\s*aif=/i)
       
  3284 		{
       
  3285 			my $xip="_xip";
       
  3286 			my @aif= split(/\s+/,$line);
       
  3287 			my $path=Path_Split('Path',"$aif[0]");
       
  3288 			my $base=Path_Split('Base',"$aif[0]");
       
  3289 			$path =~ s/^....//;
       
  3290 			my $ext=Path_Split('Ext',"$aif[0]");
       
  3291 			if ($is_xip && (-e "$path$base$xip$ext"))
       
  3292 			{ $line="data=$path$base$xip$ext\t\t$aif[1]\n"; }
       
  3293 			else
       
  3294 			{ $line="data=$path$base$ext\t\t$aif[1]\n"; }
       
  3295 		}
       
  3296 		#
       
  3297 		# auto-bitmap=
       
  3298 		#
       
  3299 		# if currently in XIP image, then use a compressed-bitmap
       
  3300 		# otherwise use a RAM format bitmap
       
  3301 		#
       
  3302 		if ($line =~ /^\s*auto-bitmap=/i)
       
  3303 		{
       
  3304 			if ($is_xip)
       
  3305 			{ $line =~ s/auto-bitmap=/compressed-bitmap=/i }
       
  3306 			else
       
  3307 			{ $line =~ s/auto-bitmap=/data=/i }
       
  3308 		}
       
  3309 		#
       
  3310 		# uncompressed-bitmap
       
  3311 		#
       
  3312 		# this is currently just a synonym for 'bitmap'
       
  3313 		$line =~ s/uncompressed-bitmap=/bitmap=/i;
       
  3314 	
       
  3315 		# 
       
  3316 		# bitmap=source dest 
       
  3317 		#
       
  3318 		if ($line =~ /^\s*bitmap=\s*"?(\S+)"?\s+"?(\S+)"?/i)
       
  3319 		{
       
  3320 			my $mbm = $1;
       
  3321 			my $dest = $2;
       
  3322 			my $rom_mbm = "$1_rom";
       
  3323 			if ($is_xip eq 0)
       
  3324 			{
       
  3325 				# non-XIP rom - just include the mbm file
       
  3326 				$line = "data=\"$mbm\"\t\"$dest\"\n";
       
  3327 			}
       
  3328 			else
       
  3329 			{	
       
  3330 		        if (! -e $rom_mbm || -M $rom_mbm >= -M $mbm)
       
  3331 			    {
       
  3332 				    system "bmconv /q /r $rom_mbm /m$mbm";
       
  3333 				    my $bmconv_status = $?;
       
  3334 				    die "* bmconv failed\n" if ($bmconv_status != 0 || !-f $rom_mbm);
       
  3335 			    }
       
  3336 				$line = "data=\"$rom_mbm\"\t\"$dest\"\n";
       
  3337 				push @tempfiles, $rom_mbm;
       
  3338 			}
       
  3339 		}
       
  3340 		#
       
  3341 		# compressed-bitmap=
       
  3342 		#
       
  3343 		# if file is a compressed ROM image file
       
  3344 		elsif ($line =~ /^\s*compressed-bitmap=\s*"?(\S+)"?\s+"?(\S+)"?/i)
       
  3345 		{
       
  3346 			my $mbm = $1;
       
  3347 			my $dest = $2;
       
  3348 			my $cmprssd_rom_mbm = "$1_rom";
       
  3349 			if ($is_xip eq 0)
       
  3350 			{
       
  3351 				# non-XIP rom - just include the mbm file
       
  3352 				$line = "data=\"$mbm\"\t\"$dest\"\n";
       
  3353 			}
       
  3354 			else
       
  3355 			{
       
  3356 				if (! -e $cmprssd_rom_mbm || -M $cmprssd_rom_mbm >= -M $mbm)
       
  3357 			    {
       
  3358 				    system "bmconv /q /s $cmprssd_rom_mbm /m$mbm";
       
  3359 				    my $bmconv_status = $?;
       
  3360 				    die "* bmconv failed\n" if ($bmconv_status != 0 || !-f $cmprssd_rom_mbm);
       
  3361 				}
       
  3362 				$line = "data=\"$cmprssd_rom_mbm\"\t\"$dest\"\n";
       
  3363 				push @tempfiles, $cmprssd_rom_mbm;			    
       
  3364 			}
       
  3365 		}
       
  3366 		push @newobydata, $line;
       
  3367 	}
       
  3368 	@obydata = @newobydata;
       
  3369 	dump_obydata("tmp8.oby", "result of bitmap conversion phase") if ($opt_v);
       
  3370 }
       
  3371 
       
  3372 
       
  3373 sub reformat_line($)
       
  3374 {
       
  3375 	my ($line) = @_;
       
  3376 	my $type = "";
       
  3377 	my $variant = "";
       
  3378 	my $pcfile = "";
       
  3379 	my $romfile = "";
       
  3380 	my $tail = "";
       
  3381 	
       
  3382 	# time=21/07/1999 12:00:00
       
  3383 	# primary[0x09080004]   =\epoc32\release\misa\udeb\ekern.exe
       
  3384 	# data=\epoc32\wins\C\System\Alarms\churchbell.snd    "System\Alarms\Church bell"
       
  3385 	# file[0x07060001]=\epoc32\release\MAWD\urel\cAkyb1.dll          System\Libs\EKeyb.dll
       
  3386 	# file=\epoc32\release\marm\urel\eikcore.dll 			System\Libs\Eikcore.dll
       
  3387 	# alias \System\Bin\DRTRVCT2_2.dll 			\System\Bin\DRTRVCT2_1.dll
       
  3388 	#
       
  3389 	if ($line =~ /^\s*TIME\s*=\s*/i)
       
  3390 	{
       
  3391 		return $line;
       
  3392 	}
       
  3393   	elsif($line =~ /^\s*volume\s*=.*/i)
       
  3394   	{
       
  3395   		return $line;		
       
  3396   	}
       
  3397 	elsif($line =~ /^\s*kerneltrace\s*=.*/i)
       
  3398 	{
       
  3399 		return $line;
       
  3400 	}
       
  3401 	if ($line =~ /^\s*(\S+)\s*=\s*(\S+)\s+"\\?(.*)"(.*)$/)
       
  3402 	{
       
  3403 		$type = $1;
       
  3404 		$variant = "";
       
  3405 		$pcfile = $2;
       
  3406 		$romfile = $3;
       
  3407 		$tail = $4;
       
  3408 	}
       
  3409 	elsif ($line =~ /^\s*(\S+)(\[\S+\])\s*=\s*(\S+)\s+\\?(\S+)(.*)$/)
       
  3410 	{
       
  3411 		$type = $1;
       
  3412 		$variant = $2;
       
  3413 		$pcfile = $3;
       
  3414 		$romfile = $4;
       
  3415 		$tail = $5;
       
  3416 	}
       
  3417 	elsif ($line =~ /(\S+)\s*=\s*"([^"]+)"\s+"\\?(.*)"(.*)$/)
       
  3418 	{
       
  3419 		if ($line !~ /^REM MISSING/i)
       
  3420 		{
       
  3421 			$type = $1;
       
  3422 			$variant = "";
       
  3423 			$pcfile = "\"$2\"";
       
  3424 			$romfile = $3;
       
  3425 			$tail = $4;
       
  3426 		}
       
  3427 		else{
       
  3428 			return $line;
       
  3429 		}
       
  3430 	}
       
  3431 	elsif ($line =~ /^\s*(\S+)\s*=\s*(\S+)\s+\\?(\S+)(.*)$/)
       
  3432 	{
       
  3433 		$type = $1;
       
  3434 		$variant = "";
       
  3435 		$pcfile = $2;
       
  3436 		$romfile = $3;
       
  3437 		$tail = $4;
       
  3438 	}
       
  3439 	elsif($line =~ /^\s*(patchdata)\s*(\S+)\s*\@\s*(\S+)\s+(\S+)/i)
       
  3440 	{
       
  3441 		# Reformat the patchdata statement
       
  3442 		my $romfilename = $2;
       
  3443 		my $patchdlldatamap_key = lc ($romfilename);
       
  3444 		my $symbolname = $3;
       
  3445 		my $value = $4;
       
  3446 		my ($index, $elementSize);		# For when the symbol is an array, and we're patching one element
       
  3447 		my $scalarSize;
       
  3448 		
       
  3449 		if(!defined $DllDataMap{$patchdlldatamap_key}->{dstpath}){
       
  3450 			print_source_error(" File $romfilename has not been included into ROM image");
       
  3451 			$errors++ if($strict);
       
  3452 			$line = "REM $line\n";
       
  3453 			return $line;
       
  3454 		}
       
  3455 	
       
  3456 		if ($enforceSysBin)
       
  3457 		{
       
  3458 			if ($DllDataMap{$patchdlldatamap_key}->{dstpath} !~ /^sys\\bin/i 
       
  3459 			 && $DllDataMap{$patchdlldatamap_key}->{dstpath} !~ /^sys\/bin/i)
       
  3460 			{
       
  3461 				$DllDataMap{$patchdlldatamap_key}->{dstpath} = "sys\\bin";
       
  3462 			}
       
  3463 		}
       
  3464 		
       
  3465 		my $dllfile = $DllDataMap{$patchdlldatamap_key}->{dstpath} . "\\". $romfilename;
       
  3466 		
       
  3467 		$line = "$1  ";
       
  3468 		$line .= "$dllfile ";
       
  3469  
       
  3470 		# Convert value into decimal (used to be done in AddDllDataInfo, but that limited us to
       
  3471 		# one value per symbol, and we now support patching arrays, e.g. the Hal's InitialValue[],
       
  3472 		# so we can't do it that way any more.)
       
  3473 		if ($value =~ /^0x([0-9a-f]+)$/i) {
       
  3474 			$value = hex($1);
       
  3475 		}
       
  3476 		elsif ($value =~ /^(-?\d+)$/) {
       
  3477 			$value = $1;
       
  3478 		}
       
  3479 		else {
       
  3480 			print_source_error("Attempt to set $symbolname to illegal value $value");
       
  3481 			$errors++ if($strict);
       
  3482 			$line = "REM $line\n";
       
  3483 			return $line;
       
  3484 		}
       
  3485 
       
  3486 		if ($symbolname =~ s/:(\d+)\[((0x)?[0-9a-f]+)\]$//i) {
       
  3487 			($index, $elementSize) = ($2, $1);
       
  3488 			$index = hex($index) if $index =~ /^0x/i;
       
  3489 		}
       
  3490 
       
  3491 		my $DllSymInfoRef = $DllDataMap{$patchdlldatamap_key}->{$symbolname};
       
  3492  
       
  3493 		if (!defined($DllSymInfoRef->{size})) {
       
  3494 			print_source_error("Size for symbol $symbolname not found");
       
  3495 			$errors++ if($strict);
       
  3496 			$line = "REM $line\n";
       
  3497 			return $line;
       
  3498 		}
       
  3499 
       
  3500 		if (defined($elementSize)) {
       
  3501 			$scalarSize = $elementSize / 8;
       
  3502 			if ($scalarSize != 1 && $scalarSize != 2 && $scalarSize != 4) {
       
  3503 				print_source_error("Invalid bit size $elementSize for array $symbolname in $romfilename");
       
  3504 				$errors++ if($strict);
       
  3505 				$line = "REM $line\n";
       
  3506 				return $line;
       
  3507 			}
       
  3508 			if (($index + 1) * $scalarSize > $DllSymInfoRef->{size}) {
       
  3509 				print_source_error("Invalid index $index into array $symbolname in $romfilename");
       
  3510 				$errors++ if($strict);
       
  3511 				$line = "REM $line\n";
       
  3512 				return $line;
       
  3513 			}
       
  3514 		} else {
       
  3515 			$scalarSize = $DllSymInfoRef->{size};
       
  3516 		}
       
  3517 
       
  3518 		my $max_value = 0xffffffff;
       
  3519 
       
  3520 		if ($scalarSize == 1) {
       
  3521 			$max_value = 0xff;
       
  3522 		}
       
  3523 		elsif ($scalarSize == 2) {
       
  3524 			$max_value = 0xffff;
       
  3525 		}
       
  3526 
       
  3527 		if ($value > $max_value) {
       
  3528 			$value &= $max_value;
       
  3529 			print "$DllSymInfoRef->{obyfilename}($DllSymInfoRef->{lineno}): Warning:Value overflow of $symbolname\n";
       
  3530 			$errors++ if($strict);
       
  3531 		}
       
  3532 
       
  3533 		if(defined $DllSymInfoRef->{ordinal}) {
       
  3534 			if (defined($elementSize)) {
       
  3535 				my $ord = $DllSymInfoRef->{ordinal};
       
  3536 				my $offset = $index * $scalarSize;
       
  3537 				$line .= "ordinal $ord+$offset ";
       
  3538 			} else {
       
  3539 				$line .= "ordinal ";
       
  3540 				$line .= $DllSymInfoRef->{ordinal} . " ";
       
  3541 			}
       
  3542 		}
       
  3543 		elsif(defined $DllSymInfoRef->{dataAddr}) {
       
  3544 			if (defined($elementSize)) {
       
  3545 				my $addr = $DllSymInfoRef->{dataAddr};
       
  3546 				$addr = hex($addr) if $addr =~ /^0x/i;
       
  3547 				$addr = sprintf("0x%08x", $addr + $index * $scalarSize);
       
  3548 				$line .= "addr $addr ";
       
  3549 			} else {
       
  3550 				$line .= "addr ";
       
  3551 				$line .= $DllSymInfoRef->{dataAddr} . " ";
       
  3552 			}
       
  3553 		}
       
  3554 		else
       
  3555 		{
       
  3556 			print_source_error("Ordinal or Address for exported symbol $symbolname in $romfilename couldn't be located");
       
  3557 			$errors++ if($strict);
       
  3558 			$line = "REM $line\n";
       
  3559 			return $line;
       
  3560 		};
       
  3561 		
       
  3562 		$line .= "$scalarSize $value\n";
       
  3563 
       
  3564 		return $line;
       
  3565 	}
       
  3566 	elsif ($line =~ /^\s*(\S+)\s*(\S+)\s+\\?(\S+)(.*)$/)
       
  3567 	{
       
  3568 		$type = $1;
       
  3569 		$variant = "";
       
  3570 		$pcfile = $2;
       
  3571 		$romfile = $3;
       
  3572 		$tail = $4;
       
  3573 
       
  3574 		if ($type !~ /^(alias)$/i)
       
  3575 		{
       
  3576 			# Return now, if it is not an 'alias'.
       
  3577 			return $line;
       
  3578 		}
       
  3579 		else
       
  3580 		{
       
  3581 			# There is no substitution needed for SysBin 'alias'es.
       
  3582 			if ($romfile =~ /^sys\\bin\\/i
       
  3583 			  ||$romfile =~ /^sys\/bin/i)
       
  3584 			{
       
  3585 				return $line;
       
  3586 			}
       
  3587 		}
       
  3588 	}
       
  3589 	else
       
  3590 	{
       
  3591 		return $line;
       
  3592 	}
       
  3593  	# Buildrom should generate warning when destination path provided for a file 
       
  3594  	# is not a standard path(as per platsec) and "PlatSecEnforceSysBin" is turned off. 
       
  3595  	my $warnFlag = 1;
       
  3596 	my $mustBeSysBin = $enforceSysBin;
       
  3597 	if ($type =~ /^(data|compress|nocompress)$/i
       
  3598 		&& $romfile !~ /^system\\(bin|libs|programs)\\/i)
       
  3599 	{
       
  3600 		$mustBeSysBin = 0;
       
  3601  		$warnFlag = 0;
       
  3602 	}
       
  3603 	
       
  3604 	if ($mustBeSysBin)
       
  3605 	{
       
  3606 		if ($type =~ /^(alias)$/i
       
  3607 			&& $romfile !~ /^sys\\bin\\/i
       
  3608 			&& $romfile !~ /^sys\/bin/i)
       
  3609 		{
       
  3610 			# for multilinguify 'alias'es (generally resource files) 'MustBeSysBin' should not be enforced.
       
  3611 			if($romfile =~ /\.rsc$/i || defined($multiLinguifyAlias{$pcfile})) {
       
  3612 				return $line;  
       
  3613 			}
       
  3614 
       
  3615 			my $filename = "\\$romfile";	# in case no path is specified
       
  3616 			$filename = substr $filename, rindex($filename, "\\");
       
  3617 			$romfile = "sys\\bin".$filename;
       
  3618 
       
  3619 			if ($pcfile !~ /^sys\\bin\\/i
       
  3620 			    && $pcfile !~ /^sys\/bin/i)
       
  3621 			{
       
  3622 				my $pcfilename = "\\$pcfile";	# in case no path is specified
       
  3623 				$pcfilename = substr $pcfilename, rindex($pcfilename, "\\");
       
  3624 				$pcfile = "sys\\bin".$pcfilename;
       
  3625 			}
       
  3626 			return "$type$variant $pcfile \t$romfile$tail\n";
       
  3627 		}
       
  3628 
       
  3629 		if ($romfile !~ /^sys\\bin\\/i
       
  3630 		    && $romfile !~ /^sys\/bin/i)
       
  3631 		{
       
  3632 			my $filename = "\\$romfile";	# in case no path is specified
       
  3633 			$filename = substr $filename, rindex($filename, "\\");
       
  3634 			$romfile = "sys\\bin".$filename;
       
  3635 		}
       
  3636 	}
       
  3637 	else
       
  3638 	{
       
  3639  		if ($warnFlag && $romfile !~ /^sys\\bin\\/i && $romfile !~ /^sys\/bin/i)
       
  3640  		{
       
  3641  			print "Warning: Outside standard path at \"$line\"\n";
       
  3642  		}
       
  3643 		if ($type =~ /^(alias)$/i)
       
  3644 		{
       
  3645 			# Return the line as it is for non-MustBeSysBin 'alias'es.
       
  3646 			return $line;
       
  3647 		}
       
  3648 	}
       
  3649 	$romfiles{$romfile} = $variant.$pcfile;
       
  3650 	$ibyfiles{$romfile} = $sourcefile;
       
  3651 	return "$type$variant=$pcfile \t\"$romfile\"$tail\n";
       
  3652 }
       
  3653 
       
  3654 my @hidearray;
       
  3655 
       
  3656 sub mark
       
  3657 { # function to mark files in ROMs as hidden
       
  3658 	my ($base,$ext) = @_;
       
  3659 	my $i=0;
       
  3660 	my @coreimagerange = (-1,-1); #coreimagerange stores the places within @hidearray where the $base files start and end
       
  3661 	my @extensionimagerange = (-1,-1); #extensionimagerange stores the places within @hidearray where the $ext files start and end
       
  3662 	for(my $i=0;$i<scalar @hidearray;$i++) { #loop sets values in @coreimagerange and in @extensionimagerange
       
  3663 		if($hidearray[$i]{rom}==$base) {
       
  3664 			if($coreimagerange[0]<0) {
       
  3665 				$coreimagerange[0]=$i;
       
  3666 				$coreimagerange[1]=$i;
       
  3667 			} else {
       
  3668 				$coreimagerange[1]=$i;
       
  3669 			}
       
  3670 		} elsif($hidearray[$i]{rom}==$ext) {
       
  3671 			if($extensionimagerange[0]<0) {
       
  3672 				$extensionimagerange[0]=$i;
       
  3673 				$extensionimagerange[1]=$i;
       
  3674 			} else {
       
  3675 				$extensionimagerange[1]=$i;
       
  3676 			}
       
  3677 		}
       
  3678 	}
       
  3679 	
       
  3680 	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
       
  3681 		for(my $j=$coreimagerange[0];$j<=$coreimagerange[1];$j++) {
       
  3682 			if($hidearray[$i]{dest} eq $hidearray[$j]{dest}) {
       
  3683 				$hidearray[$i]{hide}=1;
       
  3684 			}
       
  3685 		}
       
  3686 	}
       
  3687 }
       
  3688 
       
  3689 
       
  3690 #----------------------------------------------------------------------------------
       
  3691 # Cleaning phase
       
  3692 #
       
  3693 # Remove "REM defined", "REM handled"
       
  3694 # Remove the "# lineno" information
       
  3695 # Collapse multiple blank lines
       
  3696 # Apply the PlatSecEnforceSysBin setting
       
  3697 # Produce ROM directory listing
       
  3698 # Identify the ROM image name
       
  3699 sub cleaning_phase
       
  3700 {	
       
  3701 	my $romname;
       
  3702 	my $skippingBlanks=0;
       
  3703 	undef @newobydata;
       
  3704 	
       
  3705     if($opt_v)
       
  3706     {
       
  3707 	  my $logWin = "logwin.oby";
       
  3708 	  my $logLinux = "loglinux.oby";
       
  3709 	  unlink($logWin);
       
  3710 	  unlink($logLinux);
       
  3711 	  open LOGWIN, ">$logWin" or die("* Can't create $logWin\n");
       
  3712 	  open LOGLINUX, ">$logLinux" or die("* Can't create $logLinux\n");
       
  3713     }	
       
  3714 
       
  3715 	foreach $line (@obydata)
       
  3716 	{
       
  3717 		track_source($line);
       
  3718 		if ($line=~/^REM (defined|handled)/)
       
  3719 		{
       
  3720 			next;
       
  3721 		}
       
  3722 		if ($line=~/^# (\d+) "(.*)"/)
       
  3723 		{
       
  3724 			next;
       
  3725 		}
       
  3726 		#
       
  3727 		# Blank line compression
       
  3728 		#
       
  3729 		if ($line=~/^\s*$/)
       
  3730 		{
       
  3731 			if ($skippingBlanks==1)
       
  3732 			{
       
  3733 				next;
       
  3734 			}
       
  3735 			$skippingBlanks=1;
       
  3736 		}
       
  3737 		else
       
  3738 		{
       
  3739 			$skippingBlanks=0;
       
  3740 		}
       
  3741 		#
       
  3742 		# Track ROMNAME, allowing overrides
       
  3743 		#
       
  3744 		if ($line=~/romname\s*=\s*"?(\S+)\.(\S+)"?\s*/i)
       
  3745 		{
       
  3746 			if ($romname ne "" && $opt_o eq "")
       
  3747 			{
       
  3748 				print_source_error("Overrides previous ROM name $romname");
       
  3749 			}
       
  3750 			$rombasename = $1;
       
  3751 			$romname = "$1.$2";
       
  3752 			next;
       
  3753 		}
       
  3754 		#
       
  3755 		# ROM directory listing
       
  3756 		#
       
  3757 		    my $newline = reformat_line($line);
       
  3758 	    if( ($newline !~ /^\s*TIME\s*=\s*/i)
       
  3759   	      &&($newline !~ /^\s*volume\s*=.*/i)
       
  3760 	      &&($newline !~ /^\s*kerneltrace\s*=.*/i))
       
  3761 	    {
       
  3762 	        my $tmpline = $newline;
       
  3763 	        if($^O =~ /^MSWin32$/i)
       
  3764 	        {
       
  3765 	          $newline =~ s-\/-\\-go;
       
  3766 	          if($opt_v)
       
  3767 	          {
       
  3768                 print LOGWIN $newline;
       
  3769 	            $tmpline =~ s-\\-\/-go;
       
  3770 	            print LOGLINUX $tmpline;
       
  3771 	          }
       
  3772 	        }else #unix os
       
  3773 	        {
       
  3774 	          $newline =~ s-\\-\/-go;
       
  3775 	          if($opt_v)
       
  3776 	          {
       
  3777 	            print LOGLINUX $newline;
       
  3778 	            $tmpline =~ s-\/-\\-go;
       
  3779 	            print LOGWIN $tmpline;
       
  3780 	          }
       
  3781 	        }
       
  3782 	    }
       
  3783 	    
       
  3784 		push @newobydata, $newline;
       
  3785 	}
       
  3786 	if($opt_v)
       
  3787 	{
       
  3788 	  close LOGWIN;
       
  3789 	  close LOGLINUX;
       
  3790 	}
       
  3791 	
       
  3792 	exit(1) if($errors && $strict);
       
  3793 
       
  3794 	# Handle ROMNAME and possible -o override
       
  3795 	if ($opt_o ne "")
       
  3796 	{
       
  3797 		$romname=$opt_o;
       
  3798 		if ($opt_o=~/(\S+)\.(\S+)/)
       
  3799 		{
       
  3800 			$rombasename=$1;
       
  3801 		}
       
  3802 		else
       
  3803 		{
       
  3804 			$rombasename=$romname;
       
  3805 		}
       
  3806 	}
       
  3807 	if(!$onlysmrimage)
       
  3808 	{
       
  3809 		unshift @newobydata, "romname=$romname\n";	# first line of final OBY file
       
  3810 	}
       
  3811 	@obydata = @newobydata;
       
  3812 	
       
  3813 	print "* Removing previous image and logs...\n";
       
  3814 	unlink glob("$rombasename.*");
       
  3815 	
       
  3816 	my $obyrecordline;
       
  3817 	if($createspi) {# section added to mark SPI files in core images as hidden (if appropriate) if extension ROMs are being produced
       
  3818 		my $imagenum=0;
       
  3819 		my $count=0;
       
  3820 		foreach my $line (@obydata) { # fill @hidearray with all file= or data= entries from @obydata, recording which image they are in and their target destination
       
  3821 			if($line =~/^\s*(file|data)\s*=\s*(\S+)\s+(\S+)\s*$/gi) {
       
  3822 				$hidearray[$count] = {rom=>$imagenum, type=>$1, dest=>$3};
       
  3823 				$hidearray[$count]{dest} =~s/\"//g;
       
  3824 				$count++;
       
  3825 			} elsif($line =~/^\s*REM\s+ROM_IMAGE\[(\d)\]\s*$/i ) {
       
  3826 				$imagenum=$1;
       
  3827 			}
       
  3828 		}
       
  3829 		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
       
  3830 			if($romimage[$i]{extension}) {
       
  3831 				mark($i-1,$i);
       
  3832 			}
       
  3833 		}
       
  3834 		undef @newobydata;
       
  3835 	
       
  3836 		my $hideflag=0; # is set to 1 if there are files which need to be hidden, determines whether to run next section of code 
       
  3837 		for(my $i=0;$i<scalar @hidearray;$i++) {
       
  3838 			if($hidearray[$i]{hide}==1) {
       
  3839 				$hideflag=1;
       
  3840 			}
       
  3841 		}
       
  3842 	
       
  3843 		my $obeyrom=0;	
       
  3844 		if($hideflag) { #if there exist files which need hiding
       
  3845 			my $i=0;
       
  3846 			my $exitflag=0;
       
  3847 			$obyrecordline=0;
       
  3848 			for(;$obyrecordline<scalar @obydata && !$exitflag;) { # nested for loops produce new obey file in @newobydata, including hide= lines
       
  3849 				print "Line = $obyrecordline $i " . scalar @hidearray . "\n";
       
  3850 				if($i==scalar @hidearray) {
       
  3851 					$exitflag=1;
       
  3852 				}
       
  3853 				for(;$i<scalar @hidearray;$i++) {
       
  3854 					if($hidearray[$i]{hide}==1) {
       
  3855 						my $rom=$hidearray[$i]{rom};
       
  3856 						my $destination=$hidearray[$i]{dest};
       
  3857 						while($obeyrom<$rom && $obyrecordline<scalar @obydata) { #pushes lines to @newobydata until specified rom is reached
       
  3858 							push @newobydata, $obydata[$obyrecordline];
       
  3859 							if($obydata[$obyrecordline] =~/^\s*REM\s+ROM_IMAGE\[(\d)\]\s*$/i){
       
  3860 								$obeyrom=$1;
       
  3861 							}
       
  3862 							$obyrecordline++;
       
  3863 						}
       
  3864 						my $flag=1; #get to here when $obeyrom==$rom
       
  3865 						while($flag && $obyrecordline<scalar @obydata) {
       
  3866 							$destination=~s|\\|/|g;
       
  3867 							my $obyline=$obydata[$obyrecordline];
       
  3868 							$obyline=~s|\\|/|g;			
       
  3869 							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
       
  3870 								push @newobydata, "hide=$hidearray[$i]{dest}\n$obydata[$obyrecordline]";
       
  3871 								$obyrecordline++;
       
  3872 								$flag=0;
       
  3873 							} else {
       
  3874 								push @newobydata, $obydata[$obyrecordline++];
       
  3875 							}
       
  3876 						}
       
  3877 					}
       
  3878 				}
       
  3879 			}		
       
  3880 		}		
       
  3881 		while($obyrecordline< scalar @obydata) { # add the rest of the lines from @obydata to @newobydata
       
  3882 			push @newobydata, $obydata[$obyrecordline++];
       
  3883 		}
       
  3884 		@obydata=@newobydata;
       
  3885 		undef @newobydata;	
       
  3886 	}
       
  3887 	dump_obydata("tmp9.oby", "result of cleaning phase") if ($opt_v);
       
  3888 }
       
  3889 
       
  3890 
       
  3891 #----------------------------------------------------------------------------------
       
  3892 #
       
  3893 # Divide the oby file into multiple sections - one for each rom image - ready
       
  3894 # for the appropriate rom builder.
       
  3895 #
       
  3896 
       
  3897 sub generate_romheader
       
  3898 {
       
  3899 	my ($idx) = @_;
       
  3900 	if ($romimage[$idx]{xip} ne 0)
       
  3901 	{ 
       
  3902 		my $header = "\n";
       
  3903 		if ($romimage[$idx]{extension})
       
  3904 		{
       
  3905 			$header = "extensionrom=$rombasename.$romimage[$idx]{name}.img\n";
       
  3906 			$header .= "romsize=$romimage[$idx]{size}\n\n";
       
  3907 		}
       
  3908 		return $header; 
       
  3909 	}
       
  3910 	# non-xip
       
  3911 	my $header;
       
  3912 	if ($romimage[$idx]{extension})
       
  3913 	{
       
  3914 		$header =  "extensionrofs=$rombasename.$romimage[$idx]{name}.img\n";
       
  3915 		$header .= "rofssize=$romimage[$idx]{size}\n\n";
       
  3916 	}
       
  3917 	else
       
  3918 	{
       
  3919 		$header="rofsname=$rombasename.$romimage[$idx]{name}.img\n";
       
  3920 		$header .= "rofssize=$romimage[$idx]{size}\n\n";
       
  3921 	}
       
  3922 	return $header;
       
  3923 }
       
  3924 
       
  3925 #----------------------------------------------------------------------------------
       
  3926 # Dump OBY file.
       
  3927 #
       
  3928 # Creates final OBY file.
       
  3929 #
       
  3930 sub create_dumpfile
       
  3931 {
       
  3932 	my $romimageidx;
       
  3933 	my $smrimageidx = 0;
       
  3934 	my $dumpfile="$rombasename";
       
  3935 	$romimage[0]{obeyfile}=$dumpfile;
       
  3936 	$dumpfile .= ".oby";
       
  3937 	unlink($dumpfile);
       
  3938 	if($rombasename && !$onlysmrimage)
       
  3939 	{
       
  3940 		open DUMPFILE, ">$dumpfile" or die("* Can't create $dumpfile\n");
       
  3941 		print "* Writing $dumpfile - final OBY file\n";
       
  3942 		$romimageidx=0;
       
  3943 		print DUMPFILE generate_romheader($romimageidx);
       
  3944 	}
       
  3945 	foreach $line (@obydata)
       
  3946 	{
       
  3947 		if ($line =~ /^\s*REM ROM_IMAGE\[(\d+)\]\s+(.*)$/i)
       
  3948 		{
       
  3949 			$romimageidx=$1;
       
  3950 			if ($romimage[$romimageidx]{extension} eq '0')
       
  3951 			{ # next rom oby file
       
  3952 				close DUMPFILE;
       
  3953 				$dumpfile="$rombasename.$romimage[$romimageidx]{name}";
       
  3954 				$romimage[$romimageidx]{obeyfile}=$dumpfile;
       
  3955 				$dumpfile .= ".oby";
       
  3956 				open DUMPFILE, ">$dumpfile" or die("* Can't create $dumpfile\n");		
       
  3957 				print "* Writing $dumpfile - final OBY file\n";
       
  3958 				# header
       
  3959 				print DUMPFILE $line;
       
  3960 				print DUMPFILE generate_romheader($romimageidx);
       
  3961 				next;
       
  3962 			}
       
  3963 			else
       
  3964 			{ # extension
       
  3965 				# header
       
  3966 				print DUMPFILE $line;
       
  3967 				print DUMPFILE generate_romheader($romimageidx);
       
  3968 				next;
       
  3969 			}
       
  3970 		}
       
  3971 		# write data drive oby file.
       
  3972 		elsif ($line =~ /^\s*REM DATA_IMAGE\[(\d+)\]\s+(.*)$/i)
       
  3973 		{
       
  3974 				my $dataimageidx=$1;
       
  3975 				close DUMPFILE;
       
  3976 				$dumpfile="$datadriveimage[$dataimageidx]{name}";
       
  3977 				$datadriveimage[$dataimageidx]{obeyfile}=$dumpfile;
       
  3978 				$dumpfile .= ".oby";
       
  3979 				open DUMPFILE, ">$dumpfile" or die("* Can't create $dumpfile\n");		
       
  3980 				print "* Writing $dumpfile - intermediate OBY file\n";
       
  3981 				# header
       
  3982 				print DUMPFILE $line;
       
  3983 				print DUMPFILE generate_datadriveheader($dataimageidx,\@datadriveimage);
       
  3984 				push(@dataDriveFileList,$dumpfile);
       
  3985 				next;
       
  3986 		}
       
  3987 		elsif ($line =~ /^\s*REM SMR_IMAGE\s*$/i)
       
  3988 		{
       
  3989 			close DUMPFILE;
       
  3990 			$dumpfile = $obeyFileList[$smrimageidx];
       
  3991 			$smrimageidx++;
       
  3992 			$dumpfile .= ".oby";
       
  3993 			open DUMPFILE, ">$dumpfile" or die("* Can't create $dumpfile\n");
       
  3994 			print "*Writing $dumpfile - intermediate OBY file\n";
       
  3995 			print DUMPFILE $line;
       
  3996 			push(@smrImageFileList, $dumpfile);
       
  3997 			next;
       
  3998 		}
       
  3999 		print DUMPFILE $line;
       
  4000 	}
       
  4001 	close DUMPFILE;
       
  4002 }
       
  4003 
       
  4004 #----------------------------------------------------------------------------------
       
  4005 #
       
  4006 # Full ROM directory listing - use case-insensitive sort
       
  4007 #
       
  4008 sub create_dirlisting
       
  4009 {
       
  4010 	if($rombasename)
       
  4011 	{
       
  4012 		print "* Writing $rombasename.dir - ROM directory listing\n";
       
  4013 		open DIRFILE, ">$rombasename.dir" or die("* Can't create ROM directory listing\n");
       
  4014 	
       
  4015 		my $file;
       
  4016 		my $prevdir = "";
       
  4017 		foreach $file (sort {uc($a) cmp uc($b)} keys %romfiles)
       
  4018 		{
       
  4019 			my $dir = substr $file,0,rindex($file, "\\");
       
  4020 			if (uc $dir ne uc $prevdir)
       
  4021 			{
       
  4022 				$prevdir = $dir;
       
  4023 				print DIRFILE "\n";
       
  4024 			}
       
  4025 	
       
  4026 			my @sources = split /\n/,$romfiles{$file};
       
  4027 			my @ibyfiles = split /\n/,$ibyfiles{$file};
       
  4028 			printf DIRFILE "%-40s\t%s\t%s\n", $file, shift @sources, shift @ibyfiles;
       
  4029 			while (@sources)
       
  4030 			{
       
  4031 				printf DIRFILE "%39s+\t%s\t%s\n", "", shift @sources, shift @ibyfiles;
       
  4032 			}
       
  4033 		}
       
  4034 		close DIRFILE;
       
  4035 	}
       
  4036 }
       
  4037 
       
  4038 #----------------------------------------------------------------------------------
       
  4039 #
       
  4040 # Suppress Rom/Rofs/DataDrive Image creation if "-noimage" option is provided.
       
  4041 #
       
  4042 
       
  4043 sub suppress_image_generation
       
  4044 {
       
  4045 	if($noimage) 
       
  4046 	{
       
  4047 		&tidy_exit;		
       
  4048 	}
       
  4049 }
       
  4050 
       
  4051 #----------------------------------------------------------------------------------
       
  4052 # Execute rombuild & maksym for each final XIP OBY file
       
  4053 # Execute rofsbuild for each non-XIP oby file
       
  4054 #
       
  4055 
       
  4056 sub run_rombuilder
       
  4057 {
       
  4058 	my ($command, $obeyfile, $logfile) = @_;
       
  4059 	$command .= " $obeyfile.oby";
       
  4060 	#CR1258 test cases are depending on the following output.
       
  4061 	print "* Executing $command\n" if ($opt_v);
       
  4062 
       
  4063 	open DATA, "$command 2>&1 |"   or die "Couldn't execute command: $command";
       
  4064 	while ( defined( my $line = <DATA> ) ) {
       
  4065 	chomp($line);
       
  4066 	print "$line\n";
       
  4067 	}
       
  4068 	close DATA;
       
  4069 
       
  4070 	if ($? != 0)
       
  4071 	{
       
  4072 		$errors++;
       
  4073 		$command =~ /^\s*(\S+)\s+-slog/;
       
  4074 		print "* $1 failed\n";
       
  4075 	}
       
  4076 	else
       
  4077 	{
       
  4078 		push(@romImages,$obeyfile.".img");
       
  4079 	}
       
  4080 	print "\n";
       
  4081 	rename "$logfile","$obeyfile.log" or die("* Can't rename $logfile\n");
       
  4082 	exit(1) if ($errors);
       
  4083 }
       
  4084 
       
  4085 #----------------------------------------------------------------------------------
       
  4086 # ROMBUILD AND ROFSBUILD
       
  4087 #
       
  4088 # Invokes rombuild and rofsbuild.
       
  4089 # Creates .log, .symbol files.
       
  4090 #
       
  4091 sub invoke_rombuild
       
  4092 {
       
  4093 	#For CR1258, -compress command line option is introduced, and it's being handled as following
       
  4094 	my $rom_compression_type;
       
  4095 	if($opt_compression_type eq ALLSECTIONS)
       
  4096 	{
       
  4097 		$rom_compression_type = "-compress";
       
  4098 	}
       
  4099 	elsif($opt_compression_type eq PAGEDSECTION)
       
  4100 	{
       
  4101 		$rom_compression_type = "-compress=paged";
       
  4102 	}
       
  4103 	elsif($opt_compression_type eq UNPAGEDSECTION)
       
  4104 	{
       
  4105 		$rom_compression_type = "-compress=unpaged";
       
  4106 	}
       
  4107 	else
       
  4108 	{
       
  4109 		$rom_compression_type = "";
       
  4110 	}
       
  4111 	
       
  4112 	my $rombuild;
       
  4113 	if(!$geninc)
       
  4114 	{
       
  4115 		$rombuild = "rombuild -slog $rom_compression_type $logLevel $lowMem $opt_fastcompress $opt_jobs";
       
  4116 	}
       
  4117 	else
       
  4118 	{
       
  4119 		$rombuild = "rombuild -slog $rom_compression_type -geninc $logLevel $lowMem $opt_fastcompress $opt_jobs";
       
  4120 	}
       
  4121 	if($gendep)
       
  4122 	{
       
  4123 		$rombuild .= " -gendep";
       
  4124 	}
       
  4125 	my $rofsbuild = "rofsbuild -slog $logLevel $lowMem $opt_fastcompress $opt_jobs";
       
  4126 	foreach my $arg (keys %rombuildOptions)
       
  4127 	{
       
  4128 		$rombuild .= " $arg";
       
  4129 	}
       
  4130 	        
       
  4131 	for (my $romidx=0; $romidx<8; $romidx++)
       
  4132 	{
       
  4133 		my $obeyfile=$romimage[$romidx]{obeyfile};
       
  4134 		my $xip=$romimage[$romidx]{xip};
       
  4135 		my $compress=$romimage[$romidx]{compress};
       
  4136 		my $uncompress=$romimage[$romidx]{uncompress};
       
  4137 		if ($obeyfile)
       
  4138 		{
       
  4139 			if(!defined $opt_compression)
       
  4140 			{
       
  4141 				if ($compress ne 0)
       
  4142 				{
       
  4143 					$compress=" -compress";
       
  4144 				}
       
  4145 				elsif($uncompress ne 0)
       
  4146 				{
       
  4147 					$compress=" -uncompress";
       
  4148 				}
       
  4149  				elsif($compress eq 0)
       
  4150  				{
       
  4151  					$compress=" ";
       
  4152 				}
       
  4153 			}
       
  4154 			else
       
  4155 			{
       
  4156 				$compress = $opt_compression;
       
  4157 				$compress =~m/\s-(compression)(method)\s(none|inflate|bytepair)/;
       
  4158 				print "* ".$1." ".$2.": ".$3;
       
  4159 			}                        
       
  4160 			if ($xip)
       
  4161 			{
       
  4162 				run_rombuilder($rombuild.$compress, $obeyfile, "ROMBUILD.LOG");
       
  4163 				if(!$nosymbols){
       
  4164 				print "* Writing $obeyfile.symbol - ROM symbol file\n";
       
  4165 				print "* Executing maksym $obeyfile.log $obeyfile.symbol\n" if ($opt_v);
       
  4166 				system("maksym $obeyfile.log $obeyfile.symbol >maksym.out");
       
  4167 				exit(1) if (!-e "$obeyfile.symbol");
       
  4168 				}
       
  4169 			}
       
  4170 			else
       
  4171 			{
       
  4172 				# efficient_rom_paging.pm can move everything to core rom.
       
  4173 				# If that is the case, don't run rofsbuild at all to avoid errors.
       
  4174 				use constant TRUE => 1;
       
  4175 				use constant FALSE => 0;
       
  4176 				my $run_rofs_build = FALSE;
       
  4177 				
       
  4178 				open OBYFILE, "$obeyfile.oby";
       
  4179 				for (<OBYFILE>)
       
  4180 				{
       
  4181 					if (is_oby_statement($_))
       
  4182 					{
       
  4183 						$run_rofs_build = TRUE;
       
  4184 						last;
       
  4185 					}
       
  4186 				}
       
  4187 				close OBYFILE;
       
  4188 				if ($run_rofs_build)
       
  4189 				{
       
  4190 					run_rombuilder($rofsbuild.$compress, $obeyfile, "ROFSBUILD.LOG");
       
  4191 					if(!$nosymbols){
       
  4192 					print "* Writing $obeyfile.symbol - ROFS symbol file\n";
       
  4193 					print "* Executing maksymrofs $obeyfile.log $obeyfile.symbol\n" if ($opt_v);
       
  4194 					system("maksymrofs $obeyfile.log $obeyfile.symbol >maksym.out");
       
  4195 					exit(1) if (!-e "$obeyfile.symbol" );
       
  4196 					}			
       
  4197 				}
       
  4198 			}
       
  4199 			unlink "rombuild.log";
       
  4200 			unlink "maksym.out";
       
  4201 		}
       
  4202 	}
       
  4203 }
       
  4204 
       
  4205 #-------------------------------------------------------
       
  4206 # Subroutine: check if current statement is a valid oby statement
       
  4207 #
       
  4208 sub is_oby_statement
       
  4209 {
       
  4210 	my ($li) = @_;
       
  4211 	if ($li =~ /\s*data\s*=/) { return 1;}
       
  4212 	if ($li =~ /\s*file\s*=/) { return 1;}
       
  4213 	if ($li =~ /\s*dll\s*=/) { return 1;}
       
  4214 	if ($li =~ /\s*secondary\s*=/) { return 1;}
       
  4215 
       
  4216 	return 0;
       
  4217 }
       
  4218 
       
  4219 #-------------------------------------------------------
       
  4220 # Subroutine: convert possibly absolute path into relative path
       
  4221 #
       
  4222 
       
  4223 sub relative_path
       
  4224 {
       
  4225     my ($arg) = @_;
       
  4226     return $arg if ($arg !~ /^\\/);	# not an absolute path
       
  4227     if ($uppath eq "x")
       
  4228 	{
       
  4229 		$uppath=cwd;
       
  4230 		$uppath=~s-/-\\-go;		    # separator from Perl 5.005_02+ is forward slash
       
  4231 		$uppath=~s-^(.*[^\\])$-$1\\-o;	    # ensure path ends with a backslash
       
  4232 		$uppath=~s-\\([^\\]+)-\\..-og;	    # convert directories into ..
       
  4233 		$uppath=~s-^.:\\--o;		    # remove drive letter and leading backslash
       
  4234 	}
       
  4235     $arg=~s-^\\--o;	# remove leading backslash from original path
       
  4236     return "$uppath$arg";
       
  4237 }
       
  4238 
       
  4239 # Returns the global @obydata reference to support external tool invocation.
       
  4240 sub getOBYDataRef{
       
  4241 	return \@obydata;
       
  4242 }
       
  4243 
       
  4244 #Match the blank or the comment
       
  4245 sub isobystatement
       
  4246 {
       
  4247 	my ($l) = @_;
       
  4248 	if ($l !~ /=/) { 
       
  4249 		return 0;
       
  4250 	}
       
  4251 	return 1;
       
  4252 }
       
  4253 
       
  4254 #Match the data statements
       
  4255 sub isdatastatement {
       
  4256 	my ($l) = @_;
       
  4257 	if ($l !~ /data=/) 
       
  4258 	{ 
       
  4259 		return 0;
       
  4260 	}
       
  4261 	return 1;
       
  4262 }
       
  4263 
       
  4264 #Match the spidata statements
       
  4265 sub isspidatastatement {
       
  4266 	my ($l) = @_;
       
  4267 	if ($l !~ /spidata=/) { 
       
  4268 		return 0;
       
  4269 	}
       
  4270 	return 1;
       
  4271 }
       
  4272 
       
  4273 #Match the executable statements
       
  4274 sub isexecutablefile {
       
  4275 	my ($l) = @_;
       
  4276 	if (($l=~/file=/)||($l=~/dll=/)||($l=~/primary=/)||($l=~/secondary=/)||($l=~/variant=/)||($l=~/device=/)||($l=~/extension=/)){ 
       
  4277 		return 1;
       
  4278 	}
       
  4279 	return 0;
       
  4280 }
       
  4281 
       
  4282 #Match the directory metadata statements
       
  4283 sub isdirectorymetadata {
       
  4284 	my ($l) = @_;
       
  4285 	if (($l=~/hide=/) || ($l=~/rename=/) || ($l=~/alias=/)){ 
       
  4286 		return 1;
       
  4287 	}
       
  4288 	return 0;
       
  4289 }
       
  4290 
       
  4291 #Match the bitmap statements
       
  4292 sub isbitmap {
       
  4293 	my ($l) = @_;
       
  4294 	if ($l=~/bitmap=/){ 
       
  4295 		return 1;
       
  4296 	}
       
  4297 	return 0;
       
  4298 }
       
  4299 
       
  4300 
       
  4301 #Match the aif file
       
  4302 sub isaif {
       
  4303 	my ($l) = @_;
       
  4304 	if ($l=~/(.*)\.aif/){ 
       
  4305 		return 1;
       
  4306 	}
       
  4307 	return 0;
       
  4308 }
       
  4309 
       
  4310 
       
  4311 #Match the resource file
       
  4312 sub isresource {
       
  4313 	my ($l) = @_;
       
  4314 	if ($l=~/(.*)\.rsc/){ 
       
  4315 		return 1;
       
  4316 	}
       
  4317 	return 0;
       
  4318 }
       
  4319 
       
  4320 #Returns the executable extensions
       
  4321 sub executableextension {
       
  4322 	my ($l) = @_;
       
  4323 	if ($l=~/file=(.*)\.exe$/){ 
       
  4324 		return "exe";
       
  4325 	}
       
  4326 	elsif ($l=~/file=(.*)\.dll$/){ 
       
  4327 		return "dll";
       
  4328 	}
       
  4329 	elsif ($l=~/file=(.*)\.ldd$/){ 
       
  4330 		return "ldd";
       
  4331 	}
       
  4332 	elsif ($l=~/file=(.*)\.fsy$/){ 
       
  4333 		return "fsy";
       
  4334 	}
       
  4335 }
       
  4336 
       
  4337 
       
  4338 #Returns all 3 UIDS
       
  4339 sub executabletype {
       
  4340 	my ($l) = @_;
       
  4341 	my $uid1;
       
  4342 	my $uid2;
       
  4343 	my $uid3;
       
  4344 	if ($l=~/uid1\s(0x[\d]*)/){ 
       
  4345 		$uid1=$1;
       
  4346 	}
       
  4347 	if ($l=~/uid2\s(0x[\d]*)/){ 
       
  4348 		$uid2=$1;
       
  4349 	}
       
  4350 	if ($l=~/uid3\s(0x[\d]*)/){ 
       
  4351 		$uid3=$1;
       
  4352 	}
       
  4353 	
       
  4354 	return $uid1." ".$uid2." ".$uid3."\n";
       
  4355 }
       
  4356 
       
  4357 
       
  4358 #Return source file name
       
  4359 sub getSourceFile {
       
  4360 	my ($line) = shift;
       
  4361 	if ($line=~/(\w*=)(\S*\s+\S*)\s+(\S*)\s+(\S*)?/) {
       
  4362 		return $2;
       
  4363 	}
       
  4364 }
       
  4365 
       
  4366 #Return destination file name
       
  4367 sub getDestFile{
       
  4368 	my ($line) = shift;
       
  4369 	if ($line=~/(\w*=)(\S*\s+\S*)\s+(\S*)\s+(\S*)?/) {
       
  4370 		return $3;
       
  4371 	}
       
  4372 }
       
  4373 
       
  4374 #Return the obycommand attributes
       
  4375 sub getOBYAttributes{
       
  4376 	my ($line) = shift;
       
  4377 	if ($line=~/(\w*=)(\S*\s+\S*)\s+(\S*)\s+(\S*)?/) {
       
  4378 		return $4;
       
  4379 	}
       
  4380 }
       
  4381 
       
  4382 #Return the hardware variant delimiter
       
  4383 sub getHardwareVariant{
       
  4384 	my ($line) = shift;
       
  4385 	if ($line=~/(\w*[0x[\d]*]=)/) {
       
  4386 		return $1;
       
  4387 	}
       
  4388 }
       
  4389 
       
  4390 #Return the hardware variant delimiter
       
  4391 sub getObyCommand{
       
  4392 	my ($line) = shift;
       
  4393 	if ($line=~/^[data=]/) {
       
  4394 		return "data";
       
  4395 	}
       
  4396 
       
  4397 	if ($line=~/^[file=]/) {
       
  4398 		return "file";
       
  4399 	}
       
  4400 
       
  4401 	if ($line=~/^[dll=]/) {
       
  4402 		return "dll";
       
  4403 	}
       
  4404 }
       
  4405 
       
  4406 # Initialize the symbol info within the given DLL.
       
  4407 sub AddDllDataInfo
       
  4408 {
       
  4409 	my ($line) = @_;
       
  4410 	# syntax "<DLLname>@<symbolname> <newvalue>"
       
  4411 	if($line =~ /^\s*(\S+)\s*\@\s*(\S+)\s+(\S+)\s*$/)
       
  4412 	{
       
  4413 		my $dllName = lc ($1);
       
  4414 		my $symbolname = $2;
       
  4415 		my $intVal = $3;
       
  4416 		my $newVal = 0;
       
  4417 		if($intVal =~ /^0x([0-9a-fA-F]+)$/){
       
  4418 		$newVal = hex($1);
       
  4419 		}
       
  4420 		elsif($intVal =~ /^(-\d+)$/ or $intVal =~ /^(\d+)$/){		
       
  4421 			$newVal = $1;
       
  4422 		}
       
  4423 		else{
       
  4424  			print "ERROR: Invalid patchable value at \"$line\"\n";
       
  4425  			$errors++ if($strict);
       
  4426  			return 1;
       
  4427 		}
       
  4428 		$symbolname =~ s/:(\d+)\[(0x)?[0-9a-f]+\]$//i;	# Remove array element specification (:ELEMENT_BIT_SIZE[INDEX]) to get symbol name
       
  4429 
       
  4430 		my $DllMapRef = \%{$DllDataMap{$dllName}};
       
  4431 
       
  4432 		my %DllSymInfo = ();
       
  4433 		$DllSymInfo{ordinal}	= undef;
       
  4434 		$DllSymInfo{dataAddr}	= undef;
       
  4435 		$DllSymInfo{size}		= undef;
       
  4436 		# We don't store the value here, since patchdata can be used on an array,
       
  4437 		# in which case we'll create another one of these, and lose the value.
       
  4438 		# Instead, the value is retrieved by re-parsing the command line later.
       
  4439 		$DllSymInfo{lineno}		= $sourceline;
       
  4440 		$DllSymInfo{obyfilename}= $sourcefile;
       
  4441 
       
  4442 		$DllMapRef->{$symbolname} = \%DllSymInfo;
       
  4443 		return 0;
       
  4444 	}
       
  4445 		return 1;
       
  4446 }
       
  4447 
       
  4448 sub process_dlldata
       
  4449 {
       
  4450 	if(!$patchDataStmtFlag){
       
  4451 		return;
       
  4452 	}
       
  4453 	my $symbolTblEntry;
       
  4454 
       
  4455 	foreach my $dll (keys %DllDataMap){
       
  4456 		my $DllMapRef = $DllDataMap{$dll};
       
  4457 		if(!$DllMapRef->{srcfile}){
       
  4458 		next;
       
  4459 		}
       
  4460 		my $aDllFile = $DllMapRef->{srcfile};
       
  4461 		my $SymbolCount = scalar ( keys %{$DllMapRef}) - 2; #The map has 'srcfile' and 'dstpath' special keys besides the symbols.
       
  4462 
       
  4463 		my $DllSymMapRef;
       
  4464 
       
  4465 		my @BPABIPlats = &BPABIutl_Plat_List;
       
  4466 		my $matchedSymbols = 0;
       
  4467 		my $globalSyms = 0;
       
  4468 		my @platlist = &Plat_List();
       
  4469 		my $platName;
       
  4470 		my $rootPlatName;
       
  4471 		my $plat = "ARMV5";				
       
  4472 		$plat = &Variant_GetMacro() ? $plat."_ABIV1" : $plat."_ABIV2";		
       
  4473 
       
  4474 		foreach my $plat(@platlist) 
       
  4475 		{
       
  4476 			if(($aDllFile =~ /\\($plat)\\/i) or ($aDllFile =~ /\\($plat\.\w+)\\/i ))
       
  4477 			{
       
  4478 				$platName = $1;
       
  4479 				last;
       
  4480 			}
       
  4481 		}		
       
  4482 		$rootPlatName =	&Plat_Customizes($platName) ? &Plat_Root($platName) : $platName;
       
  4483 		
       
  4484 		# Map files will be referred for all ARM platforms, 
       
  4485 		# and for BSF platforms which cutomizes ARM platforms.
       
  4486 		if($rootPlatName =~ /^ARMV5|$plat$/i){
       
  4487 			my $mapfile = "${aDllFile}.map";
       
  4488 			
       
  4489 			open MAPFILE, "$mapfile" or die "Can't open $mapfile\n";
       
  4490 			while(<MAPFILE>){
       
  4491 			my $line = $_;
       
  4492 
       
  4493 				#Ignore Local symbols.
       
  4494 				if(!$globalSyms){
       
  4495 					if($line =~ /Global Symbols/){
       
  4496 						$globalSyms = 1;
       
  4497 						next;
       
  4498 					}
       
  4499 					else{
       
  4500 						next;
       
  4501 					}
       
  4502 				}
       
  4503 
       
  4504 				$symbolTblEntry = $line;
       
  4505 				if($symbolTblEntry =~ /\s*(\S+)(?:\s+\(EXPORTED\))?\s+(\S+)\s+(\S+)\s+(\S+)\s+(.*)/){
       
  4506 					my $symbol		= $1;
       
  4507 					my $symbolValue = $2;
       
  4508 					my $data		= $3;
       
  4509 					my $symbolSz	= $4;
       
  4510 					if(!exists $DllMapRef->{$symbol}){
       
  4511 						next;
       
  4512 					}
       
  4513 					$DllSymMapRef = $DllMapRef->{$symbol};
       
  4514 					if($data =~ /Data/){
       
  4515 					# Valid
       
  4516 					}
       
  4517 					else {
       
  4518 					#	Invalid to patch a code symbol.
       
  4519 						print( "$DllSymMapRef->{obyfilename}($DllSymMapRef->{lineno}): Warning: $symbol is not a data Symbol.Ignoring patch statement.\n");
       
  4520 						$errors++ if($strict);
       
  4521 						$DllMapRef->{$symbol} = undef;
       
  4522 						next;
       
  4523 					}
       
  4524 
       
  4525 					
       
  4526 					# Record the address and the size of the symbol.
       
  4527 					$DllSymMapRef->{dataAddr} = $symbolValue;
       
  4528 					$DllSymMapRef->{size} = $symbolSz;
       
  4529 
       
  4530 					$matchedSymbols++;
       
  4531 					if( $matchedSymbols >= $SymbolCount){
       
  4532 						last;
       
  4533 					}
       
  4534 				}
       
  4535 			}
       
  4536 			close MAPFILE;
       
  4537 		}
       
  4538 		# DSO files will be referred for BPABI platforms(excluding ARM platforms),
       
  4539 		# and for BSF platforms which cutomizes BPABI platforms.
       
  4540 		else {
       
  4541 			my $abiDir = undef;
       
  4542 			foreach my $bpabi (@BPABIPlats){
       
  4543 				if($rootPlatName =~ /^$bpabi$/i){
       
  4544 					$abiDir = $platName;
       
  4545 					last;
       
  4546 				}
       
  4547 			}
       
  4548 
       
  4549 			if(!defined $abiDir){
       
  4550 				print("Can't locate the map or proxy dso file for $aDllFile\n");
       
  4551 				$errors++ if($strict);
       
  4552 				next; #go to the next patch dll data statement
       
  4553 			}
       
  4554 			if( $aDllFile =~ /(.*)\.[^.]+$/ ){
       
  4555 				my $proxydsofile = "$1.dso";
       
  4556 				$proxydsofile =~ s/$abiDir\\(.*)\\/ARMV5\\LIB\\/ig;
       
  4557 				open PIPE, "getexports -d $proxydsofile|" or die "Can't open file $proxydsofile\n";
       
  4558 				while (<PIPE>){
       
  4559 					my $line = $_;
       
  4560 					if($line =~ /\s*(\S+)\s+(\d+)\s+((\S+)\s+(\d+))?/){
       
  4561 						my $symbol = $1;
       
  4562 						my $ordinal = $2;
       
  4563 						my $data = $3;
       
  4564 						my $symbolSz = $5;
       
  4565 
       
  4566 						if(!$data){
       
  4567 							next;
       
  4568 						}
       
  4569 						if(!exists $DllMapRef->{$symbol}){
       
  4570 							next;
       
  4571 						}
       
  4572 
       
  4573 						$DllSymMapRef = $DllMapRef->{$symbol};
       
  4574 
       
  4575 						# Record the ordinal and the size of the symbol.
       
  4576 						$DllSymMapRef->{ordinal} = $ordinal;
       
  4577 						$DllSymMapRef->{size} = $symbolSz;
       
  4578 						$matchedSymbols++;
       
  4579 						if( $matchedSymbols >= $SymbolCount){
       
  4580 						last;
       
  4581 						}
       
  4582 					}
       
  4583 				}
       
  4584 
       
  4585 				close PIPE;
       
  4586 			}
       
  4587 		}
       
  4588 	}
       
  4589 	exit(1) if ($errors && $strict ) ;
       
  4590 }
       
  4591 
       
  4592 # make sure that all the absolute feature variant paths include a
       
  4593 # drive letter. This is required because cpp will not work with
       
  4594 # absolute paths starting with slashes.
       
  4595 sub addDrivesToFeatureVariantPaths
       
  4596 {
       
  4597 	return unless $featureVariant{'VALID'};
       
  4598 
       
  4599 	my $current = cwd();
       
  4600 	my $drive = $1 if ($current =~ /^(.:)/);
       
  4601 
       
  4602 	# pre-include file
       
  4603 	my $HRH = $featureVariant{'VARIANT_HRH'};
       
  4604 	$featureVariant{'VARIANT_HRH'} = $drive . $HRH if ($HRH =~ /^[\\\/]/);
       
  4605 
       
  4606 	# ROM include path
       
  4607 	my $dirRef = $featureVariant{'ROM_INCLUDES'};
       
  4608 	return unless $dirRef;
       
  4609 	my $i = 0;
       
  4610 
       
  4611 	foreach my $dir (@$dirRef)
       
  4612 	{
       
  4613 		$$dirRef[$i] = $drive . $dir if ($dir =~ /^[\\\/]/);
       
  4614 		$i++;
       
  4615 	}
       
  4616 }
       
  4617 sub create_smrimage
       
  4618 {
       
  4619 	if($needSmrImage)
       
  4620 	{
       
  4621 		foreach my $oby (@obeyFileList)
       
  4622 		{
       
  4623 			my $command = "rofsbuild -slog -smr=$oby.oby";
       
  4624 			print "* Executing $command\n" if($opt_v);
       
  4625 			system($command);
       
  4626 			if($? != 0)
       
  4627 			{
       
  4628 				print("* ROFSBUILD failed to generate SMR IMAGE\n") if($opt_v);
       
  4629 			}
       
  4630 			else
       
  4631 			{
       
  4632 				push(@smrImageFileList, $oby.".img");
       
  4633 			}
       
  4634 		}
       
  4635 	}
       
  4636 	if(@smrImageFileList)
       
  4637 	{
       
  4638 		print "\n";
       
  4639 		print "-------------------------------------------------------\n";
       
  4640 		print "| List of file(s) generated pertaining to SMR image |\n";
       
  4641 		print "-------------------------------------------------------\n";
       
  4642 		my $arraySize = scalar(@smrImageFileList);
       
  4643 		for(my $i=0; $i < $arraySize; $i++)
       
  4644 		{
       
  4645 			my $element = shift(@smrImageFileList);
       
  4646 			my $size = -s $element;
       
  4647 			print "Size = ".$size." bytes"."\t"."File = ".$element."\n";
       
  4648 		}
       
  4649 	}
       
  4650 	foreach my $errSmr (keys(%smrNameInfo))
       
  4651 	{
       
  4652 		if($smrNameInfo{$errSmr} > 1)
       
  4653 		{
       
  4654 			print "\n SMR image: $errSmr.img creating error for duplicated names!\n";
       
  4655 		}
       
  4656 	}
       
  4657 	if($smrNoImageName)
       
  4658 	{
       
  4659 		print "\n SMR image creating error for empty image name!\n";
       
  4660 	}
       
  4661 }
       
  4662 
       
  4663 1;