imgtools/buildrom/tools/ImageContentHandler.pm
changeset 0 044383f39525
child 590 360bd6b35136
equal deleted inserted replaced
-1:000000000000 0:044383f39525
       
     1 #
       
     2 # Copyright (c) 1997-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 #
       
    16 
       
    17 # This package processes the Image Content XML, and creates an OBY file to create a Rom image.
       
    18 package ImageContentHandler;
       
    19 
       
    20 
       
    21 require Exporter;
       
    22 @ISA=qw(Exporter);
       
    23 @EXPORT=qw(
       
    24 	ParseImageContentXML
       
    25 	ProcessImageContent
       
    26 	AddBinary
       
    27 	GetBldRomOpts
       
    28 	SetBldRomOpts
       
    29 	GenObyFile
       
    30 	GetObyFiles
       
    31 	AddBinaryFromOby
       
    32 	UpdateObyBinaryStaticDep
       
    33 	PrintMsg
       
    34 	DumpBinaries
       
    35 );
       
    36 
       
    37 use strict;
       
    38 use genericparser;
       
    39 use cdfparser;
       
    40 use Dep_Lister;
       
    41 
       
    42 #Error list
       
    43 my @errors;
       
    44 
       
    45 my %ImageContent=();		#Image details are stored in this tree
       
    46 my $RootNode;				#The root node of the XML root document element
       
    47 my @TargetImageList;		#The list of target element nodes in the XML. These are ordered based on their 
       
    48 							#  imageid (if it is a number, else, based on the availibility of Rom locations within 0..7).
       
    49 my @binarySelectionArray;	#This array stores the ABI directories to be looked up to select binaries.
       
    50 my @ImageContentBinaries;	#This list is for the biaries mentioned in Image content XML for 
       
    51 							#  keywords like, 'primary', 'secondary', 'device', 'extension', 'variant'.
       
    52 
       
    53 # List that contains information of binary from OBY file. This list is maintained to check if their static dependencies
       
    54 #	have been included already in Rom.
       
    55 my %obyFileInfo=();
       
    56 
       
    57 my $ImageIndex=-1;
       
    58 
       
    59 my @Includes;		#List of included features. The included feature in this list is a hash table giving the 
       
    60 					#Uid or the name. These features are collected either from the Image content or the CDF XMLs.
       
    61 my @Excludes;		#List of excluded features.The excluded feature in this list is a hash table giving the 
       
    62 					#Uid or the name. These features are collected either from the Image content or the CDF XMLs.
       
    63 
       
    64 my %DefaultDirs =();#This hash table records the default ABI and the BUILD directories. These are updated in case
       
    65 					#  the overriding buildrom options are provided e.g., -D_FULL_DEBUG or -D_PLAT=GCCE etc.
       
    66 
       
    67 my @BPABIPlats = &BPABIutl::BPABIutl_Plat_List; # Add the BPABI Platforms to be added
       
    68 
       
    69 my $isEcomPlugin=0; # This flag will be set when PLUGINs are provided in the CDF file.
       
    70 
       
    71 sub ParseImageContentXML
       
    72 {
       
    73 	my $XMLFile = shift;
       
    74 
       
    75 	$XMLFile =~ s/\\/\//g;
       
    76 	$RootNode = &getRootElement($XMLFile);
       
    77 
       
    78 	&SetImageDetails(\%ImageContent, $RootNode);
       
    79 }
       
    80 
       
    81 
       
    82 my @padding;
       
    83 #This subroutine traverses the XML tree and stores the fields in the hast table %ImageContent. The keys
       
    84 #	are the branch names. For target nodes., it stores the nodes themselves in the hash table and doesn't
       
    85 #	go deeper. These nodes are processed laster. For the other nodes, it keeps traversing recursively.
       
    86 # There are some special keys used to store the nodes and values in the tree. While storing an XML::DOM
       
    87 #  node, it sores with the keys 'nodes', while, for storing a value, it is stored with the key 'vals'.
       
    88 # These are the keys used to retrieve the contents of the tree while generating the final OBY.
       
    89 sub SetImageDetails
       
    90 {
       
    91 	my ($ImageDetailRef, $ImageNode) = @_;
       
    92 	my @children = &genericparser::getChildElements($ImageNode);
       
    93 	my $child;
       
    94 	my $TreeRef;
       
    95 	my $branch;
       
    96 	my $parentName = &genericparser::getElementName($ImageNode);
       
    97 	my $childCnt = scalar @children;
       
    98 
       
    99 	my ($indent) = join('', @padding);
       
   100 
       
   101 	my $val = &genericparser::getElementValue($ImageNode);
       
   102 	$val = Trim($val);
       
   103 	if($val ne "")
       
   104 	{
       
   105 		push @{$ImageDetailRef->{vals}}, $val;
       
   106 	}
       
   107 
       
   108 	my $NodeRef;
       
   109 	foreach $child (@children)
       
   110 	{
       
   111 		$branch = &genericparser::getElementName($child);
       
   112 
       
   113 		$NodeRef = \%{$ImageDetailRef->{$branch}};
       
   114 
       
   115 		if($branch eq "cdf" and $parentName eq "romscope")
       
   116 		{
       
   117 #			Record the romscope node. This node indicates the oby files or cdf files/directories
       
   118 #			that may be used.
       
   119 			push @{$NodeRef->{nodes}}, $child;
       
   120 			next;
       
   121 		}
       
   122 		if($branch eq "target" and $parentName eq "romtarget")
       
   123 		{
       
   124 			push @{$NodeRef->{nodes}}, $child;
       
   125 			next;
       
   126 		}
       
   127 		if( ($branch =~ /primary/i  ) ||
       
   128 			($branch =~ /secondary/i) ||
       
   129 			($branch =~ /extension/i) ||
       
   130 			($branch =~ /variant/i  ) ||
       
   131 			($branch =~ /device/i   ) )
       
   132 		{
       
   133 			next;
       
   134 		}
       
   135 		
       
   136 		if( $child->hasChildNodes() )
       
   137 		{
       
   138 			$NodeRef->{hasChildren} = 1;
       
   139 			push @padding, ".";
       
   140 			SetImageDetails($NodeRef, $child);
       
   141 		}
       
   142 		else
       
   143 		{
       
   144 			$NodeRef->{hasChildren} = 0;
       
   145 		}
       
   146 
       
   147 #		Get all attributes...
       
   148 		my $attribs = &genericparser::getNodeAttributes($child);
       
   149 		my $attrib;
       
   150 
       
   151 		my $nodeName;
       
   152 		my $nodeVal;
       
   153 		my %attr=();
       
   154 		my $attrLen = $attribs->getLength;
       
   155 		for (my $pos = 0; $pos < $attrLen;$pos++)
       
   156 		{
       
   157 			$attrib = $attribs->item($pos);
       
   158 			if(!$attrib)
       
   159 			{
       
   160 				next;
       
   161 			}
       
   162 			$nodeName = lc ($attrib->getName);
       
   163 			$nodeVal = lc  ($attrib->getValue);
       
   164 			$attr{$nodeName}=$nodeVal;
       
   165 
       
   166 		}
       
   167 		push @{$NodeRef->{vals}}, \%attr;
       
   168 	}
       
   169 
       
   170 	pop @padding;
       
   171 }
       
   172 
       
   173 my @romGeometry;			#Array to store all Roms mentioned in RomGeometry
       
   174 my %romGeometryHash = ();	#This Hash table records the indices in @romGeometry array, keying on their Ids.
       
   175 
       
   176 my $curRomImageIndex;		#This scalar records the current Rom image being processed. An binary encountered
       
   177 							#  becomes part of the Rom image corresponding to this partition.
       
   178 
       
   179 # This subroutine associates the RomGeometry and the RomTarget sub-trees to set indices for the Rom-target
       
   180 #   nodes.It stores the Image content XML entries for primary/secondary/device/extension/variant keywords.
       
   181 #   It also stores the features that are included/excluded in Image content XML.
       
   182 
       
   183 sub ProcessImageContent
       
   184 {
       
   185 	my $TotalImages = &ProcessRomGeometry();
       
   186 
       
   187 	my @trgList;
       
   188 	if( defined @{$ImageContent{romtarget}{target}{nodes}})
       
   189 	{
       
   190 		@trgList = @{$ImageContent{romtarget}{target}{nodes}};
       
   191 	}
       
   192 
       
   193 #	Go through the romgeometry to find the location of each image. The valid IDs are 0 through 7.
       
   194 
       
   195 	foreach my $trg (@trgList)
       
   196 	{
       
   197 #		The ID field in romgeometry can be an integer in the range 0 through 7.
       
   198 #		If it is not a number, its location is assumed as its sequence number
       
   199 		my $imageid = &genericparser::getAttrValue($trg, "imageid");
       
   200 		if($imageid =~ /Any/i)
       
   201 		{
       
   202 			next;
       
   203 		}
       
   204 		elsif(exists $romGeometryHash{$imageid})
       
   205 		{
       
   206 			$ImageIndex = $romGeometryHash{$imageid};
       
   207 			push @{$TargetImageList[$ImageIndex]} , $trg;
       
   208 		}
       
   209 	}
       
   210 
       
   211 #	Romscope - update the maps if the files and directories are mentioned.
       
   212 	my @romScopeNodes;
       
   213 	if(defined @{$ImageContent{romscope}{cdf}{nodes}})
       
   214 	{
       
   215 		@romScopeNodes = @{$ImageContent{romscope}{cdf}{nodes}};
       
   216 	}
       
   217 
       
   218 	my $type;
       
   219 	my $file;
       
   220 	my $dir;
       
   221 	foreach my $aNode (@romScopeNodes)
       
   222 	{
       
   223 		$type = &genericparser::getAttrValue($aNode, "type");
       
   224 		if( $type =~ /dir/i)
       
   225 		{
       
   226 			$dir = &genericparser::getElementValue($aNode);
       
   227 			&cdfparser::CreateCDFFileBinaryMapFromDir($dir);
       
   228 		}
       
   229 		elsif($type =~ /file/i)
       
   230 		{
       
   231 			$file = &genericparser::getElementValue($aNode);
       
   232 			&cdfparser::CreateCDFFileBinaryMap($file);
       
   233 		}
       
   234 	}
       
   235 
       
   236 	my $availablePos = 0;
       
   237 	foreach my $trg (@trgList)
       
   238 	{
       
   239 		if(&genericparser::getAttrValue($trg, "imageid") =~ /Any/i)
       
   240 		{
       
   241 			while($availablePos < $TotalImages)
       
   242 			{
       
   243 				if( !defined($TargetImageList[$availablePos][0]) )
       
   244 				{
       
   245 					push @{$TargetImageList[$availablePos]}, $trg;
       
   246 					last;
       
   247 				}
       
   248 				$availablePos++;
       
   249 			}
       
   250 		}
       
   251 	}
       
   252 
       
   253 	my $pos = 0;
       
   254 	while( $pos < 8)
       
   255 	{
       
   256 		if( defined $TargetImageList[$pos][0] )
       
   257 		{
       
   258 #			Record the current Rom image index so that the binaries are included in the corresponding
       
   259 #			Rom image.
       
   260 #			The romGeometry and TargetImageList arrays are associated both being indexed on
       
   261 #			the Rom-image index.
       
   262 
       
   263 			$curRomImageIndex = $pos;
       
   264 			&ProcessTarget($pos, \@{$TargetImageList[$pos]});
       
   265 		}
       
   266 		$pos++;
       
   267 	}
       
   268 
       
   269 #	Pick the primary/secondary/device binaries
       
   270 	my @nodes = &genericparser::getNodeFromTree($RootNode, "options", "primary", "file");
       
   271 	if( defined @nodes)
       
   272 	{
       
   273 		&SaveImageContentBinaries(\@nodes, "primary");
       
   274 	}
       
   275 
       
   276 	@nodes = &genericparser::getNodeFromTree($RootNode, "options", "secondary", "file");
       
   277 	if( defined @nodes)
       
   278 	{
       
   279 		&SaveImageContentBinaries(\@nodes, "secondary");
       
   280 	}
       
   281 
       
   282 	@nodes = &genericparser::getNodeFromTree($RootNode, "options", "extension", "file");
       
   283 	if( defined @nodes)
       
   284 	{
       
   285 		&SaveImageContentBinaries(\@nodes, "extension");
       
   286 	}
       
   287 
       
   288 	@nodes = &genericparser::getNodeFromTree($RootNode, "options", "variant", "file");
       
   289 	if( defined @nodes)
       
   290 	{
       
   291 		&SaveImageContentBinaries(\@nodes, "variant");
       
   292 	}
       
   293 
       
   294 	@nodes = &genericparser::getNodeFromTree($RootNode, "options", "device", "file");
       
   295 	if( defined @nodes)
       
   296 	{
       
   297 		&SaveImageContentBinaries(\@nodes, "device");
       
   298 	}
       
   299 
       
   300 	foreach my $imgBin (@ImageContentBinaries)
       
   301 	{
       
   302 		&ProcessStaticDep($imgBin->{source});
       
   303 	}
       
   304 
       
   305 #	Pick the binary selection order
       
   306 	if (exists($ImageContent{options}{binaryselectionorder}{vals}))
       
   307 	{
       
   308 	    my ($abiDirs) = @{$ImageContent{options}{binaryselectionorder}{vals}};
       
   309 	    @binarySelectionArray = split(',', $abiDirs);
       
   310 	    @binarySelectionArray = Trim(@binarySelectionArray);
       
   311 
       
   312 	}
       
   313 
       
   314 	my $featureList = &cdfparser::GetIncludedFeatureList();
       
   315 	foreach my $feature (@$featureList)
       
   316 	{
       
   317 		push @Includes, $feature;
       
   318 	}
       
   319 
       
   320 	$featureList = &cdfparser::GetExcludedFeatureList();
       
   321 	foreach my $feature (@$featureList)
       
   322 	{
       
   323 		push @Excludes, $feature;
       
   324 	}
       
   325 }
       
   326 
       
   327 #Arrange the Rom-geometry according to their Id when they are numbers. The named images
       
   328 #are arranged starting from the empty slots in Rom geometry array.
       
   329 sub ProcessRomGeometry
       
   330 {
       
   331 	my $RomImageCount = 0;
       
   332 	my $pos = 0;
       
   333 	while($pos < 8)
       
   334 	{
       
   335 		$romGeometry[$pos++] = undef;
       
   336 	}
       
   337 
       
   338 	my @roms = @{$ImageContent{romgeometry}{image}{vals}};
       
   339 	$RomImageCount = scalar (@roms);
       
   340 	my @namedImages;
       
   341 
       
   342 #	Visit all images and allocate them the indices they mention.
       
   343 	foreach my $img (@roms)
       
   344 	{
       
   345 		if($img->{id} =~ /(\d+)/)
       
   346 		{
       
   347 			$pos = $1;
       
   348 			if( defined($romGeometry[$pos]) )
       
   349 			{
       
   350 				print "Error: $romGeometry[$pos]->{id} and $img->{id} cant be allocated the same position\n";
       
   351 				exit;
       
   352 			}
       
   353 			$romGeometry[$pos] = $img;
       
   354 
       
   355 #			Record the index of this Rom
       
   356 			$romGeometryHash{$img->{id}} = $pos;
       
   357 		}
       
   358 		else
       
   359 		{
       
   360 #			These are the named images that are allocated there positions sequentially starting from
       
   361 #			the first available empty position
       
   362 			push @namedImages, $img;
       
   363 		}
       
   364 	}
       
   365 
       
   366 #	Revisit the images and allocate the remaining (unallocated) positions.
       
   367 
       
   368 	$pos = 0;
       
   369 	my $namedImageCount = scalar (@namedImages);
       
   370 	my $firstNamedImgIdx = 0;
       
   371 	my $img;
       
   372 	while(	($pos < 8) and ($namedImageCount > 0) )
       
   373 	{
       
   374 		if( $romGeometry[$pos] )
       
   375 		{
       
   376 #			skip the positions already allocated.
       
   377 			$pos++;
       
   378 			next;
       
   379 		}
       
   380 		$img = $namedImages[$firstNamedImgIdx];
       
   381 		$romGeometry[$pos] = $img;
       
   382 
       
   383 #		Record the index of this Rom
       
   384 		$romGeometryHash{$img->{id}} = $pos;
       
   385 		
       
   386 		$pos++;$firstNamedImgIdx++;
       
   387 		$namedImageCount--;
       
   388 	}
       
   389 
       
   390 	return $RomImageCount;
       
   391 }
       
   392 
       
   393 my @ObyFileList;
       
   394 
       
   395 #This subrouting processes the target nodes that may include OBYs/CDFs or features. For CDFs, the satic/dynamic
       
   396 #  dependencies are evaluated.
       
   397 
       
   398 sub ProcessTarget
       
   399 {
       
   400 	my ($ImgPos , $trgNodesRef) = @_;
       
   401 	my @cdfFileList;
       
   402 
       
   403 #	For all the 'target' nodes associated with an image in romgeometry at the given index...
       
   404 #	The link between a target and an image in romGeometry is the image id. If the imageid
       
   405 #	of a target is 'Any', then the first available image in romGeometry is allocated to
       
   406 #	that target.
       
   407 
       
   408 	foreach my $target (@$trgNodesRef)
       
   409 	{
       
   410 
       
   411 #		Fetch any cdfs included within the Image Content file
       
   412 		my @cdfs = &getNodeFromTree($target, "include","cdf");
       
   413 
       
   414 		my $type;
       
   415 		my $file;
       
   416 		my $dir;
       
   417 		foreach my $cdfNode (@cdfs)
       
   418 		{
       
   419 			$type = &genericparser::getAttrValue($cdfNode, "type");
       
   420 			
       
   421 			if( !($type) || ($type eq "file") )
       
   422 			{
       
   423 				$file = &genericparser::getElementValue($cdfNode);
       
   424 				push @cdfFileList, $file;
       
   425 			}
       
   426 			elsif($type eq "dir")
       
   427 			{
       
   428 				$dir = &genericparser::getElementValue($cdfNode);
       
   429 				&cdfparser::CreateCDFFileBinaryMapFromDir($dir);
       
   430 			}
       
   431 		}
       
   432 
       
   433 #		Collect all the obey files mentioned in this 'target' node.
       
   434 		my @obys = &getNodeFromTree($target, "include","obyFile");
       
   435 		foreach my $obyNode (@obys)
       
   436 		{
       
   437 			$file = &genericparser::getElementValue($obyNode);
       
   438 			push @ObyFileList, $file;
       
   439 		}
       
   440 
       
   441 		&CollectFeatures($target, 1, \@Includes);
       
   442 		&CollectFeatures($target, 0, \@Excludes);
       
   443 	}
       
   444 
       
   445 	ProcessCDFList(\@cdfFileList);
       
   446 }
       
   447 
       
   448 # This subroutine updates the include or exclude feature list collected from Image content XML.
       
   449 sub CollectFeatures
       
   450 {
       
   451 #	Collect all the features included/excluded in this 'target' node.
       
   452 
       
   453 	my ($target, $Inc, $IncludeExcludeListRef) = @_;
       
   454 	my $IncExcStr;
       
   455 	if($Inc == 1)
       
   456 	{
       
   457 		$IncExcStr = "include";
       
   458 	}
       
   459 	else
       
   460 	{
       
   461 		$IncExcStr = "exclude";
       
   462 	}
       
   463 
       
   464 	my @nodes = &getNodeFromTree($target, $IncExcStr,"feature");
       
   465 
       
   466 	foreach my $node (@nodes)
       
   467 	{
       
   468 		my %aFeatureInfo = ();
       
   469 		my $isValidFeature = 0;
       
   470 		my $feature = &genericparser::getAttrValue($node, "name");
       
   471 
       
   472 		if($Inc)
       
   473 		{
       
   474 #			Mark the feature included.
       
   475 			$aFeatureInfo{include} = 1;
       
   476 		}
       
   477 		else
       
   478 		{
       
   479 #			Mark the feature excluded.
       
   480 			$aFeatureInfo{exclude} = 1;
       
   481 		}
       
   482 
       
   483 		if(defined $feature and $feature ne "")
       
   484 		{
       
   485 			$aFeatureInfo{name}= $feature;
       
   486 			$aFeatureInfo{uid} = undef;
       
   487 			$isValidFeature = 1;
       
   488 		}
       
   489 		else
       
   490 		{
       
   491 			$feature = &genericparser::getAttrValue($node, "uid");
       
   492 			if(!defined $feature or $feature eq "")
       
   493 			{
       
   494 				print "Warning: Neither feature name nor uid is defined \n";
       
   495 			}
       
   496 			else
       
   497 			{
       
   498 				if(&featureparser::ValidateUIDValue($feature))
       
   499 				{
       
   500 					$feature = &featureparser::ConvertHexToDecimal($feature);
       
   501 					$aFeatureInfo{uid}= $feature;
       
   502 					$aFeatureInfo{name}= undef;
       
   503 					$isValidFeature = 1;
       
   504 				}
       
   505 				else
       
   506 				{
       
   507 					print "The uid value $feature specified in the Image Content Description is not a valid number\n";
       
   508 				}
       
   509 			}
       
   510 		}
       
   511 
       
   512 		if($isValidFeature)
       
   513 		{
       
   514 			push @$IncludeExcludeListRef, \%aFeatureInfo;
       
   515 		}
       
   516 	}
       
   517 }
       
   518 
       
   519 sub DumpImageDetails
       
   520 {
       
   521 	my ($HRef) = @_;
       
   522 	my %hash = %$HRef;
       
   523 	my $ChildHRef;
       
   524 
       
   525 	foreach my $Key (keys %hash)
       
   526 	{
       
   527 		if($Key eq "hasChildren" || $Key eq "vals")
       
   528 		{
       
   529 			next;
       
   530 		}
       
   531 		my $indent = join('', @padding);
       
   532 		&PrintMsg ($indent. $Key);
       
   533 		if($hash{$Key}{hasChildren} == 1)
       
   534 		{
       
   535 			push @padding, ".";
       
   536 			&PrintMsg ("\n");
       
   537 			$ChildHRef = \%{$hash{$Key}};
       
   538 			&DumpImageDetails($ChildHRef);
       
   539 		}
       
   540 		elsif( defined ($hash{$Key}{vals}) )
       
   541 		{
       
   542 			&PrintMsg ("\nVals $hash{$Key}{vals}\n");
       
   543 			push @padding, ".";
       
   544 			$indent = join('', @padding);
       
   545 			my @array = @{$hash{$Key}{vals}};
       
   546 			&PrintMsg ("array len = " . scalar(@array) . "\n");
       
   547 			foreach my $attrib ( @array )
       
   548 			{
       
   549 				foreach my $key1 (keys %$attrib)
       
   550 				{
       
   551 					&PrintMsg ($indent . $Key. " ". "$key1=$$attrib{$key1}\n");
       
   552 				}
       
   553 				&PrintMsg ("\n");
       
   554 			}
       
   555 		}
       
   556 		elsif( defined (@{$hash{$Key}{nodes}}) )
       
   557 		{
       
   558 			my $node = $hash{$Key}{nodes}[0];
       
   559 			&PrintMsg ("{". scalar(@{$hash{$Key}{nodes}})."}\n");
       
   560 		}
       
   561 	}
       
   562 	pop @padding;
       
   563 }
       
   564 
       
   565 sub CheckErrors
       
   566 {
       
   567 	if($#errors > -1)
       
   568 	{
       
   569 		&PrintMsg ("errors..........$#errors \n");
       
   570 		foreach (@errors)
       
   571 		{
       
   572 			&PrintMsg ($_ ."\n");
       
   573 		}
       
   574 		exit;
       
   575 	}
       
   576 }
       
   577 
       
   578 my @ImageBinaryList;#2d array storing the list of binaries per rom image
       
   579 sub AddBinary
       
   580 {
       
   581 	my ($binaryName) = @_;
       
   582 	{
       
   583 		push @{$ImageBinaryList[$curRomImageIndex]}, $binaryName;
       
   584 	}
       
   585 }
       
   586 
       
   587 sub SetBldRomOpts
       
   588 {
       
   589 	my ($key, $value) = @_;
       
   590 	if( $key eq undef )
       
   591 	{
       
   592 #		The default ABI directory is armv5 unless specified otherwise in the buildrom command-line.
       
   593 #		The default build directory is urel unless specified otherwise in the buildrom command-line.
       
   594 		$DefaultDirs{ABI_DIR} = 'ARMV5';
       
   595 		$DefaultDirs{BUILD_DIR}='urel';
       
   596 
       
   597 		$DefaultDirs{DEST_DIR}= "\\sys\\bin";
       
   598 
       
   599 	}
       
   600 	else
       
   601 	{
       
   602 #		trim the value for leading/trailing whitespace
       
   603 		$value = Trim($value);
       
   604 		$DefaultDirs{$key} = $value;
       
   605 	}
       
   606 }
       
   607 
       
   608 sub Trim()
       
   609 {
       
   610 	my @out = @_;
       
   611 	for (@out) {
       
   612 		s/^\s+//;
       
   613 		s/\s+$//;
       
   614 	}
       
   615 	return wantarray ? @out : $out[0];
       
   616 }
       
   617 
       
   618 sub GetBldRomOpts
       
   619 {
       
   620 	my ($key) = @_;
       
   621 	return $DefaultDirs{$key};
       
   622 }
       
   623 
       
   624 sub DumpBinaries
       
   625 {
       
   626 	&PrintMsg ("***********Binaries in ROM***********\n");
       
   627 	my $img_idx = 0;
       
   628 	while ($img_idx < 8 and defined ($ImageBinaryList[$img_idx]))
       
   629 	{
       
   630 		my @list = @{$ImageBinaryList[$img_idx]};
       
   631 		&PrintMsg ("Image $img_idx has ". scalar (@list ) . " binaries\n");
       
   632 		foreach my $bin (@list)
       
   633 		{
       
   634 			&PrintMsg ("file[$img_idx]=$bin\n");
       
   635 		}
       
   636 		$img_idx++;
       
   637 	}
       
   638 
       
   639 	&PrintMsg ("***********END***********\n");
       
   640 }
       
   641 
       
   642 sub PrintMsg
       
   643 {
       
   644 	my ($msg) = @_;
       
   645 	print "$msg";
       
   646 }
       
   647 
       
   648 # This subroutine is used to generate OBY-contents based on contents of the Image content XML. The image content XML 
       
   649 #   may have, in turn, included other OBYs/CDFs. These contents are appended to the Phase-I OBY file (where, the 
       
   650 #   Phase-I OBY file is generated by the preprocessor which is the conglomeration of all the buildrom supplied OBY files).
       
   651 sub GenObyFile
       
   652 {
       
   653 	my ($ObyFileName) = @_;
       
   654 	open (OBYFH, ">>$ObyFileName") or die("* Can't open $ObyFileName\n");
       
   655 	my $binRef;
       
   656 	my $line;
       
   657 	my $index;
       
   658 	my $new_src_path;
       
   659 	my $exec_src_path = $ENV{EPOCROOT};#This is the Executable source path
       
   660 	$exec_src_path .= "epoc32\\release\\";
       
   661 	my $abidir = $DefaultDirs{ABI_DIR};
       
   662 	my $blddir = $DefaultDirs{BUILD_DIR};
       
   663 
       
   664 	GenObyHeader(*OBYFH);
       
   665 
       
   666 	for($index = 0;$index < 8;$index++)
       
   667 	{
       
   668 		if( !defined $romGeometry[$index] )
       
   669 		{
       
   670 			next;
       
   671 		}
       
   672 
       
   673 		$line = "rom_image $index ";
       
   674 		$line .= $romGeometry[$index]{name} . " ";
       
   675 		$line .= "size=" . $romGeometry[$index]{size} . " ";
       
   676 		if( $romGeometry[$index]{type} =~ /nonxip/)
       
   677 		{
       
   678 			$line .= " non-xip ";
       
   679 		}
       
   680 		else
       
   681 		{
       
   682 			$line .= " xip ";
       
   683 		}
       
   684 
       
   685 		$line .= $romGeometry[$index]{compression} . " ";
       
   686 		if($romGeometry[$index]{extension} eq "yes")
       
   687 		{
       
   688 			$line .= " extension ";
       
   689 		}
       
   690 
       
   691 		$line .= "\n";
       
   692 
       
   693 		print OBYFH $line;
       
   694 
       
   695 		$line = "ROM_IMAGE[$index] {\n";	#Start of contents of this image
       
   696 		print OBYFH $line;
       
   697 
       
   698 		foreach my $binary (@{$ImageBinaryList[$index]}) {
       
   699 			$binRef = &cdfparser::GetBinaryInfo($binary);
       
   700 			if( defined ($binRef) and $binRef->{IsFoundInCDF})
       
   701 			{
       
   702 				if(exists $binRef->{default})
       
   703 				{
       
   704 					$line = "DEFAULT_LANGUAGE $binRef->{default} \n";
       
   705 					print OBYFH "$line";
       
   706 				}
       
   707 				
       
   708 				if(exists $binRef->{language})
       
   709 				{
       
   710 					my $langCodes = $binRef->{language};
       
   711  					foreach my $lang (@$langCodes)
       
   712 					{
       
   713 						$line = "LANGUAGE_CODE $lang \n";
       
   714 						print OBYFH "$line";
       
   715 					}
       
   716 				}
       
   717 
       
   718 #				Replace the BUILD_DIR with udeb or urel
       
   719 #				Default BUILD_DIR is urel and can be overridden by using cmd line option '_FULL_DEBUG'
       
   720 #				If a binary is to be picked always from udeb, then the src path in CDF must be mentioned
       
   721 #				as udeb e.g. <source>abi_dir\udeb\drtaeabi.dll</source>, in which case, the mentioned dir
       
   722 #				is picked as it is.
       
   723 
       
   724 				$new_src_path = $binRef->{source};
       
   725 
       
   726 				$new_src_path =~ s/ABI_DIR/$abidir/i;
       
   727 				$new_src_path =~ s/BUILD_DIR/$blddir/i;
       
   728 				$new_src_path =~ s/DEBUG_DIR/udeb/i;
       
   729 
       
   730 				$new_src_path =~ s/epocroot/EPOCROOT/;
       
   731 				$new_src_path =~ s/zresource/ZRESOURCE/;
       
   732 				$new_src_path =~ s/zprivate/ZPRIVATE/;
       
   733 				$new_src_path =~ s/zsystem/ZSYSTEM/;
       
   734 
       
   735 				
       
   736 				my $FileFound = 0;
       
   737 				
       
   738 				if($binRef->{IsExecutable})
       
   739 				{
       
   740 					$new_src_path = $exec_src_path . $new_src_path;
       
   741 					if(!-f $new_src_path)
       
   742 					{
       
   743 						foreach my $newAbiDir (@binarySelectionArray)
       
   744 						{
       
   745 							$new_src_path =~ s/$abidir/$newAbiDir/i;
       
   746 							if(-f $new_src_path)
       
   747 							{
       
   748 								$FileFound = 1;
       
   749 								last;
       
   750 							}
       
   751 							$abidir = $newAbiDir;
       
   752 						}
       
   753 
       
   754 						if( !$FileFound )
       
   755 						{
       
   756 							$FileFound = fallback($abidir, \$new_src_path);
       
   757   							if( !$FileFound )
       
   758 							{
       
   759 								print "Missing file $binRef->{source} \n";
       
   760 								$new_src_path = $binRef->{source};
       
   761 							}
       
   762 
       
   763 						}
       
   764 					}
       
   765 #					compress options
       
   766 					if(exists $binRef->{compress} and ($binRef->{compress} eq "uncompress") )
       
   767 					{
       
   768 						$line = "fileuncompress=";
       
   769 					}
       
   770 					elsif($binRef->{compress} eq "compress")
       
   771 					{
       
   772 						$line = "filecompress=";
       
   773 					}
       
   774 					elsif( exists $binRef->{dll})
       
   775 					{
       
   776 						$line = "dll=";
       
   777 					}
       
   778 #					Checks the plugin type
       
   779 					elsif( exists $binRef->{type} and $binRef->{type} eq "plugin")
       
   780 					{
       
   781 						if (exists $binRef->{plugin_name})
       
   782 						{
       
   783 							$isEcomPlugin=1;
       
   784 							$line = "__$binRef->{plugin_name}_PLUGIN(ABI_DIR\\BUILD_DIR,ECOM_BIN_DIR,DATAZ_,ECOM_RSC_DIR,$binRef->{id},$binRef->{id})\n";
       
   785 						}
       
   786 					}
       
   787 					else
       
   788 					{
       
   789 						$isEcomPlugin=0;
       
   790 						$line = "file=";
       
   791 					}
       
   792 
       
   793 					if (!$isEcomPlugin)
       
   794 					{
       
   795 						$line .= $new_src_path . " ";
       
   796 						$line .= $binRef->{destination};
       
   797 					}
       
   798 
       
   799 
       
   800 #					stack,heap,fixed,priority,uid,dll,dlldatatop
       
   801 					if( exists $binRef->{stack})
       
   802 					{
       
   803 						$line .= " stack " . $binRef->{stack};
       
   804 					}
       
   805 					if( exists $binRef->{heapmin})
       
   806 					{
       
   807 						$line .= " heapmin " . $binRef->{heapmin};
       
   808 					}
       
   809 					if( exists $binRef->{heapmax})
       
   810 					{
       
   811 						$line .= " heapmax " . $binRef->{heapmax};
       
   812 					}
       
   813 					if( exists $binRef->{fixed})
       
   814 					{
       
   815 						$line .= " fixed";
       
   816 					}
       
   817 					if( exists $binRef->{priority})
       
   818 					{
       
   819 						$line .= " priority " . $binRef->{priority};
       
   820 					}
       
   821 					if( exists $binRef->{uid1})
       
   822 					{
       
   823 						$line .= " uid1 " . $binRef->{uid1};
       
   824 					}
       
   825 					if( exists $binRef->{uid2})
       
   826 					{
       
   827 						$line .= " uid2 " . $binRef->{uid2};
       
   828 					}
       
   829 					if( exists $binRef->{uid3})
       
   830 					{
       
   831 						$line .= " uid3 " . $binRef->{uid3};
       
   832 					}
       
   833 					if( exists $binRef->{dlldatatop})
       
   834 					{
       
   835 						$line .= " dlldatatop ". $binRef->{dlldatatop}; 
       
   836 					}
       
   837 					if( exists $binRef->{customisable} and $binRef->{customisable} eq "true")
       
   838 					{
       
   839 						$line .= " patched ";
       
   840 					}
       
   841 				}
       
   842 				else
       
   843 				{
       
   844 					my $type = $binRef->{type};
       
   845 					if($type =~ /normal/i)
       
   846 					{
       
   847 						$line = "data=";
       
   848 					}
       
   849 					if($type =~ /aif/i)
       
   850 					{
       
   851 						$line = "aif=";
       
   852 					}
       
   853 					elsif($type =~ /compressedbitmap/i)
       
   854 					{
       
   855 						$line = "compressed-bitmap=";
       
   856 					}
       
   857 					elsif($type =~ /autobitmap/i)
       
   858 					{
       
   859 						$line = "auto-bitmap=";
       
   860 					}
       
   861 					elsif($type =~ /bitmap/i)
       
   862 					{
       
   863 						$line = "bitmap=";
       
   864 					}
       
   865 
       
   866 					if(exists $binRef->{multilinguify})
       
   867 					{
       
   868 						my $extension;
       
   869 						my $srcNameWithoutExt;
       
   870 						my $dstNameWithoutExt;
       
   871 
       
   872 						if($new_src_path =~ /(.*)\.(.*)/)
       
   873 						{
       
   874 							$srcNameWithoutExt = $1;
       
   875 							$extension = $2;
       
   876 						}
       
   877 						if($binRef->{destination} =~ /(.*)\.(.*)/)
       
   878 						{
       
   879 							$dstNameWithoutExt = $1;
       
   880 						}
       
   881 
       
   882 						$line .= "MULTI_LINGUIFY(";
       
   883 						$line .= $extension . " ";
       
   884 						$line .= $srcNameWithoutExt . " ";
       
   885 						$line .= $dstNameWithoutExt;
       
   886 						$line .= ") ";
       
   887 					}
       
   888 					else
       
   889 					{
       
   890 						$line .= $new_src_path . " ";
       
   891 						$line .= $binRef->{destination};
       
   892 					}
       
   893 				}
       
   894 
       
   895 				$line .= "\n";
       
   896 				print OBYFH $line;
       
   897 			}
       
   898 			else
       
   899 			{
       
   900 				#Check if the binary is from ImageContent XML file.
       
   901 				my $imagecontentbin = 0;
       
   902 				foreach my $bin (@ImageContentBinaries) {
       
   903 					my $source;
       
   904 					if( $bin->{source} =~ /.*\\(\S+)/)
       
   905 					{
       
   906 						$source = $1;
       
   907 					}
       
   908 					if (grep /$binary/i, $source) {#Skip the binary that is already included in the OBY Header
       
   909 						$imagecontentbin = 1;
       
   910 						next;
       
   911 					}
       
   912 				}
       
   913 
       
   914 				if ($imagecontentbin) {
       
   915 					next;
       
   916 				}
       
   917 				my $obyInfo = &ImageContentHandler::GetObyBinaryInfo($binary);
       
   918 				if(!defined $obyInfo)
       
   919 				{
       
   920 					$line = "file=" . $exec_src_path. $DefaultDirs{ABI_DIR}. "\\" . $DefaultDirs{BUILD_DIR}. "\\". $binary. " ";
       
   921 					$line .= $DefaultDirs{DEST_DIR}. "\\". $binary;
       
   922 					$line .= "\n";
       
   923 					print OBYFH $line;
       
   924 				}
       
   925 			}
       
   926 		}
       
   927 		$line = "\n}\n";
       
   928 		print OBYFH $line;
       
   929 	}
       
   930 	close OBYFH;
       
   931 }
       
   932 
       
   933 #Sets default target to ARMV5 directory if the requested binary is not found
       
   934 sub fallback{
       
   935 	
       
   936 	my ($abidir, $abiFileRef) = @_;
       
   937 	my $foundFile=0;
       
   938 	foreach my $BpabiPlat (@BPABIPlats)
       
   939 	{
       
   940 		if ($$abiFileRef =~ /^(.*)\\$BpabiPlat\\(.*)$/)
       
   941 		{
       
   942 			$$abiFileRef =~ s/$abidir/ARMV5/i;
       
   943 			if(-f $$abiFileRef)
       
   944 			{
       
   945 				$foundFile = 1;
       
   946 				last;
       
   947 			}
       
   948 		}
       
   949 	}
       
   950 	return $foundFile;
       
   951 }
       
   952 
       
   953 # This subroutine generates the Rom configuration details like, 'bootbinary', 'romlinearbase', romalign,
       
   954 #   'kerneldataaddress', 'kernelheapmin' etc.
       
   955 sub GenObyHeader
       
   956 {
       
   957 	my ($fh) = @_;
       
   958 	my $line;
       
   959 
       
   960 #	version
       
   961 	if( defined @{$ImageContent{version}{vals}})
       
   962 	{
       
   963 		my $ver = @{$ImageContent{version}{vals}}[0];
       
   964 		if(defined $ver)
       
   965 		{
       
   966 			$line = "version=$ver\n";
       
   967 			print $fh $line;
       
   968 		}
       
   969 	}
       
   970 
       
   971 #	romchecksum
       
   972 	if( defined @{$ImageContent{romchecksum}{vals}})
       
   973 	{
       
   974 		my $cksum = @{$ImageContent{romchecksum}{vals}}[0];
       
   975 		if(defined $cksum)
       
   976 		{
       
   977 			$line = "romchecksum=$cksum\n";
       
   978 			print $fh $line;
       
   979 		}
       
   980 	}
       
   981 
       
   982 #	time
       
   983 	if( defined @{$ImageContent{time}{vals}})
       
   984 	{
       
   985 		my $time = @{$ImageContent{time}{vals}}[0];
       
   986 		if(defined $time)
       
   987 		{
       
   988 			$line = "time=ROMDATE $time\n";
       
   989 			print $fh $line;
       
   990 		}
       
   991 	}
       
   992 
       
   993 
       
   994 #	The Binary selection order
       
   995 	if(scalar @binarySelectionArray )
       
   996 	{
       
   997 		my $abilist = join (',', @binarySelectionArray);
       
   998 		$line = "\nBINARY_SELECTION_ORDER $abilist\n";
       
   999 		print $fh $line;
       
  1000 	}
       
  1001 
       
  1002 #	trace
       
  1003 	if( defined @{$ImageContent{options}{trace}{vals}})
       
  1004 	{
       
  1005 		my @traceFlags = @{$ImageContent{options}{trace}{vals}};
       
  1006 		if(scalar @traceFlags)
       
  1007 		{
       
  1008 			$line = "trace $traceFlags[0]\n";
       
  1009 			print $fh $line;
       
  1010 		}
       
  1011 	}
       
  1012 
       
  1013 #	The bootbinary
       
  1014 	if( defined @{$ImageContent{options}{bootbinary}{vals}})
       
  1015 	{
       
  1016 		my $binary;
       
  1017 		my @bootbin = @{$ImageContent{options}{bootbinary}{vals}};
       
  1018 		if(scalar @bootbin)
       
  1019 		{
       
  1020 			$binary = $bootbin[0];
       
  1021 			$binary =~ s/abi_dir/ABI_DIR/;
       
  1022  			$line = "bootbinary=$binary\n";
       
  1023 			print $fh $line;
       
  1024 		}
       
  1025 	}
       
  1026 
       
  1027 
       
  1028 #	dataaddress
       
  1029 	if( defined @{$ImageContent{options}{dataaddress}{vals}})
       
  1030 	{
       
  1031 		my @dataAddr = @{$ImageContent{options}{dataaddress}{vals}};
       
  1032 		if(scalar @dataAddr)
       
  1033 		{
       
  1034 			$line = "dataaddress=$dataAddr[0]\n";
       
  1035 			print $fh $line;
       
  1036 		}
       
  1037 	}
       
  1038 
       
  1039 #	debugport
       
  1040 	if( defined @{$ImageContent{options}{debugport}{vals}})
       
  1041 	{
       
  1042 		my @dgbPort = @{$ImageContent{options}{debugport}{vals}};
       
  1043 		if(scalar @dgbPort)
       
  1044 		{
       
  1045 			$line = "debugport=$dgbPort[0]\n";
       
  1046 			print $fh $line;
       
  1047 		}
       
  1048 	}
       
  1049 
       
  1050 #	defaultstackreserve
       
  1051 	if( defined @{$ImageContent{options}{defaultstackreserve}{vals}})
       
  1052 	{
       
  1053 		my @defStackRes = @{$ImageContent{options}{defaultstackreserve}{vals}};
       
  1054 		if(scalar @defStackRes)
       
  1055 		{
       
  1056 			$line = "defaultstackreserve=$defStackRes[0]\n";
       
  1057 			print $fh $line;
       
  1058 		}
       
  1059 	}
       
  1060 
       
  1061 #	wrapper
       
  1062 	if( defined @{$ImageContent{options}{wrapper}{vals}})
       
  1063 	{
       
  1064 		my %tbl = @{$ImageContent{options}{wrapper}{vals}}[0];
       
  1065 		if(exists $tbl{epoc})
       
  1066 		{
       
  1067 			$line = "epocwrapper\n";
       
  1068 			print $fh $line;
       
  1069 		}
       
  1070 		elsif(exists $tbl{coff})
       
  1071 		{
       
  1072 			$line = "coffwrapper\n";
       
  1073 			print $fh $line;
       
  1074 		}
       
  1075 		elsif(exists $tbl{none})
       
  1076 		{
       
  1077 			$line = "nowrapper\n";
       
  1078 			print $fh $line;
       
  1079 		}
       
  1080 	}
       
  1081 
       
  1082 #	kernel options
       
  1083 	my $val;
       
  1084 	if( defined @{$ImageContent{options}{kernel}{name}{vals}})
       
  1085 	{
       
  1086 		$val = @{$ImageContent{options}{kernel}{name}{vals}}[0];
       
  1087 		$line = "kernelromname=$val\n";
       
  1088 		print $fh $line;
       
  1089 	}
       
  1090 	if( defined @{$ImageContent{options}{kernel}{dataaddress}{vals}})
       
  1091 	{
       
  1092 		$val = @{$ImageContent{options}{kernel}{dataaddress}{vals}}[0];
       
  1093 		$line = "kerneldataaddress=$val\n";
       
  1094 		print $fh $line;
       
  1095 	}
       
  1096 	if( defined @{$ImageContent{options}{kernel}{trace}{vals}})
       
  1097 	{
       
  1098 		$val = @{$ImageContent{options}{kernel}{trace}{vals}}[0];
       
  1099 		$line = "kerneltrace $val\n";
       
  1100 		print $fh $line;
       
  1101 	}
       
  1102 	if( defined @{$ImageContent{options}{kernel}{heapmin}{vals}})
       
  1103 	{
       
  1104 		$val = @{$ImageContent{options}{kernel}{heapmin}{vals}}[0];
       
  1105 		$line = "kernelheapmin=$val\n";
       
  1106 		print $fh $line;
       
  1107 	}
       
  1108 	if( defined @{$ImageContent{options}{kernel}{heapmax}{vals}})
       
  1109 	{
       
  1110 		$val = @{$ImageContent{options}{kernel}{heapmax}{vals}}[0];
       
  1111 		$line = "kernelheapmax=$val\n";
       
  1112 		print $fh $line;
       
  1113 	}
       
  1114 #	romlinearbase
       
  1115 	if( defined @{$ImageContent{options}{romlinearbase}{vals}})
       
  1116 	{
       
  1117 		my @romLinBase = @{$ImageContent{options}{romlinearbase}{vals}};
       
  1118 		if(scalar @romLinBase)
       
  1119 		{
       
  1120 			$line = "romlinearbase=$romLinBase[0]\n";
       
  1121 			print $fh $line;
       
  1122 		}
       
  1123 	}
       
  1124 
       
  1125 #   romalign
       
  1126 	if( defined @{$ImageContent{options}{romalign}{vals}})
       
  1127 	{
       
  1128 		my @romAlign = @{$ImageContent{options}{romalign}{vals}};
       
  1129 		if(scalar @romAlign )
       
  1130 		{
       
  1131 			$line = "romalign=$romAlign[0]\n";
       
  1132 			print $fh $line;
       
  1133 		}
       
  1134 	}
       
  1135 
       
  1136 
       
  1137 
       
  1138 
       
  1139 #	autosize keyword with the block size
       
  1140 	if( defined @{$ImageContent{options}{autosize}{vals}})
       
  1141 	{
       
  1142 		my @autoSz = @{$ImageContent{options}{autosize}{vals}};
       
  1143 		if(scalar @autoSz )
       
  1144 		{
       
  1145 			$line = "autosize=$autoSz[0]\n";
       
  1146 			print $fh $line;
       
  1147 		}
       
  1148 	}
       
  1149 
       
  1150 #	coreimage keyword with the coreimage name.
       
  1151 	if( defined @{$ImageContent{options}{coreimage}{vals}})
       
  1152 	{
       
  1153 		my @coreImg = @{$ImageContent{options}{coreimage}{vals}};
       
  1154 		if(scalar @coreImg)
       
  1155 		{
       
  1156 			$line = "coreimage=$coreImg[0]\n";
       
  1157 			print $fh $line;
       
  1158 		}
       
  1159 	}
       
  1160 
       
  1161 
       
  1162 
       
  1163 	foreach my $imgBin (@ImageContentBinaries)
       
  1164 	{
       
  1165 		$line = $imgBin->{keyword};
       
  1166 		my $srcPath = $imgBin->{source};
       
  1167 		$srcPath =~ s/abi_dir/ABI_DIR/;
       
  1168 		$srcPath =~ s/kernel_dir/KERNEL_DIR/;
       
  1169 		$srcPath =~ s/debug_dir/DEBUG_DIR/;
       
  1170 		$srcPath =~ s/build_dir/BUILD_DIR/;
       
  1171 		if(! ($imgBin->{keyword} =~ /secondary/i) )
       
  1172 		{
       
  1173 #			VARID mentioned for primary, device, extension and variant keywords.
       
  1174 			$line .= "[VARID]" ;
       
  1175 		}
       
  1176 		$line .= "=" . $srcPath . "\t\t" .  $imgBin->{destination};
       
  1177 		for my $key (keys %$imgBin)
       
  1178 		{
       
  1179 			if( ($key =~ /keyword/i) ||
       
  1180 				($key =~ /source/i) ||
       
  1181 				($key =~ /destination/i))
       
  1182 			{
       
  1183 #				These keys are already taken care.
       
  1184 				next;
       
  1185 			}
       
  1186 
       
  1187 #			Write the rest of the keywords if any, (e.g., 'fixed' or HEAPMAX(0x40000) ) to the oby line.
       
  1188 			$line .= " ".($key);
       
  1189 			if( defined $imgBin->{$key})
       
  1190 			{
       
  1191 				$line .= "(". $imgBin->{$key}. ") ";
       
  1192 			}
       
  1193 		}
       
  1194 		print $fh "$line\n";
       
  1195 	}
       
  1196 }
       
  1197 
       
  1198 sub GetObyFiles
       
  1199 {
       
  1200 	return \@ObyFileList;
       
  1201 }
       
  1202 
       
  1203 sub GetBinarySelectionOrder
       
  1204 {
       
  1205 	return \@binarySelectionArray;
       
  1206 }
       
  1207 
       
  1208 sub GetFeatures()
       
  1209 {
       
  1210 	my %FeatureMap = ();
       
  1211 	my @FeatList;
       
  1212 	my $featRef;
       
  1213 	my $uid;
       
  1214 	foreach my $feat (@Includes)
       
  1215 	{
       
  1216 		if($feat->{name})
       
  1217 		{
       
  1218 			$uid = &featureparser::getFeatureUID($feat->{name});
       
  1219 			if(!defined $uid)
       
  1220 			{
       
  1221 				print "Error: Feature $feat->{name} not found in feature list XML\n";
       
  1222 				next;
       
  1223 			}
       
  1224 			$feat->{uid} = $uid;
       
  1225 		}
       
  1226 		else
       
  1227 		{
       
  1228 			$uid = $feat->{uid};
       
  1229 			if(!&featureparser::getFeatureInfo($uid))
       
  1230 			{
       
  1231 				print "Error: Feature Uid $uid not found in feature list XML\n";
       
  1232 				next;
       
  1233 			}
       
  1234 		}
       
  1235 
       
  1236 		$featRef = $FeatureMap{$uid};
       
  1237 		if( $featRef->{include} == 1 )
       
  1238 		{
       
  1239 #			Already added to the final feature list
       
  1240 		}
       
  1241 		else
       
  1242 		{
       
  1243 			$FeatureMap{$uid} = $feat;
       
  1244 			push @FeatList, $feat;
       
  1245 		}
       
  1246 	}
       
  1247 
       
  1248 	foreach my $feat (@Excludes)
       
  1249 	{
       
  1250 		if($feat->{name})
       
  1251 		{
       
  1252 			$uid = &featureparser::getFeatureUID($feat->{name});
       
  1253 			if(!defined $uid)
       
  1254 			{
       
  1255 				print "Error: Feature $feat->{name} not found in feature list XML\n";
       
  1256 				next;
       
  1257 			}
       
  1258 			$feat->{uid} = $uid;
       
  1259 		}
       
  1260 		else
       
  1261 		{
       
  1262 			$uid = $feat->{uid};
       
  1263 			if(!&featureparser::getFeatureInfo($uid))
       
  1264 			{
       
  1265 				print "Error: Feature Uid $uid not found in feature list XML\n";
       
  1266 				next;
       
  1267 			}
       
  1268 		}
       
  1269 
       
  1270 		$featRef = $FeatureMap{$uid};
       
  1271 		if( $featRef->{include} == 1 )
       
  1272 		{
       
  1273 			print "Error:The feature Uid $uid was added into the include as well as exclude list\n";
       
  1274 			next;
       
  1275 		}
       
  1276 		elsif($featRef->{exclude} == 1)
       
  1277 		{
       
  1278 #			Already added to the final feature list
       
  1279 			next;
       
  1280 		}
       
  1281 		else
       
  1282 		{
       
  1283 			$FeatureMap{$uid} = $feat;
       
  1284 			push @FeatList, $feat;
       
  1285 		}
       
  1286 	}
       
  1287 	return \@FeatList;
       
  1288 }
       
  1289 
       
  1290 sub AddBinaryFromOby
       
  1291 {
       
  1292 		my $aBinary = lc shift;
       
  1293 	my $aFullPath = lc shift;
       
  1294 
       
  1295 	my $bin = \%{$obyFileInfo{$aBinary}};
       
  1296 	$bin->{IsFoundInOby}  = 1;
       
  1297 	$bin->{fullpath} = $aFullPath;
       
  1298 }
       
  1299 
       
  1300 sub GetObyBinaryInfo
       
  1301 {
       
  1302 	my $aBinary = lc shift;
       
  1303 
       
  1304 	my $aBinaryInfoHash = \%{$obyFileInfo{$aBinary}};
       
  1305 
       
  1306 	if( $aBinaryInfoHash->{IsFoundInOby} == 1)
       
  1307 	{
       
  1308 		return $aBinaryInfoHash;
       
  1309 	}
       
  1310 	return undef;
       
  1311 }
       
  1312 
       
  1313 sub UpdateObyBinaryStaticDep
       
  1314 {
       
  1315 #	Go through the files added from Oby to see if any of their static
       
  1316 #	dependencies need to be resolved.
       
  1317 
       
  1318 	foreach my $obyBin (keys %obyFileInfo)
       
  1319 	{
       
  1320 		if(!defined (&VisitedBinaryInfo($obyBin)) )
       
  1321 		{
       
  1322 			&ProcessStaticDep($obyFileInfo{$obyBin}{fullpath});
       
  1323 		}
       
  1324 	} 
       
  1325 }
       
  1326 
       
  1327 sub SaveImageContentBinaries
       
  1328 {
       
  1329 	my ($binaryListRef, $aKeyword) = @_;
       
  1330 	
       
  1331 	foreach my $node (@$binaryListRef)
       
  1332 	{
       
  1333 		my %binInfo = ();
       
  1334 
       
  1335 #		The keywords being primary, secondary, extension, variant and device
       
  1336 		$binInfo{keyword} = $aKeyword;
       
  1337 
       
  1338 		my @children = &genericparser::getChildElements($node);
       
  1339 
       
  1340 		foreach my $child (@children)
       
  1341 		{
       
  1342 			my $name = &genericparser::getElementName($child);
       
  1343 			my $val = &genericparser::getElementValue($child);
       
  1344 			$binInfo{$name} = $val;
       
  1345 		}
       
  1346 		push @ImageContentBinaries, \%binInfo;
       
  1347 	}
       
  1348 }
       
  1349 
       
  1350 my %VisitedBinaries = ();
       
  1351 my @RomIncludeList;
       
  1352 
       
  1353 sub ProcessCDFList {
       
  1354 
       
  1355 	my ($CDFListRef) = @_;
       
  1356 
       
  1357 	foreach my $cdf (@$CDFListRef)
       
  1358 	{
       
  1359 		&LoadFromCDF($cdf);
       
  1360 	}
       
  1361 
       
  1362 }
       
  1363 
       
  1364 my @padding ;
       
  1365 sub LoadFromCDF
       
  1366 {
       
  1367 	my $cdf;
       
  1368 	my $binFile;
       
  1369 
       
  1370 	my @BinList;
       
  1371 	($cdf, $binFile) = @_;
       
  1372 
       
  1373 #Load the XML and get its contents
       
  1374 	cdfparser::LoadCDF($cdf);
       
  1375 
       
  1376 #Get all binaries from the mdf
       
  1377 	(@BinList) = &cdfparser::GetBinaries($cdf);
       
  1378 
       
  1379 	my $DynBinListRef;
       
  1380 	my $aBinary;
       
  1381 	my $aFile;
       
  1382 
       
  1383 	my $VisitedBinaryInfoHash;
       
  1384 	my $indent = join('', @padding);
       
  1385 	my $binInfo;
       
  1386 	foreach $aBinary (@BinList)
       
  1387 	{
       
  1388 		$VisitedBinaryInfoHash = &VisitedBinaryInfo($aBinary);
       
  1389 		if($VisitedBinaryInfoHash)
       
  1390 		{
       
  1391 			next;
       
  1392 		}
       
  1393 		else
       
  1394 		{
       
  1395 			$VisitedBinaryInfoHash = \%{$VisitedBinaries{$aBinary}};
       
  1396 		}
       
  1397 
       
  1398 		&ImageContentHandler::AddBinary($aBinary);
       
  1399 
       
  1400 		$VisitedBinaryInfoHash->{Marked} = 1;
       
  1401 		push @RomIncludeList, $aBinary;
       
  1402 
       
  1403 #		Include the dynamic dependencies.
       
  1404 		($DynBinListRef) = cdfparser::GetDynamicDependencies($aBinary);
       
  1405 		foreach $aFile (@$DynBinListRef)
       
  1406 		{
       
  1407 			if(grep $aFile, @BinList)
       
  1408 			{
       
  1409 #				the dynamic dependency is found in the same cdf file which
       
  1410 #				is already loaded.
       
  1411 				next;
       
  1412 			}
       
  1413 
       
  1414 			my $new_cdf = cdfparser::GetCDFFileName($aFile);
       
  1415 #			In case there is no cdf describing this binary, ignore it.
       
  1416 			if( defined $new_cdf )
       
  1417 			{
       
  1418 				push @padding, ".";
       
  1419 				LoadFromCDF($new_cdf, $aFile);
       
  1420 			}
       
  1421 		}
       
  1422 		$binInfo = cdfparser::GetBinaryInfo($aBinary);
       
  1423 		&ProcessStaticDep($binInfo->{source}, $aBinary);
       
  1424 	}
       
  1425 }
       
  1426 
       
  1427 sub ProcessStaticDep
       
  1428 {
       
  1429 	my ($aBinary) = @_;
       
  1430 
       
  1431 	my $aAbsFile;
       
  1432 #	Include the static dependencies.
       
  1433 
       
  1434 	my $dir = "$ENV{EPOCROOT}epoc32\\release\\";
       
  1435 	my $abidir = &ImageContentHandler::GetBldRomOpts("ABI_DIR");
       
  1436 	my $blddir = &ImageContentHandler::GetBldRomOpts("BUILD_DIR"); 
       
  1437 
       
  1438 	if($aBinary =~ /(.*)\\.*/)
       
  1439 	{
       
  1440 		$aBinary =~ s/ABI_DIR/$abidir/i;
       
  1441 		$aBinary =~ s/BUILD_DIR/$blddir/i;
       
  1442 		$aBinary =~ s/DEBUG_DIR/udeb/i;
       
  1443 	}
       
  1444 	else
       
  1445 	{
       
  1446 		$dir .= $abidir . "\\";
       
  1447 		$dir .= $blddir. "\\";
       
  1448 	}
       
  1449 	$aAbsFile = $dir. $aBinary;
       
  1450 
       
  1451 	if(!-f $aAbsFile)
       
  1452 	{
       
  1453 #		While evaluating the static dependency, check if the file is found in the 
       
  1454 #		default abi directory. Otherwise, look into the binary selection order.
       
  1455 		my $binSelOrderRef = &ImageContentHandler::GetBinarySelectionOrder();
       
  1456 		my $foundFile = 0;
       
  1457 		foreach my $newAbiDir (@$binSelOrderRef)
       
  1458 		{
       
  1459 			$aAbsFile =~ s/$abidir/$newAbiDir/i;
       
  1460 			if(-f $aAbsFile)
       
  1461 			{
       
  1462 				$foundFile = 1;
       
  1463 				last;
       
  1464 			}
       
  1465 			$abidir = $newAbiDir;
       
  1466 		}
       
  1467 		if($foundFile == 0)
       
  1468 		{
       
  1469 #While evaluating the static dependency, check if the file is found in the 
       
  1470 #default abi directory. Otherwise, fallback to the default ARMV5 directory.
       
  1471 			$foundFile = fallback($abidir, \$aAbsFile);
       
  1472 			if($foundFile == 0)
       
  1473 			{
       
  1474 				return;
       
  1475 			}
       
  1476 
       
  1477 		}
       
  1478 	}
       
  1479 
       
  1480 #	Collect the static dependencies of this binary.
       
  1481 	my (@StatDepsList) = &Dep_Lister::StaticDeps($aAbsFile);
       
  1482 
       
  1483 #	Remove the path portion from the file name if found to get the filename.
       
  1484 #	This is the key into the BinaryInfo map maintained by cdfparser.
       
  1485 	my $filename;
       
  1486 
       
  1487 	if( $aBinary =~ /.*\\(\S+)/)
       
  1488 	{
       
  1489 		$filename = $1;
       
  1490 	}
       
  1491 	else
       
  1492 	{
       
  1493 		$filename = $aBinary;
       
  1494 	}
       
  1495 
       
  1496 	my $binaryInfoRef = cdfparser::GetBinaryInfo($filename);
       
  1497 
       
  1498 	if( defined $binaryInfoRef)
       
  1499 	{
       
  1500 #		Mark the binary it it is a valid E32 executable.
       
  1501 		if(defined @StatDepsList)
       
  1502 		{
       
  1503 			$binaryInfoRef->{IsExecutable} = 1;
       
  1504 		}
       
  1505 		else
       
  1506 		{
       
  1507 			$binaryInfoRef->{IsExecutable} = 0;
       
  1508 		}
       
  1509 	}
       
  1510 
       
  1511 	my $VisitedBinaryInfoHash;
       
  1512 	foreach my $aFile (@StatDepsList)
       
  1513 	{
       
  1514 		my $new_cdf = cdfparser::GetCDFFileName($aFile);
       
  1515 
       
  1516 		if(defined($new_cdf))
       
  1517 		{
       
  1518 			LoadFromCDF($new_cdf, $aFile);
       
  1519 		}
       
  1520 		else
       
  1521 		{
       
  1522 #			Include the static dependencies even if there is no mdf describing this binary
       
  1523 
       
  1524 			$VisitedBinaryInfoHash = &VisitedBinaryInfo($aFile);
       
  1525 			if( !defined ($VisitedBinaryInfoHash) )
       
  1526 			{
       
  1527 				$VisitedBinaryInfoHash = \%{$VisitedBinaries{$aFile}};
       
  1528 				$VisitedBinaryInfoHash->{Marked} = 1;
       
  1529 				&ImageContentHandler::AddBinary($aFile);
       
  1530 				&ProcessStaticDep($aFile);
       
  1531 			}
       
  1532 			else
       
  1533 			{
       
  1534 			}
       
  1535 		}
       
  1536 	}
       
  1537 }
       
  1538 
       
  1539 sub VisitedBinaryInfo
       
  1540 {
       
  1541 	my ($aBinary) = @_;
       
  1542 	my $VisitedBinaryInfoHash = \%{$VisitedBinaries{$aBinary}};
       
  1543 	if($VisitedBinaryInfoHash->{Marked} == 1)
       
  1544 	{
       
  1545 		return $VisitedBinaryInfoHash;
       
  1546 	}
       
  1547 	return undef;
       
  1548 }
       
  1549 
       
  1550 1;