diff -r c7c26511138f -r 360bd6b35136 imgtools/buildrom/tools/ImageContentHandler.pm --- a/imgtools/buildrom/tools/ImageContentHandler.pm Wed Jun 16 16:51:40 2010 +0300 +++ b/imgtools/buildrom/tools/ImageContentHandler.pm Wed Jun 23 16:56:47 2010 +0800 @@ -1,1550 +1,1551 @@ -# -# Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. -# This component and the accompanying materials are made available -# under the terms of the License "Eclipse Public License v1.0" -# which accompanies this distribution, and is available -# at the URL "http://www.eclipse.org/legal/epl-v10.html". -# -# Initial Contributors: -# Nokia Corporation - initial contribution. -# -# Contributors: -# -# Description: -# - -# This package processes the Image Content XML, and creates an OBY file to create a Rom image. -package ImageContentHandler; - - -require Exporter; -@ISA=qw(Exporter); -@EXPORT=qw( - ParseImageContentXML - ProcessImageContent - AddBinary - GetBldRomOpts - SetBldRomOpts - GenObyFile - GetObyFiles - AddBinaryFromOby - UpdateObyBinaryStaticDep - PrintMsg - DumpBinaries -); - -use strict; -use genericparser; -use cdfparser; -use Dep_Lister; - -#Error list -my @errors; - -my %ImageContent=(); #Image details are stored in this tree -my $RootNode; #The root node of the XML root document element -my @TargetImageList; #The list of target element nodes in the XML. These are ordered based on their - # imageid (if it is a number, else, based on the availibility of Rom locations within 0..7). -my @binarySelectionArray; #This array stores the ABI directories to be looked up to select binaries. -my @ImageContentBinaries; #This list is for the biaries mentioned in Image content XML for - # keywords like, 'primary', 'secondary', 'device', 'extension', 'variant'. - -# List that contains information of binary from OBY file. This list is maintained to check if their static dependencies -# have been included already in Rom. -my %obyFileInfo=(); - -my $ImageIndex=-1; - -my @Includes; #List of included features. The included feature in this list is a hash table giving the - #Uid or the name. These features are collected either from the Image content or the CDF XMLs. -my @Excludes; #List of excluded features.The excluded feature in this list is a hash table giving the - #Uid or the name. These features are collected either from the Image content or the CDF XMLs. - -my %DefaultDirs =();#This hash table records the default ABI and the BUILD directories. These are updated in case - # the overriding buildrom options are provided e.g., -D_FULL_DEBUG or -D_PLAT=GCCE etc. - -my @BPABIPlats = &BPABIutl::BPABIutl_Plat_List; # Add the BPABI Platforms to be added - -my $isEcomPlugin=0; # This flag will be set when PLUGINs are provided in the CDF file. - -sub ParseImageContentXML -{ - my $XMLFile = shift; - - $XMLFile =~ s/\\/\//g; - $RootNode = &getRootElement($XMLFile); - - &SetImageDetails(\%ImageContent, $RootNode); -} - - -my @padding; -#This subroutine traverses the XML tree and stores the fields in the hast table %ImageContent. The keys -# are the branch names. For target nodes., it stores the nodes themselves in the hash table and doesn't -# go deeper. These nodes are processed laster. For the other nodes, it keeps traversing recursively. -# There are some special keys used to store the nodes and values in the tree. While storing an XML::DOM -# node, it sores with the keys 'nodes', while, for storing a value, it is stored with the key 'vals'. -# These are the keys used to retrieve the contents of the tree while generating the final OBY. -sub SetImageDetails -{ - my ($ImageDetailRef, $ImageNode) = @_; - my @children = &genericparser::getChildElements($ImageNode); - my $child; - my $TreeRef; - my $branch; - my $parentName = &genericparser::getElementName($ImageNode); - my $childCnt = scalar @children; - - my ($indent) = join('', @padding); - - my $val = &genericparser::getElementValue($ImageNode); - $val = Trim($val); - if($val ne "") - { - push @{$ImageDetailRef->{vals}}, $val; - } - - my $NodeRef; - foreach $child (@children) - { - $branch = &genericparser::getElementName($child); - - $NodeRef = \%{$ImageDetailRef->{$branch}}; - - if($branch eq "cdf" and $parentName eq "romscope") - { -# Record the romscope node. This node indicates the oby files or cdf files/directories -# that may be used. - push @{$NodeRef->{nodes}}, $child; - next; - } - if($branch eq "target" and $parentName eq "romtarget") - { - push @{$NodeRef->{nodes}}, $child; - next; - } - if( ($branch =~ /primary/i ) || - ($branch =~ /secondary/i) || - ($branch =~ /extension/i) || - ($branch =~ /variant/i ) || - ($branch =~ /device/i ) ) - { - next; - } - - if( $child->hasChildNodes() ) - { - $NodeRef->{hasChildren} = 1; - push @padding, "."; - SetImageDetails($NodeRef, $child); - } - else - { - $NodeRef->{hasChildren} = 0; - } - -# Get all attributes... - my $attribs = &genericparser::getNodeAttributes($child); - my $attrib; - - my $nodeName; - my $nodeVal; - my %attr=(); - my $attrLen = $attribs->getLength; - for (my $pos = 0; $pos < $attrLen;$pos++) - { - $attrib = $attribs->item($pos); - if(!$attrib) - { - next; - } - $nodeName = lc ($attrib->getName); - $nodeVal = lc ($attrib->getValue); - $attr{$nodeName}=$nodeVal; - - } - push @{$NodeRef->{vals}}, \%attr; - } - - pop @padding; -} - -my @romGeometry; #Array to store all Roms mentioned in RomGeometry -my %romGeometryHash = (); #This Hash table records the indices in @romGeometry array, keying on their Ids. - -my $curRomImageIndex; #This scalar records the current Rom image being processed. An binary encountered - # becomes part of the Rom image corresponding to this partition. - -# This subroutine associates the RomGeometry and the RomTarget sub-trees to set indices for the Rom-target -# nodes.It stores the Image content XML entries for primary/secondary/device/extension/variant keywords. -# It also stores the features that are included/excluded in Image content XML. - -sub ProcessImageContent -{ - my $TotalImages = &ProcessRomGeometry(); - - my @trgList; - if( defined @{$ImageContent{romtarget}{target}{nodes}}) - { - @trgList = @{$ImageContent{romtarget}{target}{nodes}}; - } - -# Go through the romgeometry to find the location of each image. The valid IDs are 0 through 7. - - foreach my $trg (@trgList) - { -# The ID field in romgeometry can be an integer in the range 0 through 7. -# If it is not a number, its location is assumed as its sequence number - my $imageid = &genericparser::getAttrValue($trg, "imageid"); - if($imageid =~ /Any/i) - { - next; - } - elsif(exists $romGeometryHash{$imageid}) - { - $ImageIndex = $romGeometryHash{$imageid}; - push @{$TargetImageList[$ImageIndex]} , $trg; - } - } - -# Romscope - update the maps if the files and directories are mentioned. - my @romScopeNodes; - if(defined @{$ImageContent{romscope}{cdf}{nodes}}) - { - @romScopeNodes = @{$ImageContent{romscope}{cdf}{nodes}}; - } - - my $type; - my $file; - my $dir; - foreach my $aNode (@romScopeNodes) - { - $type = &genericparser::getAttrValue($aNode, "type"); - if( $type =~ /dir/i) - { - $dir = &genericparser::getElementValue($aNode); - &cdfparser::CreateCDFFileBinaryMapFromDir($dir); - } - elsif($type =~ /file/i) - { - $file = &genericparser::getElementValue($aNode); - &cdfparser::CreateCDFFileBinaryMap($file); - } - } - - my $availablePos = 0; - foreach my $trg (@trgList) - { - if(&genericparser::getAttrValue($trg, "imageid") =~ /Any/i) - { - while($availablePos < $TotalImages) - { - if( !defined($TargetImageList[$availablePos][0]) ) - { - push @{$TargetImageList[$availablePos]}, $trg; - last; - } - $availablePos++; - } - } - } - - my $pos = 0; - while( $pos < 8) - { - if( defined $TargetImageList[$pos][0] ) - { -# Record the current Rom image index so that the binaries are included in the corresponding -# Rom image. -# The romGeometry and TargetImageList arrays are associated both being indexed on -# the Rom-image index. - - $curRomImageIndex = $pos; - &ProcessTarget($pos, \@{$TargetImageList[$pos]}); - } - $pos++; - } - -# Pick the primary/secondary/device binaries - my @nodes = &genericparser::getNodeFromTree($RootNode, "options", "primary", "file"); - if( defined @nodes) - { - &SaveImageContentBinaries(\@nodes, "primary"); - } - - @nodes = &genericparser::getNodeFromTree($RootNode, "options", "secondary", "file"); - if( defined @nodes) - { - &SaveImageContentBinaries(\@nodes, "secondary"); - } - - @nodes = &genericparser::getNodeFromTree($RootNode, "options", "extension", "file"); - if( defined @nodes) - { - &SaveImageContentBinaries(\@nodes, "extension"); - } - - @nodes = &genericparser::getNodeFromTree($RootNode, "options", "variant", "file"); - if( defined @nodes) - { - &SaveImageContentBinaries(\@nodes, "variant"); - } - - @nodes = &genericparser::getNodeFromTree($RootNode, "options", "device", "file"); - if( defined @nodes) - { - &SaveImageContentBinaries(\@nodes, "device"); - } - - foreach my $imgBin (@ImageContentBinaries) - { - &ProcessStaticDep($imgBin->{source}); - } - -# Pick the binary selection order - if (exists($ImageContent{options}{binaryselectionorder}{vals})) - { - my ($abiDirs) = @{$ImageContent{options}{binaryselectionorder}{vals}}; - @binarySelectionArray = split(',', $abiDirs); - @binarySelectionArray = Trim(@binarySelectionArray); - - } - - my $featureList = &cdfparser::GetIncludedFeatureList(); - foreach my $feature (@$featureList) - { - push @Includes, $feature; - } - - $featureList = &cdfparser::GetExcludedFeatureList(); - foreach my $feature (@$featureList) - { - push @Excludes, $feature; - } -} - -#Arrange the Rom-geometry according to their Id when they are numbers. The named images -#are arranged starting from the empty slots in Rom geometry array. -sub ProcessRomGeometry -{ - my $RomImageCount = 0; - my $pos = 0; - while($pos < 8) - { - $romGeometry[$pos++] = undef; - } - - my @roms = @{$ImageContent{romgeometry}{image}{vals}}; - $RomImageCount = scalar (@roms); - my @namedImages; - -# Visit all images and allocate them the indices they mention. - foreach my $img (@roms) - { - if($img->{id} =~ /(\d+)/) - { - $pos = $1; - if( defined($romGeometry[$pos]) ) - { - print "Error: $romGeometry[$pos]->{id} and $img->{id} cant be allocated the same position\n"; - exit; - } - $romGeometry[$pos] = $img; - -# Record the index of this Rom - $romGeometryHash{$img->{id}} = $pos; - } - else - { -# These are the named images that are allocated there positions sequentially starting from -# the first available empty position - push @namedImages, $img; - } - } - -# Revisit the images and allocate the remaining (unallocated) positions. - - $pos = 0; - my $namedImageCount = scalar (@namedImages); - my $firstNamedImgIdx = 0; - my $img; - while( ($pos < 8) and ($namedImageCount > 0) ) - { - if( $romGeometry[$pos] ) - { -# skip the positions already allocated. - $pos++; - next; - } - $img = $namedImages[$firstNamedImgIdx]; - $romGeometry[$pos] = $img; - -# Record the index of this Rom - $romGeometryHash{$img->{id}} = $pos; - - $pos++;$firstNamedImgIdx++; - $namedImageCount--; - } - - return $RomImageCount; -} - -my @ObyFileList; - -#This subrouting processes the target nodes that may include OBYs/CDFs or features. For CDFs, the satic/dynamic -# dependencies are evaluated. - -sub ProcessTarget -{ - my ($ImgPos , $trgNodesRef) = @_; - my @cdfFileList; - -# For all the 'target' nodes associated with an image in romgeometry at the given index... -# The link between a target and an image in romGeometry is the image id. If the imageid -# of a target is 'Any', then the first available image in romGeometry is allocated to -# that target. - - foreach my $target (@$trgNodesRef) - { - -# Fetch any cdfs included within the Image Content file - my @cdfs = &getNodeFromTree($target, "include","cdf"); - - my $type; - my $file; - my $dir; - foreach my $cdfNode (@cdfs) - { - $type = &genericparser::getAttrValue($cdfNode, "type"); - - if( !($type) || ($type eq "file") ) - { - $file = &genericparser::getElementValue($cdfNode); - push @cdfFileList, $file; - } - elsif($type eq "dir") - { - $dir = &genericparser::getElementValue($cdfNode); - &cdfparser::CreateCDFFileBinaryMapFromDir($dir); - } - } - -# Collect all the obey files mentioned in this 'target' node. - my @obys = &getNodeFromTree($target, "include","obyFile"); - foreach my $obyNode (@obys) - { - $file = &genericparser::getElementValue($obyNode); - push @ObyFileList, $file; - } - - &CollectFeatures($target, 1, \@Includes); - &CollectFeatures($target, 0, \@Excludes); - } - - ProcessCDFList(\@cdfFileList); -} - -# This subroutine updates the include or exclude feature list collected from Image content XML. -sub CollectFeatures -{ -# Collect all the features included/excluded in this 'target' node. - - my ($target, $Inc, $IncludeExcludeListRef) = @_; - my $IncExcStr; - if($Inc == 1) - { - $IncExcStr = "include"; - } - else - { - $IncExcStr = "exclude"; - } - - my @nodes = &getNodeFromTree($target, $IncExcStr,"feature"); - - foreach my $node (@nodes) - { - my %aFeatureInfo = (); - my $isValidFeature = 0; - my $feature = &genericparser::getAttrValue($node, "name"); - - if($Inc) - { -# Mark the feature included. - $aFeatureInfo{include} = 1; - } - else - { -# Mark the feature excluded. - $aFeatureInfo{exclude} = 1; - } - - if(defined $feature and $feature ne "") - { - $aFeatureInfo{name}= $feature; - $aFeatureInfo{uid} = undef; - $isValidFeature = 1; - } - else - { - $feature = &genericparser::getAttrValue($node, "uid"); - if(!defined $feature or $feature eq "") - { - print "Warning: Neither feature name nor uid is defined \n"; - } - else - { - if(&featureparser::ValidateUIDValue($feature)) - { - $feature = &featureparser::ConvertHexToDecimal($feature); - $aFeatureInfo{uid}= $feature; - $aFeatureInfo{name}= undef; - $isValidFeature = 1; - } - else - { - print "The uid value $feature specified in the Image Content Description is not a valid number\n"; - } - } - } - - if($isValidFeature) - { - push @$IncludeExcludeListRef, \%aFeatureInfo; - } - } -} - -sub DumpImageDetails -{ - my ($HRef) = @_; - my %hash = %$HRef; - my $ChildHRef; - - foreach my $Key (keys %hash) - { - if($Key eq "hasChildren" || $Key eq "vals") - { - next; - } - my $indent = join('', @padding); - &PrintMsg ($indent. $Key); - if($hash{$Key}{hasChildren} == 1) - { - push @padding, "."; - &PrintMsg ("\n"); - $ChildHRef = \%{$hash{$Key}}; - &DumpImageDetails($ChildHRef); - } - elsif( defined ($hash{$Key}{vals}) ) - { - &PrintMsg ("\nVals $hash{$Key}{vals}\n"); - push @padding, "."; - $indent = join('', @padding); - my @array = @{$hash{$Key}{vals}}; - &PrintMsg ("array len = " . scalar(@array) . "\n"); - foreach my $attrib ( @array ) - { - foreach my $key1 (keys %$attrib) - { - &PrintMsg ($indent . $Key. " ". "$key1=$$attrib{$key1}\n"); - } - &PrintMsg ("\n"); - } - } - elsif( defined (@{$hash{$Key}{nodes}}) ) - { - my $node = $hash{$Key}{nodes}[0]; - &PrintMsg ("{". scalar(@{$hash{$Key}{nodes}})."}\n"); - } - } - pop @padding; -} - -sub CheckErrors -{ - if($#errors > -1) - { - &PrintMsg ("errors..........$#errors \n"); - foreach (@errors) - { - &PrintMsg ($_ ."\n"); - } - exit; - } -} - -my @ImageBinaryList;#2d array storing the list of binaries per rom image -sub AddBinary -{ - my ($binaryName) = @_; - { - push @{$ImageBinaryList[$curRomImageIndex]}, $binaryName; - } -} - -sub SetBldRomOpts -{ - my ($key, $value) = @_; - if( $key eq undef ) - { -# The default ABI directory is armv5 unless specified otherwise in the buildrom command-line. -# The default build directory is urel unless specified otherwise in the buildrom command-line. - $DefaultDirs{ABI_DIR} = 'ARMV5'; - $DefaultDirs{BUILD_DIR}='urel'; - - $DefaultDirs{DEST_DIR}= "\\sys\\bin"; - - } - else - { -# trim the value for leading/trailing whitespace - $value = Trim($value); - $DefaultDirs{$key} = $value; - } -} - -sub Trim() -{ - my @out = @_; - for (@out) { - s/^\s+//; - s/\s+$//; - } - return wantarray ? @out : $out[0]; -} - -sub GetBldRomOpts -{ - my ($key) = @_; - return $DefaultDirs{$key}; -} - -sub DumpBinaries -{ - &PrintMsg ("***********Binaries in ROM***********\n"); - my $img_idx = 0; - while ($img_idx < 8 and defined ($ImageBinaryList[$img_idx])) - { - my @list = @{$ImageBinaryList[$img_idx]}; - &PrintMsg ("Image $img_idx has ". scalar (@list ) . " binaries\n"); - foreach my $bin (@list) - { - &PrintMsg ("file[$img_idx]=$bin\n"); - } - $img_idx++; - } - - &PrintMsg ("***********END***********\n"); -} - -sub PrintMsg -{ - my ($msg) = @_; - print "$msg"; -} - -# This subroutine is used to generate OBY-contents based on contents of the Image content XML. The image content XML -# may have, in turn, included other OBYs/CDFs. These contents are appended to the Phase-I OBY file (where, the -# Phase-I OBY file is generated by the preprocessor which is the conglomeration of all the buildrom supplied OBY files). -sub GenObyFile -{ - my ($ObyFileName) = @_; - open (OBYFH, ">>$ObyFileName") or die("* Can't open $ObyFileName\n"); - my $binRef; - my $line; - my $index; - my $new_src_path; - my $exec_src_path = $ENV{EPOCROOT};#This is the Executable source path - $exec_src_path .= "epoc32\\release\\"; - my $abidir = $DefaultDirs{ABI_DIR}; - my $blddir = $DefaultDirs{BUILD_DIR}; - - GenObyHeader(*OBYFH); - - for($index = 0;$index < 8;$index++) - { - if( !defined $romGeometry[$index] ) - { - next; - } - - $line = "rom_image $index "; - $line .= $romGeometry[$index]{name} . " "; - $line .= "size=" . $romGeometry[$index]{size} . " "; - if( $romGeometry[$index]{type} =~ /nonxip/) - { - $line .= " non-xip "; - } - else - { - $line .= " xip "; - } - - $line .= $romGeometry[$index]{compression} . " "; - if($romGeometry[$index]{extension} eq "yes") - { - $line .= " extension "; - } - - $line .= "\n"; - - print OBYFH $line; - - $line = "ROM_IMAGE[$index] {\n"; #Start of contents of this image - print OBYFH $line; - - foreach my $binary (@{$ImageBinaryList[$index]}) { - $binRef = &cdfparser::GetBinaryInfo($binary); - if( defined ($binRef) and $binRef->{IsFoundInCDF}) - { - if(exists $binRef->{default}) - { - $line = "DEFAULT_LANGUAGE $binRef->{default} \n"; - print OBYFH "$line"; - } - - if(exists $binRef->{language}) - { - my $langCodes = $binRef->{language}; - foreach my $lang (@$langCodes) - { - $line = "LANGUAGE_CODE $lang \n"; - print OBYFH "$line"; - } - } - -# Replace the BUILD_DIR with udeb or urel -# Default BUILD_DIR is urel and can be overridden by using cmd line option '_FULL_DEBUG' -# If a binary is to be picked always from udeb, then the src path in CDF must be mentioned -# as udeb e.g. abi_dir\udeb\drtaeabi.dll, in which case, the mentioned dir -# is picked as it is. - - $new_src_path = $binRef->{source}; - - $new_src_path =~ s/ABI_DIR/$abidir/i; - $new_src_path =~ s/BUILD_DIR/$blddir/i; - $new_src_path =~ s/DEBUG_DIR/udeb/i; - - $new_src_path =~ s/epocroot/EPOCROOT/; - $new_src_path =~ s/zresource/ZRESOURCE/; - $new_src_path =~ s/zprivate/ZPRIVATE/; - $new_src_path =~ s/zsystem/ZSYSTEM/; - - - my $FileFound = 0; - - if($binRef->{IsExecutable}) - { - $new_src_path = $exec_src_path . $new_src_path; - if(!-f $new_src_path) - { - foreach my $newAbiDir (@binarySelectionArray) - { - $new_src_path =~ s/$abidir/$newAbiDir/i; - if(-f $new_src_path) - { - $FileFound = 1; - last; - } - $abidir = $newAbiDir; - } - - if( !$FileFound ) - { - $FileFound = fallback($abidir, \$new_src_path); - if( !$FileFound ) - { - print "Missing file $binRef->{source} \n"; - $new_src_path = $binRef->{source}; - } - - } - } -# compress options - if(exists $binRef->{compress} and ($binRef->{compress} eq "uncompress") ) - { - $line = "fileuncompress="; - } - elsif($binRef->{compress} eq "compress") - { - $line = "filecompress="; - } - elsif( exists $binRef->{dll}) - { - $line = "dll="; - } -# Checks the plugin type - elsif( exists $binRef->{type} and $binRef->{type} eq "plugin") - { - if (exists $binRef->{plugin_name}) - { - $isEcomPlugin=1; - $line = "__$binRef->{plugin_name}_PLUGIN(ABI_DIR\\BUILD_DIR,ECOM_BIN_DIR,DATAZ_,ECOM_RSC_DIR,$binRef->{id},$binRef->{id})\n"; - } - } - else - { - $isEcomPlugin=0; - $line = "file="; - } - - if (!$isEcomPlugin) - { - $line .= $new_src_path . " "; - $line .= $binRef->{destination}; - } - - -# stack,heap,fixed,priority,uid,dll,dlldatatop - if( exists $binRef->{stack}) - { - $line .= " stack " . $binRef->{stack}; - } - if( exists $binRef->{heapmin}) - { - $line .= " heapmin " . $binRef->{heapmin}; - } - if( exists $binRef->{heapmax}) - { - $line .= " heapmax " . $binRef->{heapmax}; - } - if( exists $binRef->{fixed}) - { - $line .= " fixed"; - } - if( exists $binRef->{priority}) - { - $line .= " priority " . $binRef->{priority}; - } - if( exists $binRef->{uid1}) - { - $line .= " uid1 " . $binRef->{uid1}; - } - if( exists $binRef->{uid2}) - { - $line .= " uid2 " . $binRef->{uid2}; - } - if( exists $binRef->{uid3}) - { - $line .= " uid3 " . $binRef->{uid3}; - } - if( exists $binRef->{dlldatatop}) - { - $line .= " dlldatatop ". $binRef->{dlldatatop}; - } - if( exists $binRef->{customisable} and $binRef->{customisable} eq "true") - { - $line .= " patched "; - } - } - else - { - my $type = $binRef->{type}; - if($type =~ /normal/i) - { - $line = "data="; - } - if($type =~ /aif/i) - { - $line = "aif="; - } - elsif($type =~ /compressedbitmap/i) - { - $line = "compressed-bitmap="; - } - elsif($type =~ /autobitmap/i) - { - $line = "auto-bitmap="; - } - elsif($type =~ /bitmap/i) - { - $line = "bitmap="; - } - - if(exists $binRef->{multilinguify}) - { - my $extension; - my $srcNameWithoutExt; - my $dstNameWithoutExt; - - if($new_src_path =~ /(.*)\.(.*)/) - { - $srcNameWithoutExt = $1; - $extension = $2; - } - if($binRef->{destination} =~ /(.*)\.(.*)/) - { - $dstNameWithoutExt = $1; - } - - $line .= "MULTI_LINGUIFY("; - $line .= $extension . " "; - $line .= $srcNameWithoutExt . " "; - $line .= $dstNameWithoutExt; - $line .= ") "; - } - else - { - $line .= $new_src_path . " "; - $line .= $binRef->{destination}; - } - } - - $line .= "\n"; - print OBYFH $line; - } - else - { - #Check if the binary is from ImageContent XML file. - my $imagecontentbin = 0; - foreach my $bin (@ImageContentBinaries) { - my $source; - if( $bin->{source} =~ /.*\\(\S+)/) - { - $source = $1; - } - if (grep /$binary/i, $source) {#Skip the binary that is already included in the OBY Header - $imagecontentbin = 1; - next; - } - } - - if ($imagecontentbin) { - next; - } - my $obyInfo = &ImageContentHandler::GetObyBinaryInfo($binary); - if(!defined $obyInfo) - { - $line = "file=" . $exec_src_path. $DefaultDirs{ABI_DIR}. "\\" . $DefaultDirs{BUILD_DIR}. "\\". $binary. " "; - $line .= $DefaultDirs{DEST_DIR}. "\\". $binary; - $line .= "\n"; - print OBYFH $line; - } - } - } - $line = "\n}\n"; - print OBYFH $line; - } - close OBYFH; -} - -#Sets default target to ARMV5 directory if the requested binary is not found -sub fallback{ - - my ($abidir, $abiFileRef) = @_; - my $foundFile=0; - foreach my $BpabiPlat (@BPABIPlats) - { - if ($$abiFileRef =~ /^(.*)\\$BpabiPlat\\(.*)$/) - { - $$abiFileRef =~ s/$abidir/ARMV5/i; - if(-f $$abiFileRef) - { - $foundFile = 1; - last; - } - } - } - return $foundFile; -} - -# This subroutine generates the Rom configuration details like, 'bootbinary', 'romlinearbase', romalign, -# 'kerneldataaddress', 'kernelheapmin' etc. -sub GenObyHeader -{ - my ($fh) = @_; - my $line; - -# version - if( defined @{$ImageContent{version}{vals}}) - { - my $ver = @{$ImageContent{version}{vals}}[0]; - if(defined $ver) - { - $line = "version=$ver\n"; - print $fh $line; - } - } - -# romchecksum - if( defined @{$ImageContent{romchecksum}{vals}}) - { - my $cksum = @{$ImageContent{romchecksum}{vals}}[0]; - if(defined $cksum) - { - $line = "romchecksum=$cksum\n"; - print $fh $line; - } - } - -# time - if( defined @{$ImageContent{time}{vals}}) - { - my $time = @{$ImageContent{time}{vals}}[0]; - if(defined $time) - { - $line = "time=ROMDATE $time\n"; - print $fh $line; - } - } - - -# The Binary selection order - if(scalar @binarySelectionArray ) - { - my $abilist = join (',', @binarySelectionArray); - $line = "\nBINARY_SELECTION_ORDER $abilist\n"; - print $fh $line; - } - -# trace - if( defined @{$ImageContent{options}{trace}{vals}}) - { - my @traceFlags = @{$ImageContent{options}{trace}{vals}}; - if(scalar @traceFlags) - { - $line = "trace $traceFlags[0]\n"; - print $fh $line; - } - } - -# The bootbinary - if( defined @{$ImageContent{options}{bootbinary}{vals}}) - { - my $binary; - my @bootbin = @{$ImageContent{options}{bootbinary}{vals}}; - if(scalar @bootbin) - { - $binary = $bootbin[0]; - $binary =~ s/abi_dir/ABI_DIR/; - $line = "bootbinary=$binary\n"; - print $fh $line; - } - } - - -# dataaddress - if( defined @{$ImageContent{options}{dataaddress}{vals}}) - { - my @dataAddr = @{$ImageContent{options}{dataaddress}{vals}}; - if(scalar @dataAddr) - { - $line = "dataaddress=$dataAddr[0]\n"; - print $fh $line; - } - } - -# debugport - if( defined @{$ImageContent{options}{debugport}{vals}}) - { - my @dgbPort = @{$ImageContent{options}{debugport}{vals}}; - if(scalar @dgbPort) - { - $line = "debugport=$dgbPort[0]\n"; - print $fh $line; - } - } - -# defaultstackreserve - if( defined @{$ImageContent{options}{defaultstackreserve}{vals}}) - { - my @defStackRes = @{$ImageContent{options}{defaultstackreserve}{vals}}; - if(scalar @defStackRes) - { - $line = "defaultstackreserve=$defStackRes[0]\n"; - print $fh $line; - } - } - -# wrapper - if( defined @{$ImageContent{options}{wrapper}{vals}}) - { - my %tbl = @{$ImageContent{options}{wrapper}{vals}}[0]; - if(exists $tbl{epoc}) - { - $line = "epocwrapper\n"; - print $fh $line; - } - elsif(exists $tbl{coff}) - { - $line = "coffwrapper\n"; - print $fh $line; - } - elsif(exists $tbl{none}) - { - $line = "nowrapper\n"; - print $fh $line; - } - } - -# kernel options - my $val; - if( defined @{$ImageContent{options}{kernel}{name}{vals}}) - { - $val = @{$ImageContent{options}{kernel}{name}{vals}}[0]; - $line = "kernelromname=$val\n"; - print $fh $line; - } - if( defined @{$ImageContent{options}{kernel}{dataaddress}{vals}}) - { - $val = @{$ImageContent{options}{kernel}{dataaddress}{vals}}[0]; - $line = "kerneldataaddress=$val\n"; - print $fh $line; - } - if( defined @{$ImageContent{options}{kernel}{trace}{vals}}) - { - $val = @{$ImageContent{options}{kernel}{trace}{vals}}[0]; - $line = "kerneltrace $val\n"; - print $fh $line; - } - if( defined @{$ImageContent{options}{kernel}{heapmin}{vals}}) - { - $val = @{$ImageContent{options}{kernel}{heapmin}{vals}}[0]; - $line = "kernelheapmin=$val\n"; - print $fh $line; - } - if( defined @{$ImageContent{options}{kernel}{heapmax}{vals}}) - { - $val = @{$ImageContent{options}{kernel}{heapmax}{vals}}[0]; - $line = "kernelheapmax=$val\n"; - print $fh $line; - } -# romlinearbase - if( defined @{$ImageContent{options}{romlinearbase}{vals}}) - { - my @romLinBase = @{$ImageContent{options}{romlinearbase}{vals}}; - if(scalar @romLinBase) - { - $line = "romlinearbase=$romLinBase[0]\n"; - print $fh $line; - } - } - -# romalign - if( defined @{$ImageContent{options}{romalign}{vals}}) - { - my @romAlign = @{$ImageContent{options}{romalign}{vals}}; - if(scalar @romAlign ) - { - $line = "romalign=$romAlign[0]\n"; - print $fh $line; - } - } - - - - -# autosize keyword with the block size - if( defined @{$ImageContent{options}{autosize}{vals}}) - { - my @autoSz = @{$ImageContent{options}{autosize}{vals}}; - if(scalar @autoSz ) - { - $line = "autosize=$autoSz[0]\n"; - print $fh $line; - } - } - -# coreimage keyword with the coreimage name. - if( defined @{$ImageContent{options}{coreimage}{vals}}) - { - my @coreImg = @{$ImageContent{options}{coreimage}{vals}}; - if(scalar @coreImg) - { - $line = "coreimage=$coreImg[0]\n"; - print $fh $line; - } - } - - - - foreach my $imgBin (@ImageContentBinaries) - { - $line = $imgBin->{keyword}; - my $srcPath = $imgBin->{source}; - $srcPath =~ s/abi_dir/ABI_DIR/; - $srcPath =~ s/kernel_dir/KERNEL_DIR/; - $srcPath =~ s/debug_dir/DEBUG_DIR/; - $srcPath =~ s/build_dir/BUILD_DIR/; - if(! ($imgBin->{keyword} =~ /secondary/i) ) - { -# VARID mentioned for primary, device, extension and variant keywords. - $line .= "[VARID]" ; - } - $line .= "=" . $srcPath . "\t\t" . $imgBin->{destination}; - for my $key (keys %$imgBin) - { - if( ($key =~ /keyword/i) || - ($key =~ /source/i) || - ($key =~ /destination/i)) - { -# These keys are already taken care. - next; - } - -# Write the rest of the keywords if any, (e.g., 'fixed' or HEAPMAX(0x40000) ) to the oby line. - $line .= " ".($key); - if( defined $imgBin->{$key}) - { - $line .= "(". $imgBin->{$key}. ") "; - } - } - print $fh "$line\n"; - } -} - -sub GetObyFiles -{ - return \@ObyFileList; -} - -sub GetBinarySelectionOrder -{ - return \@binarySelectionArray; -} - -sub GetFeatures() -{ - my %FeatureMap = (); - my @FeatList; - my $featRef; - my $uid; - foreach my $feat (@Includes) - { - if($feat->{name}) - { - $uid = &featureparser::getFeatureUID($feat->{name}); - if(!defined $uid) - { - print "Error: Feature $feat->{name} not found in feature list XML\n"; - next; - } - $feat->{uid} = $uid; - } - else - { - $uid = $feat->{uid}; - if(!&featureparser::getFeatureInfo($uid)) - { - print "Error: Feature Uid $uid not found in feature list XML\n"; - next; - } - } - - $featRef = $FeatureMap{$uid}; - if( $featRef->{include} == 1 ) - { -# Already added to the final feature list - } - else - { - $FeatureMap{$uid} = $feat; - push @FeatList, $feat; - } - } - - foreach my $feat (@Excludes) - { - if($feat->{name}) - { - $uid = &featureparser::getFeatureUID($feat->{name}); - if(!defined $uid) - { - print "Error: Feature $feat->{name} not found in feature list XML\n"; - next; - } - $feat->{uid} = $uid; - } - else - { - $uid = $feat->{uid}; - if(!&featureparser::getFeatureInfo($uid)) - { - print "Error: Feature Uid $uid not found in feature list XML\n"; - next; - } - } - - $featRef = $FeatureMap{$uid}; - if( $featRef->{include} == 1 ) - { - print "Error:The feature Uid $uid was added into the include as well as exclude list\n"; - next; - } - elsif($featRef->{exclude} == 1) - { -# Already added to the final feature list - next; - } - else - { - $FeatureMap{$uid} = $feat; - push @FeatList, $feat; - } - } - return \@FeatList; -} - -sub AddBinaryFromOby -{ - my $aBinary = lc shift; - my $aFullPath = lc shift; - - my $bin = \%{$obyFileInfo{$aBinary}}; - $bin->{IsFoundInOby} = 1; - $bin->{fullpath} = $aFullPath; -} - -sub GetObyBinaryInfo -{ - my $aBinary = lc shift; - - my $aBinaryInfoHash = \%{$obyFileInfo{$aBinary}}; - - if( $aBinaryInfoHash->{IsFoundInOby} == 1) - { - return $aBinaryInfoHash; - } - return undef; -} - -sub UpdateObyBinaryStaticDep -{ -# Go through the files added from Oby to see if any of their static -# dependencies need to be resolved. - - foreach my $obyBin (keys %obyFileInfo) - { - if(!defined (&VisitedBinaryInfo($obyBin)) ) - { - &ProcessStaticDep($obyFileInfo{$obyBin}{fullpath}); - } - } -} - -sub SaveImageContentBinaries -{ - my ($binaryListRef, $aKeyword) = @_; - - foreach my $node (@$binaryListRef) - { - my %binInfo = (); - -# The keywords being primary, secondary, extension, variant and device - $binInfo{keyword} = $aKeyword; - - my @children = &genericparser::getChildElements($node); - - foreach my $child (@children) - { - my $name = &genericparser::getElementName($child); - my $val = &genericparser::getElementValue($child); - $binInfo{$name} = $val; - } - push @ImageContentBinaries, \%binInfo; - } -} - -my %VisitedBinaries = (); -my @RomIncludeList; - -sub ProcessCDFList { - - my ($CDFListRef) = @_; - - foreach my $cdf (@$CDFListRef) - { - &LoadFromCDF($cdf); - } - -} - -my @padding ; -sub LoadFromCDF -{ - my $cdf; - my $binFile; - - my @BinList; - ($cdf, $binFile) = @_; - -#Load the XML and get its contents - cdfparser::LoadCDF($cdf); - -#Get all binaries from the mdf - (@BinList) = &cdfparser::GetBinaries($cdf); - - my $DynBinListRef; - my $aBinary; - my $aFile; - - my $VisitedBinaryInfoHash; - my $indent = join('', @padding); - my $binInfo; - foreach $aBinary (@BinList) - { - $VisitedBinaryInfoHash = &VisitedBinaryInfo($aBinary); - if($VisitedBinaryInfoHash) - { - next; - } - else - { - $VisitedBinaryInfoHash = \%{$VisitedBinaries{$aBinary}}; - } - - &ImageContentHandler::AddBinary($aBinary); - - $VisitedBinaryInfoHash->{Marked} = 1; - push @RomIncludeList, $aBinary; - -# Include the dynamic dependencies. - ($DynBinListRef) = cdfparser::GetDynamicDependencies($aBinary); - foreach $aFile (@$DynBinListRef) - { - if(grep $aFile, @BinList) - { -# the dynamic dependency is found in the same cdf file which -# is already loaded. - next; - } - - my $new_cdf = cdfparser::GetCDFFileName($aFile); -# In case there is no cdf describing this binary, ignore it. - if( defined $new_cdf ) - { - push @padding, "."; - LoadFromCDF($new_cdf, $aFile); - } - } - $binInfo = cdfparser::GetBinaryInfo($aBinary); - &ProcessStaticDep($binInfo->{source}, $aBinary); - } -} - -sub ProcessStaticDep -{ - my ($aBinary) = @_; - - my $aAbsFile; -# Include the static dependencies. - - my $dir = "$ENV{EPOCROOT}epoc32\\release\\"; - my $abidir = &ImageContentHandler::GetBldRomOpts("ABI_DIR"); - my $blddir = &ImageContentHandler::GetBldRomOpts("BUILD_DIR"); - - if($aBinary =~ /(.*)\\.*/) - { - $aBinary =~ s/ABI_DIR/$abidir/i; - $aBinary =~ s/BUILD_DIR/$blddir/i; - $aBinary =~ s/DEBUG_DIR/udeb/i; - } - else - { - $dir .= $abidir . "\\"; - $dir .= $blddir. "\\"; - } - $aAbsFile = $dir. $aBinary; - - if(!-f $aAbsFile) - { -# While evaluating the static dependency, check if the file is found in the -# default abi directory. Otherwise, look into the binary selection order. - my $binSelOrderRef = &ImageContentHandler::GetBinarySelectionOrder(); - my $foundFile = 0; - foreach my $newAbiDir (@$binSelOrderRef) - { - $aAbsFile =~ s/$abidir/$newAbiDir/i; - if(-f $aAbsFile) - { - $foundFile = 1; - last; - } - $abidir = $newAbiDir; - } - if($foundFile == 0) - { -#While evaluating the static dependency, check if the file is found in the -#default abi directory. Otherwise, fallback to the default ARMV5 directory. - $foundFile = fallback($abidir, \$aAbsFile); - if($foundFile == 0) - { - return; - } - - } - } - -# Collect the static dependencies of this binary. - my (@StatDepsList) = &Dep_Lister::StaticDeps($aAbsFile); - -# Remove the path portion from the file name if found to get the filename. -# This is the key into the BinaryInfo map maintained by cdfparser. - my $filename; - - if( $aBinary =~ /.*\\(\S+)/) - { - $filename = $1; - } - else - { - $filename = $aBinary; - } - - my $binaryInfoRef = cdfparser::GetBinaryInfo($filename); - - if( defined $binaryInfoRef) - { -# Mark the binary it it is a valid E32 executable. - if(defined @StatDepsList) - { - $binaryInfoRef->{IsExecutable} = 1; - } - else - { - $binaryInfoRef->{IsExecutable} = 0; - } - } - - my $VisitedBinaryInfoHash; - foreach my $aFile (@StatDepsList) - { - my $new_cdf = cdfparser::GetCDFFileName($aFile); - - if(defined($new_cdf)) - { - LoadFromCDF($new_cdf, $aFile); - } - else - { -# Include the static dependencies even if there is no mdf describing this binary - - $VisitedBinaryInfoHash = &VisitedBinaryInfo($aFile); - if( !defined ($VisitedBinaryInfoHash) ) - { - $VisitedBinaryInfoHash = \%{$VisitedBinaries{$aFile}}; - $VisitedBinaryInfoHash->{Marked} = 1; - &ImageContentHandler::AddBinary($aFile); - &ProcessStaticDep($aFile); - } - else - { - } - } - } -} - -sub VisitedBinaryInfo -{ - my ($aBinary) = @_; - my $VisitedBinaryInfoHash = \%{$VisitedBinaries{$aBinary}}; - if($VisitedBinaryInfoHash->{Marked} == 1) - { - return $VisitedBinaryInfoHash; - } - return undef; -} - -1; +# +# Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# + +# This package processes the Image Content XML, and creates an OBY file to create a Rom image. +package imagecontenthandler; + + +require Exporter; +@ISA=qw(Exporter); +@EXPORT=qw( + ParseImageContentXML + ProcessImageContent + AddBinary + GetBldRomOpts + SetBldRomOpts + GenObyFile + GetObyFiles + AddBinaryFromOby + UpdateObyBinaryStaticDep + PrintMsg + DumpBinaries +); + +use strict; +use genericparser; +use cdfparser; +use dep_lister; +use romutl; + +#Error list +my @errors; + +my %ImageContent=(); #Image details are stored in this tree +my $RootNode; #The root node of the XML root document element +my @TargetImageList; #The list of target element nodes in the XML. These are ordered based on their + # imageid (if it is a number, else, based on the availibility of Rom locations within 0..7). +my @binarySelectionArray; #This array stores the ABI directories to be looked up to select binaries. +my @ImageContentBinaries; #This list is for the biaries mentioned in Image content XML for + # keywords like, 'primary', 'secondary', 'device', 'extension', 'variant'. + +# List that contains information of binary from OBY file. This list is maintained to check if their static dependencies +# have been included already in Rom. +my %obyFileInfo=(); + +my $ImageIndex=-1; + +my @Includes; #List of included features. The included feature in this list is a hash table giving the + #Uid or the name. These features are collected either from the Image content or the CDF XMLs. +my @Excludes; #List of excluded features.The excluded feature in this list is a hash table giving the + #Uid or the name. These features are collected either from the Image content or the CDF XMLs. + +my %DefaultDirs =();#This hash table records the default ABI and the BUILD directories. These are updated in case + # the overriding buildrom options are provided e.g., -D_FULL_DEBUG or -D_PLAT=GCCE etc. + +my @BPABIPlats = &BPABIutl::BPABIutl_Plat_List; # Add the BPABI Platforms to be added + +my $isEcomPlugin=0; # This flag will be set when PLUGINs are provided in the CDF file. + +sub ParseImageContentXML +{ + my $XMLFile = shift; + + $XMLFile =~ s/\\/\//g; + $RootNode = &getRootElement($XMLFile); + + &SetImageDetails(\%ImageContent, $RootNode); +} + + +my @padding; +#This subroutine traverses the XML tree and stores the fields in the hast table %ImageContent. The keys +# are the branch names. For target nodes., it stores the nodes themselves in the hash table and doesn't +# go deeper. These nodes are processed laster. For the other nodes, it keeps traversing recursively. +# There are some special keys used to store the nodes and values in the tree. While storing an XML::DOM +# node, it sores with the keys 'nodes', while, for storing a value, it is stored with the key 'vals'. +# These are the keys used to retrieve the contents of the tree while generating the final OBY. +sub SetImageDetails +{ + my ($ImageDetailRef, $ImageNode) = @_; + my @children = &genericparser::getChildElements($ImageNode); + my $child; + my $TreeRef; + my $branch; + my $parentName = &genericparser::getElementName($ImageNode); + my $childCnt = scalar @children; + + my ($indent) = join('', @padding); + + my $val = &genericparser::getElementValue($ImageNode); + $val = Trim($val); + if($val ne "") + { + push @{$ImageDetailRef->{vals}}, $val; + } + + my $NodeRef; + foreach $child (@children) + { + $branch = &genericparser::getElementName($child); + + $NodeRef = \%{$ImageDetailRef->{$branch}}; + + if($branch eq "cdf" and $parentName eq "romscope") + { +# Record the romscope node. This node indicates the oby files or cdf files/directories +# that may be used. + push @{$NodeRef->{nodes}}, $child; + next; + } + if($branch eq "target" and $parentName eq "romtarget") + { + push @{$NodeRef->{nodes}}, $child; + next; + } + if( ($branch =~ /primary/i ) || + ($branch =~ /secondary/i) || + ($branch =~ /extension/i) || + ($branch =~ /variant/i ) || + ($branch =~ /device/i ) ) + { + next; + } + + if( $child->hasChildNodes() ) + { + $NodeRef->{hasChildren} = 1; + push @padding, "."; + SetImageDetails($NodeRef, $child); + } + else + { + $NodeRef->{hasChildren} = 0; + } + +# Get all attributes... + my $attribs = &genericparser::getNodeAttributes($child); + my $attrib; + + my $nodeName; + my $nodeVal; + my %attr=(); + my $attrLen = $attribs->getLength; + for (my $pos = 0; $pos < $attrLen;$pos++) + { + $attrib = $attribs->item($pos); + if(!$attrib) + { + next; + } + $nodeName = lc ($attrib->getName); + $nodeVal = lc ($attrib->getValue); + $attr{$nodeName}=$nodeVal; + + } + push @{$NodeRef->{vals}}, \%attr; + } + + pop @padding; +} + +my @romGeometry; #Array to store all Roms mentioned in RomGeometry +my %romGeometryHash = (); #This Hash table records the indices in @romGeometry array, keying on their Ids. + +my $curRomImageIndex; #This scalar records the current Rom image being processed. An binary encountered + # becomes part of the Rom image corresponding to this partition. + +# This subroutine associates the RomGeometry and the RomTarget sub-trees to set indices for the Rom-target +# nodes.It stores the Image content XML entries for primary/secondary/device/extension/variant keywords. +# It also stores the features that are included/excluded in Image content XML. + +sub ProcessImageContent +{ + my $TotalImages = &ProcessRomGeometry(); + + my @trgList; + if( defined @{$ImageContent{romtarget}{target}{nodes}}) + { + @trgList = @{$ImageContent{romtarget}{target}{nodes}}; + } + +# Go through the romgeometry to find the location of each image. The valid IDs are 0 through 7. + + foreach my $trg (@trgList) + { +# The ID field in romgeometry can be an integer in the range 0 through 7. +# If it is not a number, its location is assumed as its sequence number + my $imageid = &genericparser::getAttrValue($trg, "imageid"); + if($imageid =~ /Any/i) + { + next; + } + elsif(exists $romGeometryHash{$imageid}) + { + $ImageIndex = $romGeometryHash{$imageid}; + push @{$TargetImageList[$ImageIndex]} , $trg; + } + } + +# Romscope - update the maps if the files and directories are mentioned. + my @romScopeNodes; + if(defined @{$ImageContent{romscope}{cdf}{nodes}}) + { + @romScopeNodes = @{$ImageContent{romscope}{cdf}{nodes}}; + } + + my $type; + my $file; + my $dir; + foreach my $aNode (@romScopeNodes) + { + $type = &genericparser::getAttrValue($aNode, "type"); + if( $type =~ /dir/i) + { + $dir = &genericparser::getElementValue($aNode); + &cdfparser::CreateCDFFileBinaryMapFromDir($dir); + } + elsif($type =~ /file/i) + { + $file = &genericparser::getElementValue($aNode); + &cdfparser::CreateCDFFileBinaryMap($file); + } + } + + my $availablePos = 0; + foreach my $trg (@trgList) + { + if(&genericparser::getAttrValue($trg, "imageid") =~ /Any/i) + { + while($availablePos < $TotalImages) + { + if( !defined($TargetImageList[$availablePos][0]) ) + { + push @{$TargetImageList[$availablePos]}, $trg; + last; + } + $availablePos++; + } + } + } + + my $pos = 0; + while( $pos < 8) + { + if( defined $TargetImageList[$pos][0] ) + { +# Record the current Rom image index so that the binaries are included in the corresponding +# Rom image. +# The romGeometry and TargetImageList arrays are associated both being indexed on +# the Rom-image index. + + $curRomImageIndex = $pos; + &ProcessTarget($pos, \@{$TargetImageList[$pos]}); + } + $pos++; + } + +# Pick the primary/secondary/device binaries + my @nodes = &genericparser::getNodeFromTree($RootNode, "options", "primary", "file"); + if( defined @nodes) + { + &SaveImageContentBinaries(\@nodes, "primary"); + } + + @nodes = &genericparser::getNodeFromTree($RootNode, "options", "secondary", "file"); + if( defined @nodes) + { + &SaveImageContentBinaries(\@nodes, "secondary"); + } + + @nodes = &genericparser::getNodeFromTree($RootNode, "options", "extension", "file"); + if( defined @nodes) + { + &SaveImageContentBinaries(\@nodes, "extension"); + } + + @nodes = &genericparser::getNodeFromTree($RootNode, "options", "variant", "file"); + if( defined @nodes) + { + &SaveImageContentBinaries(\@nodes, "variant"); + } + + @nodes = &genericparser::getNodeFromTree($RootNode, "options", "device", "file"); + if( defined @nodes) + { + &SaveImageContentBinaries(\@nodes, "device"); + } + + foreach my $imgBin (@ImageContentBinaries) + { + &ProcessStaticDep($imgBin->{source}); + } + +# Pick the binary selection order + if (exists($ImageContent{options}{binaryselectionorder}{vals})) + { + my ($abiDirs) = @{$ImageContent{options}{binaryselectionorder}{vals}}; + @binarySelectionArray = split(',', $abiDirs); + @binarySelectionArray = Trim(@binarySelectionArray); + + } + + my $featureList = &cdfparser::GetIncludedFeatureList(); + foreach my $feature (@$featureList) + { + push @Includes, $feature; + } + + $featureList = &cdfparser::GetExcludedFeatureList(); + foreach my $feature (@$featureList) + { + push @Excludes, $feature; + } +} + +#Arrange the Rom-geometry according to their Id when they are numbers. The named images +#are arranged starting from the empty slots in Rom geometry array. +sub ProcessRomGeometry +{ + my $RomImageCount = 0; + my $pos = 0; + while($pos < 8) + { + $romGeometry[$pos++] = undef; + } + + my @roms = @{$ImageContent{romgeometry}{image}{vals}}; + $RomImageCount = scalar (@roms); + my @namedImages; + +# Visit all images and allocate them the indices they mention. + foreach my $img (@roms) + { + if($img->{id} =~ /(\d+)/) + { + $pos = $1; + if( defined($romGeometry[$pos]) ) + { + print "Error: $romGeometry[$pos]->{id} and $img->{id} cant be allocated the same position\n"; + exit; + } + $romGeometry[$pos] = $img; + +# Record the index of this Rom + $romGeometryHash{$img->{id}} = $pos; + } + else + { +# These are the named images that are allocated there positions sequentially starting from +# the first available empty position + push @namedImages, $img; + } + } + +# Revisit the images and allocate the remaining (unallocated) positions. + + $pos = 0; + my $namedImageCount = scalar (@namedImages); + my $firstNamedImgIdx = 0; + my $img; + while( ($pos < 8) and ($namedImageCount > 0) ) + { + if( $romGeometry[$pos] ) + { +# skip the positions already allocated. + $pos++; + next; + } + $img = $namedImages[$firstNamedImgIdx]; + $romGeometry[$pos] = $img; + +# Record the index of this Rom + $romGeometryHash{$img->{id}} = $pos; + + $pos++;$firstNamedImgIdx++; + $namedImageCount--; + } + + return $RomImageCount; +} + +my @ObyFileList; + +#This subrouting processes the target nodes that may include OBYs/CDFs or features. For CDFs, the satic/dynamic +# dependencies are evaluated. + +sub ProcessTarget +{ + my ($ImgPos , $trgNodesRef) = @_; + my @cdfFileList; + +# For all the 'target' nodes associated with an image in romgeometry at the given index... +# The link between a target and an image in romGeometry is the image id. If the imageid +# of a target is 'Any', then the first available image in romGeometry is allocated to +# that target. + + foreach my $target (@$trgNodesRef) + { + +# Fetch any cdfs included within the Image Content file + my @cdfs = &getNodeFromTree($target, "include","cdf"); + + my $type; + my $file; + my $dir; + foreach my $cdfNode (@cdfs) + { + $type = &genericparser::getAttrValue($cdfNode, "type"); + + if( !($type) || ($type eq "file") ) + { + $file = &genericparser::getElementValue($cdfNode); + push @cdfFileList, $file; + } + elsif($type eq "dir") + { + $dir = &genericparser::getElementValue($cdfNode); + &cdfparser::CreateCDFFileBinaryMapFromDir($dir); + } + } + +# Collect all the obey files mentioned in this 'target' node. + my @obys = &getNodeFromTree($target, "include","obyFile"); + foreach my $obyNode (@obys) + { + $file = &genericparser::getElementValue($obyNode); + push @ObyFileList, $file; + } + + &CollectFeatures($target, 1, \@Includes); + &CollectFeatures($target, 0, \@Excludes); + } + + ProcessCDFList(\@cdfFileList); +} + +# This subroutine updates the include or exclude feature list collected from Image content XML. +sub CollectFeatures +{ +# Collect all the features included/excluded in this 'target' node. + + my ($target, $Inc, $IncludeExcludeListRef) = @_; + my $IncExcStr; + if($Inc == 1) + { + $IncExcStr = "include"; + } + else + { + $IncExcStr = "exclude"; + } + + my @nodes = &getNodeFromTree($target, $IncExcStr,"feature"); + + foreach my $node (@nodes) + { + my %aFeatureInfo = (); + my $isValidFeature = 0; + my $feature = &genericparser::getAttrValue($node, "name"); + + if($Inc) + { +# Mark the feature included. + $aFeatureInfo{include} = 1; + } + else + { +# Mark the feature excluded. + $aFeatureInfo{exclude} = 1; + } + + if(defined $feature and $feature ne "") + { + $aFeatureInfo{name}= $feature; + $aFeatureInfo{uid} = undef; + $isValidFeature = 1; + } + else + { + $feature = &genericparser::getAttrValue($node, "uid"); + if(!defined $feature or $feature eq "") + { + print "Warning: Neither feature name nor uid is defined \n"; + } + else + { + if(&featureparser::ValidateUIDValue($feature)) + { + $feature = &featureparser::ConvertHexToDecimal($feature); + $aFeatureInfo{uid}= $feature; + $aFeatureInfo{name}= undef; + $isValidFeature = 1; + } + else + { + print "The uid value $feature specified in the Image Content Description is not a valid number\n"; + } + } + } + + if($isValidFeature) + { + push @$IncludeExcludeListRef, \%aFeatureInfo; + } + } +} + +sub DumpImageDetails +{ + my ($HRef) = @_; + my %hash = %$HRef; + my $ChildHRef; + + foreach my $Key (keys %hash) + { + if($Key eq "hasChildren" || $Key eq "vals") + { + next; + } + my $indent = join('', @padding); + &PrintMsg ($indent. $Key); + if($hash{$Key}{hasChildren} == 1) + { + push @padding, "."; + &PrintMsg ("\n"); + $ChildHRef = \%{$hash{$Key}}; + &DumpImageDetails($ChildHRef); + } + elsif( defined ($hash{$Key}{vals}) ) + { + &PrintMsg ("\nVals $hash{$Key}{vals}\n"); + push @padding, "."; + $indent = join('', @padding); + my @array = @{$hash{$Key}{vals}}; + &PrintMsg ("array len = " . scalar(@array) . "\n"); + foreach my $attrib ( @array ) + { + foreach my $key1 (keys %$attrib) + { + &PrintMsg ($indent . $Key. " ". "$key1=$$attrib{$key1}\n"); + } + &PrintMsg ("\n"); + } + } + elsif( defined (@{$hash{$Key}{nodes}}) ) + { + my $node = $hash{$Key}{nodes}[0]; + &PrintMsg ("{". scalar(@{$hash{$Key}{nodes}})."}\n"); + } + } + pop @padding; +} + +sub CheckErrors +{ + if($#errors > -1) + { + &PrintMsg ("errors..........$#errors \n"); + foreach (@errors) + { + &PrintMsg ($_ ."\n"); + } + exit; + } +} + +my @ImageBinaryList;#2d array storing the list of binaries per rom image +sub AddBinary +{ + my ($binaryName) = @_; + { + push @{$ImageBinaryList[$curRomImageIndex]}, $binaryName; + } +} + +sub SetBldRomOpts +{ + my ($key, $value) = @_; + if( $key eq undef ) + { +# The default ABI directory is armv5 unless specified otherwise in the buildrom command-line. +# The default build directory is urel unless specified otherwise in the buildrom command-line. + $DefaultDirs{ABI_DIR} = 'ARMV5'; + $DefaultDirs{BUILD_DIR}='urel'; + + $DefaultDirs{DEST_DIR}= "\/sys\/bin"; + + } + else + { +# trim the value for leading/trailing whitespace + $value = Trim($value); + $DefaultDirs{$key} = $value; + } +} + +sub Trim() +{ + my @out = @_; + for (@out) { + s/^\s+//; + s/\s+$//; + } + return wantarray ? @out : $out[0]; +} + +sub GetBldRomOpts +{ + my ($key) = @_; + return $DefaultDirs{$key}; +} + +sub DumpBinaries +{ + &PrintMsg ("***********Binaries in ROM***********\n"); + my $img_idx = 0; + while ($img_idx < 8 and defined ($ImageBinaryList[$img_idx])) + { + my @list = @{$ImageBinaryList[$img_idx]}; + &PrintMsg ("Image $img_idx has ". scalar (@list ) . " binaries\n"); + foreach my $bin (@list) + { + &PrintMsg ("file[$img_idx]=$bin\n"); + } + $img_idx++; + } + + &PrintMsg ("***********END***********\n"); +} + +sub PrintMsg +{ + my ($msg) = @_; + print "$msg"; +} + +# This subroutine is used to generate OBY-contents based on contents of the Image content XML. The image content XML +# may have, in turn, included other OBYs/CDFs. These contents are appended to the Phase-I OBY file (where, the +# Phase-I OBY file is generated by the preprocessor which is the conglomeration of all the buildrom supplied OBY files). +sub GenObyFile +{ + my ($ObyFileName) = @_; + open (OBYFH, ">>$ObyFileName") or die("* Can't open $ObyFileName\n"); + my $binRef; + my $line; + my $index; + my $new_src_path; + my $exec_src_path = &get_epocroot;#This is the Executable source path + $exec_src_path .= "epoc32\/release\/"; + my $abidir = $DefaultDirs{ABI_DIR}; + my $blddir = $DefaultDirs{BUILD_DIR}; + + GenObyHeader(*OBYFH); + + for($index = 0;$index < 8;$index++) + { + if( !defined $romGeometry[$index] ) + { + next; + } + + $line = "rom_image $index "; + $line .= $romGeometry[$index]{name} . " "; + $line .= "size=" . $romGeometry[$index]{size} . " "; + if( $romGeometry[$index]{type} =~ /nonxip/) + { + $line .= " non-xip "; + } + else + { + $line .= " xip "; + } + + $line .= $romGeometry[$index]{compression} . " "; + if($romGeometry[$index]{extension} eq "yes") + { + $line .= " extension "; + } + + $line .= "\n"; + + print OBYFH $line; + + $line = "ROM_IMAGE[$index] {\n"; #Start of contents of this image + print OBYFH $line; + + foreach my $binary (@{$ImageBinaryList[$index]}) { + $binRef = &cdfparser::GetBinaryInfo($binary); + if( defined ($binRef) and $binRef->{IsFoundInCDF}) + { + if(exists $binRef->{default}) + { + $line = "DEFAULT_LANGUAGE $binRef->{default} \n"; + print OBYFH "$line"; + } + + if(exists $binRef->{language}) + { + my $langCodes = $binRef->{language}; + foreach my $lang (@$langCodes) + { + $line = "LANGUAGE_CODE $lang \n"; + print OBYFH "$line"; + } + } + +# Replace the BUILD_DIR with udeb or urel +# Default BUILD_DIR is urel and can be overridden by using cmd line option '_FULL_DEBUG' +# If a binary is to be picked always from udeb, then the src path in CDF must be mentioned +# as udeb e.g. abi_dir\udeb\drtaeabi.dll, in which case, the mentioned dir +# is picked as it is. + + $new_src_path = $binRef->{source}; + + $new_src_path =~ s/ABI_DIR/$abidir/i; + $new_src_path =~ s/BUILD_DIR/$blddir/i; + $new_src_path =~ s/DEBUG_DIR/udeb/i; + + $new_src_path =~ s/epocroot/EPOCROOT/; + $new_src_path =~ s/zresource/ZRESOURCE/; + $new_src_path =~ s/zprivate/ZPRIVATE/; + $new_src_path =~ s/zsystem/ZSYSTEM/; + + + my $FileFound = 0; + + if($binRef->{IsExecutable}) + { + $new_src_path = $exec_src_path . $new_src_path; + if(!-f $new_src_path) + { + foreach my $newAbiDir (@binarySelectionArray) + { + $new_src_path =~ s/$abidir/$newAbiDir/i; + if(-f $new_src_path) + { + $FileFound = 1; + last; + } + $abidir = $newAbiDir; + } + + if( !$FileFound ) + { + $FileFound = fallback($abidir, \$new_src_path); + if( !$FileFound ) + { + print "Missing file $binRef->{source} \n"; + $new_src_path = $binRef->{source}; + } + + } + } +# compress options + if(exists $binRef->{compress} and ($binRef->{compress} eq "uncompress") ) + { + $line = "fileuncompress="; + } + elsif($binRef->{compress} eq "compress") + { + $line = "filecompress="; + } + elsif( exists $binRef->{dll}) + { + $line = "dll="; + } +# Checks the plugin type + elsif( exists $binRef->{type} and $binRef->{type} eq "plugin") + { + if (exists $binRef->{plugin_name}) + { + $isEcomPlugin=1; + $line = "__$binRef->{plugin_name}_PLUGIN(ABI_DIR\/BUILD_DIR,ECOM_BIN_DIR,DATAZ_,ECOM_RSC_DIR,$binRef->{id},$binRef->{id})\n"; + } + } + else + { + $isEcomPlugin=0; + $line = "file="; + } + + if (!$isEcomPlugin) + { + $line .= $new_src_path . " "; + $line .= $binRef->{destination}; + } + + +# stack,heap,fixed,priority,uid,dll,dlldatatop + if( exists $binRef->{stack}) + { + $line .= " stack " . $binRef->{stack}; + } + if( exists $binRef->{heapmin}) + { + $line .= " heapmin " . $binRef->{heapmin}; + } + if( exists $binRef->{heapmax}) + { + $line .= " heapmax " . $binRef->{heapmax}; + } + if( exists $binRef->{fixed}) + { + $line .= " fixed"; + } + if( exists $binRef->{priority}) + { + $line .= " priority " . $binRef->{priority}; + } + if( exists $binRef->{uid1}) + { + $line .= " uid1 " . $binRef->{uid1}; + } + if( exists $binRef->{uid2}) + { + $line .= " uid2 " . $binRef->{uid2}; + } + if( exists $binRef->{uid3}) + { + $line .= " uid3 " . $binRef->{uid3}; + } + if( exists $binRef->{dlldatatop}) + { + $line .= " dlldatatop ". $binRef->{dlldatatop}; + } + if( exists $binRef->{customisable} and $binRef->{customisable} eq "true") + { + $line .= " patched "; + } + } + else + { + my $type = $binRef->{type}; + if($type =~ /normal/i) + { + $line = "data="; + } + if($type =~ /aif/i) + { + $line = "aif="; + } + elsif($type =~ /compressedbitmap/i) + { + $line = "compressed-bitmap="; + } + elsif($type =~ /autobitmap/i) + { + $line = "auto-bitmap="; + } + elsif($type =~ /bitmap/i) + { + $line = "bitmap="; + } + + if(exists $binRef->{multilinguify}) + { + my $extension; + my $srcNameWithoutExt; + my $dstNameWithoutExt; + + if($new_src_path =~ /(.*)\.(.*)/) + { + $srcNameWithoutExt = $1; + $extension = $2; + } + if($binRef->{destination} =~ /(.*)\.(.*)/) + { + $dstNameWithoutExt = $1; + } + + $line .= "MULTI_LINGUIFY("; + $line .= $extension . " "; + $line .= $srcNameWithoutExt . " "; + $line .= $dstNameWithoutExt; + $line .= ") "; + } + else + { + $line .= $new_src_path . " "; + $line .= $binRef->{destination}; + } + } + + $line .= "\n"; + print OBYFH $line; + } + else + { + #Check if the binary is from ImageContent XML file. + my $imagecontentbin = 0; + foreach my $bin (@ImageContentBinaries) { + my $source; + if( $bin->{source} =~ /.*[\\\/](\S+)/) + { + $source = $1; + } + if (grep /$binary/i, $source) {#Skip the binary that is already included in the OBY Header + $imagecontentbin = 1; + next; + } + } + + if ($imagecontentbin) { + next; + } + my $obyInfo = &ImageContentHandler::GetObyBinaryInfo($binary); + if(!defined $obyInfo) + { + $line = "file=" . $exec_src_path. $DefaultDirs{ABI_DIR}. "\/" . $DefaultDirs{BUILD_DIR}. "\/". $binary. " "; + $line .= $DefaultDirs{DEST_DIR}. "\/". $binary; + $line .= "\n"; + print OBYFH $line; + } + } + } + $line = "\n}\n"; + print OBYFH $line; + } + close OBYFH; +} + +#Sets default target to ARMV5 directory if the requested binary is not found +sub fallback{ + + my ($abidir, $abiFileRef) = @_; + my $foundFile=0; + foreach my $BpabiPlat (@BPABIPlats) + { + if ($$abiFileRef =~ /^(.*)[\/\\]$BpabiPlat[\/\\](.*)$/) + { + $$abiFileRef =~ s/$abidir/ARMV5/i; + if(-f $$abiFileRef) + { + $foundFile = 1; + last; + } + } + } + return $foundFile; +} + +# This subroutine generates the Rom configuration details like, 'bootbinary', 'romlinearbase', romalign, +# 'kerneldataaddress', 'kernelheapmin' etc. +sub GenObyHeader +{ + my ($fh) = @_; + my $line; + +# version + if( defined @{$ImageContent{version}{vals}}) + { + my $ver = @{$ImageContent{version}{vals}}[0]; + if(defined $ver) + { + $line = "version=$ver\n"; + print $fh $line; + } + } + +# romchecksum + if( defined @{$ImageContent{romchecksum}{vals}}) + { + my $cksum = @{$ImageContent{romchecksum}{vals}}[0]; + if(defined $cksum) + { + $line = "romchecksum=$cksum\n"; + print $fh $line; + } + } + +# time + if( defined @{$ImageContent{time}{vals}}) + { + my $time = @{$ImageContent{time}{vals}}[0]; + if(defined $time) + { + $line = "time=ROMDATE $time\n"; + print $fh $line; + } + } + + +# The Binary selection order + if(scalar @binarySelectionArray ) + { + my $abilist = join (',', @binarySelectionArray); + $line = "\nBINARY_SELECTION_ORDER $abilist\n"; + print $fh $line; + } + +# trace + if( defined @{$ImageContent{options}{trace}{vals}}) + { + my @traceFlags = @{$ImageContent{options}{trace}{vals}}; + if(scalar @traceFlags) + { + $line = "trace $traceFlags[0]\n"; + print $fh $line; + } + } + +# The bootbinary + if( defined @{$ImageContent{options}{bootbinary}{vals}}) + { + my $binary; + my @bootbin = @{$ImageContent{options}{bootbinary}{vals}}; + if(scalar @bootbin) + { + $binary = $bootbin[0]; + $binary =~ s/abi_dir/ABI_DIR/; + $line = "bootbinary=$binary\n"; + print $fh $line; + } + } + + +# dataaddress + if( defined @{$ImageContent{options}{dataaddress}{vals}}) + { + my @dataAddr = @{$ImageContent{options}{dataaddress}{vals}}; + if(scalar @dataAddr) + { + $line = "dataaddress=$dataAddr[0]\n"; + print $fh $line; + } + } + +# debugport + if( defined @{$ImageContent{options}{debugport}{vals}}) + { + my @dgbPort = @{$ImageContent{options}{debugport}{vals}}; + if(scalar @dgbPort) + { + $line = "debugport=$dgbPort[0]\n"; + print $fh $line; + } + } + +# defaultstackreserve + if( defined @{$ImageContent{options}{defaultstackreserve}{vals}}) + { + my @defStackRes = @{$ImageContent{options}{defaultstackreserve}{vals}}; + if(scalar @defStackRes) + { + $line = "defaultstackreserve=$defStackRes[0]\n"; + print $fh $line; + } + } + +# wrapper + if( defined @{$ImageContent{options}{wrapper}{vals}}) + { + my %tbl = @{$ImageContent{options}{wrapper}{vals}}[0]; + if(exists $tbl{epoc}) + { + $line = "epocwrapper\n"; + print $fh $line; + } + elsif(exists $tbl{coff}) + { + $line = "coffwrapper\n"; + print $fh $line; + } + elsif(exists $tbl{none}) + { + $line = "nowrapper\n"; + print $fh $line; + } + } + +# kernel options + my $val; + if( defined @{$ImageContent{options}{kernel}{name}{vals}}) + { + $val = @{$ImageContent{options}{kernel}{name}{vals}}[0]; + $line = "kernelromname=$val\n"; + print $fh $line; + } + if( defined @{$ImageContent{options}{kernel}{dataaddress}{vals}}) + { + $val = @{$ImageContent{options}{kernel}{dataaddress}{vals}}[0]; + $line = "kerneldataaddress=$val\n"; + print $fh $line; + } + if( defined @{$ImageContent{options}{kernel}{trace}{vals}}) + { + $val = @{$ImageContent{options}{kernel}{trace}{vals}}[0]; + $line = "kerneltrace $val\n"; + print $fh $line; + } + if( defined @{$ImageContent{options}{kernel}{heapmin}{vals}}) + { + $val = @{$ImageContent{options}{kernel}{heapmin}{vals}}[0]; + $line = "kernelheapmin=$val\n"; + print $fh $line; + } + if( defined @{$ImageContent{options}{kernel}{heapmax}{vals}}) + { + $val = @{$ImageContent{options}{kernel}{heapmax}{vals}}[0]; + $line = "kernelheapmax=$val\n"; + print $fh $line; + } +# romlinearbase + if( defined @{$ImageContent{options}{romlinearbase}{vals}}) + { + my @romLinBase = @{$ImageContent{options}{romlinearbase}{vals}}; + if(scalar @romLinBase) + { + $line = "romlinearbase=$romLinBase[0]\n"; + print $fh $line; + } + } + +# romalign + if( defined @{$ImageContent{options}{romalign}{vals}}) + { + my @romAlign = @{$ImageContent{options}{romalign}{vals}}; + if(scalar @romAlign ) + { + $line = "romalign=$romAlign[0]\n"; + print $fh $line; + } + } + + + + +# autosize keyword with the block size + if( defined @{$ImageContent{options}{autosize}{vals}}) + { + my @autoSz = @{$ImageContent{options}{autosize}{vals}}; + if(scalar @autoSz ) + { + $line = "autosize=$autoSz[0]\n"; + print $fh $line; + } + } + +# coreimage keyword with the coreimage name. + if( defined @{$ImageContent{options}{coreimage}{vals}}) + { + my @coreImg = @{$ImageContent{options}{coreimage}{vals}}; + if(scalar @coreImg) + { + $line = "coreimage=$coreImg[0]\n"; + print $fh $line; + } + } + + + + foreach my $imgBin (@ImageContentBinaries) + { + $line = $imgBin->{keyword}; + my $srcPath = $imgBin->{source}; + $srcPath =~ s/abi_dir/ABI_DIR/; + $srcPath =~ s/kernel_dir/KERNEL_DIR/; + $srcPath =~ s/debug_dir/DEBUG_DIR/; + $srcPath =~ s/build_dir/BUILD_DIR/; + if(! ($imgBin->{keyword} =~ /secondary/i) ) + { +# VARID mentioned for primary, device, extension and variant keywords. + $line .= "[VARID]" ; + } + $line .= "=" . $srcPath . "\t\t" . $imgBin->{destination}; + for my $key (keys %$imgBin) + { + if( ($key =~ /keyword/i) || + ($key =~ /source/i) || + ($key =~ /destination/i)) + { +# These keys are already taken care. + next; + } + +# Write the rest of the keywords if any, (e.g., 'fixed' or HEAPMAX(0x40000) ) to the oby line. + $line .= " ".($key); + if( defined $imgBin->{$key}) + { + $line .= "(". $imgBin->{$key}. ") "; + } + } + print $fh "$line\n"; + } +} + +sub GetObyFiles +{ + return \@ObyFileList; +} + +sub GetBinarySelectionOrder +{ + return \@binarySelectionArray; +} + +sub GetFeatures() +{ + my %FeatureMap = (); + my @FeatList; + my $featRef; + my $uid; + foreach my $feat (@Includes) + { + if($feat->{name}) + { + $uid = &featureparser::getFeatureUID($feat->{name}); + if(!defined $uid) + { + print "Error: Feature $feat->{name} not found in feature list XML\n"; + next; + } + $feat->{uid} = $uid; + } + else + { + $uid = $feat->{uid}; + if(!&featureparser::getFeatureInfo($uid)) + { + print "Error: Feature Uid $uid not found in feature list XML\n"; + next; + } + } + + $featRef = $FeatureMap{$uid}; + if( $featRef->{include} == 1 ) + { +# Already added to the final feature list + } + else + { + $FeatureMap{$uid} = $feat; + push @FeatList, $feat; + } + } + + foreach my $feat (@Excludes) + { + if($feat->{name}) + { + $uid = &featureparser::getFeatureUID($feat->{name}); + if(!defined $uid) + { + print "Error: Feature $feat->{name} not found in feature list XML\n"; + next; + } + $feat->{uid} = $uid; + } + else + { + $uid = $feat->{uid}; + if(!&featureparser::getFeatureInfo($uid)) + { + print "Error: Feature Uid $uid not found in feature list XML\n"; + next; + } + } + + $featRef = $FeatureMap{$uid}; + if( $featRef->{include} == 1 ) + { + print "Error:The feature Uid $uid was added into the include as well as exclude list\n"; + next; + } + elsif($featRef->{exclude} == 1) + { +# Already added to the final feature list + next; + } + else + { + $FeatureMap{$uid} = $feat; + push @FeatList, $feat; + } + } + return \@FeatList; +} + +sub AddBinaryFromOby +{ + my $aBinary = lc shift; + my $aFullPath = lc shift; + + my $bin = \%{$obyFileInfo{$aBinary}}; + $bin->{IsFoundInOby} = 1; + $bin->{fullpath} = $aFullPath; +} + +sub GetObyBinaryInfo +{ + my $aBinary = lc shift; + + my $aBinaryInfoHash = \%{$obyFileInfo{$aBinary}}; + + if( $aBinaryInfoHash->{IsFoundInOby} == 1) + { + return $aBinaryInfoHash; + } + return undef; +} + +sub UpdateObyBinaryStaticDep +{ +# Go through the files added from Oby to see if any of their static +# dependencies need to be resolved. + + foreach my $obyBin (keys %obyFileInfo) + { + if(!defined (&VisitedBinaryInfo($obyBin)) ) + { + &ProcessStaticDep($obyFileInfo{$obyBin}{fullpath}); + } + } +} + +sub SaveImageContentBinaries +{ + my ($binaryListRef, $aKeyword) = @_; + + foreach my $node (@$binaryListRef) + { + my %binInfo = (); + +# The keywords being primary, secondary, extension, variant and device + $binInfo{keyword} = $aKeyword; + + my @children = &genericparser::getChildElements($node); + + foreach my $child (@children) + { + my $name = &genericparser::getElementName($child); + my $val = &genericparser::getElementValue($child); + $binInfo{$name} = $val; + } + push @ImageContentBinaries, \%binInfo; + } +} + +my %VisitedBinaries = (); +my @RomIncludeList; + +sub ProcessCDFList { + + my ($CDFListRef) = @_; + + foreach my $cdf (@$CDFListRef) + { + &LoadFromCDF($cdf); + } + +} + +my @padding ; +sub LoadFromCDF +{ + my $cdf; + my $binFile; + + my @BinList; + ($cdf, $binFile) = @_; + +#Load the XML and get its contents + cdfparser::LoadCDF($cdf); + +#Get all binaries from the mdf + (@BinList) = &cdfparser::GetBinaries($cdf); + + my $DynBinListRef; + my $aBinary; + my $aFile; + + my $VisitedBinaryInfoHash; + my $indent = join('', @padding); + my $binInfo; + foreach $aBinary (@BinList) + { + $VisitedBinaryInfoHash = &VisitedBinaryInfo($aBinary); + if($VisitedBinaryInfoHash) + { + next; + } + else + { + $VisitedBinaryInfoHash = \%{$VisitedBinaries{$aBinary}}; + } + + &ImageContentHandler::AddBinary($aBinary); + + $VisitedBinaryInfoHash->{Marked} = 1; + push @RomIncludeList, $aBinary; + +# Include the dynamic dependencies. + ($DynBinListRef) = cdfparser::GetDynamicDependencies($aBinary); + foreach $aFile (@$DynBinListRef) + { + if(grep $aFile, @BinList) + { +# the dynamic dependency is found in the same cdf file which +# is already loaded. + next; + } + + my $new_cdf = cdfparser::GetCDFFileName($aFile); +# In case there is no cdf describing this binary, ignore it. + if( defined $new_cdf ) + { + push @padding, "."; + LoadFromCDF($new_cdf, $aFile); + } + } + $binInfo = cdfparser::GetBinaryInfo($aBinary); + &ProcessStaticDep($binInfo->{source}, $aBinary); + } +} + +sub ProcessStaticDep +{ + my ($aBinary) = @_; + + my $aAbsFile; +# Include the static dependencies. + + my $dir = &get_epocroot()."epoc32\/release\/"; + my $abidir = &ImageContentHandler::GetBldRomOpts("ABI_DIR"); + my $blddir = &ImageContentHandler::GetBldRomOpts("BUILD_DIR"); + + if($aBinary =~ /(.*)[\\\/].*/) + { + $aBinary =~ s/ABI_DIR/$abidir/i; + $aBinary =~ s/BUILD_DIR/$blddir/i; + $aBinary =~ s/DEBUG_DIR/udeb/i; + } + else + { + $dir .= $abidir . "\/"; + $dir .= $blddir. "\/"; + } + $aAbsFile = $dir. $aBinary; + + if(!-f $aAbsFile) + { +# While evaluating the static dependency, check if the file is found in the +# default abi directory. Otherwise, look into the binary selection order. + my $binSelOrderRef = &ImageContentHandler::GetBinarySelectionOrder(); + my $foundFile = 0; + foreach my $newAbiDir (@$binSelOrderRef) + { + $aAbsFile =~ s/$abidir/$newAbiDir/i; + if(-f $aAbsFile) + { + $foundFile = 1; + last; + } + $abidir = $newAbiDir; + } + if($foundFile == 0) + { +#While evaluating the static dependency, check if the file is found in the +#default abi directory. Otherwise, fallback to the default ARMV5 directory. + $foundFile = fallback($abidir, \$aAbsFile); + if($foundFile == 0) + { + return; + } + + } + } + +# Collect the static dependencies of this binary. + my (@StatDepsList) = &Dep_Lister::StaticDeps($aAbsFile); + +# Remove the path portion from the file name if found to get the filename. +# This is the key into the BinaryInfo map maintained by cdfparser. + my $filename; + + if( $aBinary =~ /.*[\\\/](\S+)/) + { + $filename = $1; + } + else + { + $filename = $aBinary; + } + + my $binaryInfoRef = cdfparser::GetBinaryInfo($filename); + + if( defined $binaryInfoRef) + { +# Mark the binary it it is a valid E32 executable. + if(defined @StatDepsList) + { + $binaryInfoRef->{IsExecutable} = 1; + } + else + { + $binaryInfoRef->{IsExecutable} = 0; + } + } + + my $VisitedBinaryInfoHash; + foreach my $aFile (@StatDepsList) + { + my $new_cdf = cdfparser::GetCDFFileName($aFile); + + if(defined($new_cdf)) + { + LoadFromCDF($new_cdf, $aFile); + } + else + { +# Include the static dependencies even if there is no mdf describing this binary + + $VisitedBinaryInfoHash = &VisitedBinaryInfo($aFile); + if( !defined ($VisitedBinaryInfoHash) ) + { + $VisitedBinaryInfoHash = \%{$VisitedBinaries{$aFile}}; + $VisitedBinaryInfoHash->{Marked} = 1; + &ImageContentHandler::AddBinary($aFile); + &ProcessStaticDep($aFile); + } + else + { + } + } + } +} + +sub VisitedBinaryInfo +{ + my ($aBinary) = @_; + my $VisitedBinaryInfoHash = \%{$VisitedBinaries{$aBinary}}; + if($VisitedBinaryInfoHash->{Marked} == 1) + { + return $VisitedBinaryInfoHash; + } + return undef; +} + +1;