diff options
Diffstat (limited to 'BaseTools/Source/Python/GenFds/FfsInfStatement.py')
| -rw-r--r-- | BaseTools/Source/Python/GenFds/FfsInfStatement.py | 2268 |
1 files changed, 1134 insertions, 1134 deletions
diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py index ec9713484e..4462c337b0 100644 --- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py +++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py @@ -1,1134 +1,1134 @@ -## @file
-# process FFS generation from INF statement
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-# Copyright (c) 2014-2016 Hewlett-Packard Development Company, L.P.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from . import Rule
-import Common.LongFilePathOs as os
-from io import BytesIO
-from struct import *
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-from .Ffs import SectionSuffix,FdfFvFileTypeToFileType
-import subprocess
-import sys
-from pathlib import Path
-from . import Section
-from . import RuleSimpleFile
-from . import RuleComplexFile
-from CommonDataClass.FdfClass import FfsInfStatementClassObject
-from Common.MultipleWorkspace import MultipleWorkspace as mws
-from Common.DataType import SUP_MODULE_USER_DEFINED
-from Common.DataType import SUP_MODULE_HOST_APPLICATION
-from Common.StringUtils import *
-from Common.Misc import PathClass
-from Common.Misc import GuidStructureByteArrayToGuidString
-from Common.Misc import ProcessDuplicatedInf
-from Common.Misc import GetVariableOffset
-from Common import EdkLogger
-from Common.BuildToolError import *
-from .GuidSection import GuidSection
-from .FvImageSection import FvImageSection
-from Common.Misc import PeImageClass
-from AutoGen.GenDepex import DependencyExpression
-from PatchPcdValue.PatchPcdValue import PatchBinaryFile
-from Common.LongFilePathSupport import CopyLongFilePath
-from Common.LongFilePathSupport import OpenLongFilePath as open
-import Common.GlobalData as GlobalData
-from .DepexSection import DepexSection
-from Common.Misc import SaveFileOnChange
-from Common.Expression import *
-from Common.DataType import *
-
-## generate FFS from INF
-#
-#
-class FfsInfStatement(FfsInfStatementClassObject):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- FfsInfStatementClassObject.__init__(self)
- self.TargetOverrideList = []
- self.ShadowFromInfFile = None
- self.KeepRelocFromRule = None
- self.InDsc = True
- self.OptRomDefs = {}
- self.PiSpecVersion = '0x00000000'
- self.InfModule = None
- self.FinalTargetSuffixMap = {}
- self.CurrentLineNum = None
- self.CurrentLineContent = None
- self.FileName = None
- self.InfFileName = None
- self.OverrideGuid = None
- self.PatchedBinFile = ''
- self.MacroDict = {}
- self.Depex = False
-
- ## GetFinalTargetSuffixMap() method
- #
- # Get final build target list
- def GetFinalTargetSuffixMap(self):
- if not self.InfModule or not self.CurrentArch:
- return []
- if not self.FinalTargetSuffixMap:
- FinalBuildTargetList = GenFdsGlobalVariable.GetModuleCodaTargetList(self.InfModule, self.CurrentArch)
- for File in FinalBuildTargetList:
- self.FinalTargetSuffixMap.setdefault(os.path.splitext(File)[1], []).append(File)
-
- # Check if current INF module has DEPEX
- if '.depex' not in self.FinalTargetSuffixMap and self.InfModule.ModuleType != SUP_MODULE_USER_DEFINED and self.InfModule.ModuleType != SUP_MODULE_HOST_APPLICATION \
- and not self.InfModule.DxsFile and not self.InfModule.LibraryClass:
- ModuleType = self.InfModule.ModuleType
- PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
-
- if ModuleType != SUP_MODULE_USER_DEFINED and ModuleType != SUP_MODULE_HOST_APPLICATION:
- for LibraryClass in PlatformDataBase.LibraryClasses.GetKeys():
- if LibraryClass.startswith("NULL") and LibraryClass[4:].isdigit() and PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]:
- self.InfModule.LibraryClasses[LibraryClass] = PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]
-
- StrModule = str(self.InfModule)
- PlatformModule = None
- if StrModule in PlatformDataBase.Modules:
- PlatformModule = PlatformDataBase.Modules[StrModule]
- for LibraryClass in PlatformModule.LibraryClasses:
- if LibraryClass.startswith("NULL") and LibraryClass[4:].isdigit():
- self.InfModule.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]
-
- DependencyList = [self.InfModule]
- LibraryInstance = {}
- DepexList = []
- while len(DependencyList) > 0:
- Module = DependencyList.pop(0)
- if not Module:
- continue
- for Dep in Module.Depex[self.CurrentArch, ModuleType]:
- if DepexList != []:
- DepexList.append('AND')
- DepexList.append('(')
- DepexList.extend(Dep)
- if DepexList[-1] == 'END': # no need of a END at this time
- DepexList.pop()
- DepexList.append(')')
- if 'BEFORE' in DepexList or 'AFTER' in DepexList:
- break
- for LibName in Module.LibraryClasses:
- if LibName in LibraryInstance:
- continue
- if PlatformModule and LibName in PlatformModule.LibraryClasses:
- LibraryPath = PlatformModule.LibraryClasses[LibName]
- else:
- LibraryPath = PlatformDataBase.LibraryClasses[LibName, ModuleType]
- if not LibraryPath:
- LibraryPath = Module.LibraryClasses[LibName]
- if not LibraryPath:
- continue
- LibraryModule = GenFdsGlobalVariable.WorkSpace.BuildObject[LibraryPath, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
- LibraryInstance[LibName] = LibraryModule
- DependencyList.append(LibraryModule)
- if DepexList:
- Dpx = DependencyExpression(DepexList, ModuleType, True)
- if len(Dpx.PostfixNotation) != 0:
- # It means this module has DEPEX
- self.FinalTargetSuffixMap['.depex'] = [os.path.join(self.EfiOutputPath, self.BaseName) + '.depex']
- return self.FinalTargetSuffixMap
-
- ## __InfParse() method
- #
- # Parse inf file to get module information
- #
- # @param self The object pointer
- # @param Dict dictionary contains macro and value pair
- #
- def __InfParse__(self, Dict = None, IsGenFfs=False):
-
- GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName)
-
- self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '')
- if len(self.InfFileName) > 1 and self.InfFileName[0] == '\\' and self.InfFileName[1] == '\\':
- pass
- elif self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' :
- ws_path = Path(GenFdsGlobalVariable.WorkSpaceDir)
- inf_path = Path(self.InfFileName)
- if ws_path in inf_path.parents:
- self.InfFileName = str(inf_path.relative_to(ws_path))
- else:
- self.InfFileName = self.InfFileName[1:]
-
- if self.InfFileName.find('$') == -1:
- InfPath = NormPath(self.InfFileName)
- if not os.path.exists(InfPath):
- InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath)
- if not os.path.exists(InfPath):
- EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName))
-
- self.CurrentArch = self.GetCurrentArch()
- #
- # Get the InfClass object
- #
-
- PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)
- ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")
- if ErrorCode != 0:
- EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
-
- #
- # Cache lower case version of INF path before processing FILE_GUID override
- #
- InfLowerPath = str(PathClassObj).lower()
- if self.OverrideGuid:
- PathClassObj = ProcessDuplicatedInf(PathClassObj, self.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir)
- if self.CurrentArch is not None:
-
- Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
- #
- # Set Ffs BaseName, ModuleGuid, ModuleType, Version, OutputPath
- #
- self.BaseName = Inf.BaseName
- self.ModuleGuid = Inf.Guid
- self.ModuleType = Inf.ModuleType
- if Inf.Specification is not None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:
- self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']
- if Inf.AutoGenVersion < 0x00010005:
- self.ModuleType = Inf.ComponentType
- self.VersionString = Inf.Version
- self.BinFileList = Inf.Binaries
- self.SourceFileList = Inf.Sources
- if self.KeepReloc is None and Inf.Shadow:
- self.ShadowFromInfFile = Inf.Shadow
-
- else:
- Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
- self.BaseName = Inf.BaseName
- self.ModuleGuid = Inf.Guid
- self.ModuleType = Inf.ModuleType
- if Inf.Specification is not None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:
- self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']
- self.VersionString = Inf.Version
- self.BinFileList = Inf.Binaries
- self.SourceFileList = Inf.Sources
- if self.BinFileList == []:
- EdkLogger.error("GenFds", GENFDS_ERROR,
- "INF %s specified in FDF could not be found in build ARCH %s!" \
- % (self.InfFileName, GenFdsGlobalVariable.ArchList))
-
- if self.OverrideGuid:
- self.ModuleGuid = self.OverrideGuid
-
- if len(self.SourceFileList) != 0 and not self.InDsc:
- EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName))
-
- if self.ModuleType == SUP_MODULE_SMM_CORE and int(self.PiSpecVersion, 16) < 0x0001000A:
- EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.InfFileName)
-
- if self.ModuleType == SUP_MODULE_MM_CORE_STANDALONE and int(self.PiSpecVersion, 16) < 0x00010032:
- EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "MM_CORE_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.InfFileName)
-
- if Inf._Defs is not None and len(Inf._Defs) > 0:
- self.OptRomDefs.update(Inf._Defs)
-
- self.PatchPcds = []
- InfPcds = Inf.Pcds
- Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
- FdfPcdDict = GenFdsGlobalVariable.FdfParser.Profile.PcdDict
- PlatformPcds = Platform.Pcds
-
- # Workaround here: both build and GenFds tool convert the workspace path to lower case
- # But INF file path in FDF and DSC file may have real case characters.
- # Try to convert the path to lower case to see if PCDs value are override by DSC.
- DscModules = {}
- for DscModule in Platform.Modules:
- DscModules[str(DscModule).lower()] = Platform.Modules[DscModule]
- for PcdKey in InfPcds:
- Pcd = InfPcds[PcdKey]
- if not hasattr(Pcd, 'Offset'):
- continue
- if Pcd.Type != TAB_PCDS_PATCHABLE_IN_MODULE:
- continue
- # Override Patchable PCD value by the value from DSC
- PatchPcd = None
- if InfLowerPath in DscModules and PcdKey in DscModules[InfLowerPath].Pcds:
- PatchPcd = DscModules[InfLowerPath].Pcds[PcdKey]
- elif PcdKey in Platform.Pcds:
- PatchPcd = Platform.Pcds[PcdKey]
- DscOverride = False
- if PatchPcd and Pcd.Type == PatchPcd.Type:
- DefaultValue = PatchPcd.DefaultValue
- DscOverride = True
-
- # Override Patchable PCD value by the value from FDF
- FdfOverride = False
- if PcdKey in FdfPcdDict:
- DefaultValue = FdfPcdDict[PcdKey]
- FdfOverride = True
-
- # Override Patchable PCD value by the value from Build Option
- BuildOptionOverride = False
- if GlobalData.BuildOptionPcd:
- for pcd in GlobalData.BuildOptionPcd:
- if PcdKey == (pcd[1], pcd[0]):
- if pcd[2]:
- continue
- DefaultValue = pcd[3]
- BuildOptionOverride = True
- break
-
- if not DscOverride and not FdfOverride and not BuildOptionOverride:
- continue
-
- # Support Flexible PCD format
- if DefaultValue:
- try:
- DefaultValue = ValueExpressionEx(DefaultValue, Pcd.DatumType, Platform._GuidDict)(True)
- except BadExpression:
- EdkLogger.error("GenFds", GENFDS_ERROR, 'PCD [%s.%s] Value "%s"' %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValue), File=self.InfFileName)
-
- if Pcd.InfDefaultValue:
- try:
- Pcd.InfDefaultValue = ValueExpressionEx(Pcd.InfDefaultValue, Pcd.DatumType, Platform._GuidDict)(True)
- except BadExpression:
- EdkLogger.error("GenFds", GENFDS_ERROR, 'PCD [%s.%s] Value "%s"' %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DefaultValue), File=self.InfFileName)
-
- # Check value, if value are equal, no need to patch
- if Pcd.DatumType == TAB_VOID:
- if Pcd.InfDefaultValue == DefaultValue or not DefaultValue:
- continue
- # Get the string size from FDF or DSC
- if DefaultValue[0] == 'L':
- # Remove L"", but the '\0' must be appended
- MaxDatumSize = str((len(DefaultValue) - 2) * 2)
- elif DefaultValue[0] == '{':
- MaxDatumSize = str(len(DefaultValue.split(',')))
- else:
- MaxDatumSize = str(len(DefaultValue) - 1)
- if DscOverride:
- Pcd.MaxDatumSize = PatchPcd.MaxDatumSize
- # If no defined the maximum size in DSC, try to get current size from INF
- if not Pcd.MaxDatumSize:
- Pcd.MaxDatumSize = str(len(Pcd.InfDefaultValue.split(',')))
- else:
- Base1 = Base2 = 10
- if Pcd.InfDefaultValue.upper().startswith('0X'):
- Base1 = 16
- if DefaultValue.upper().startswith('0X'):
- Base2 = 16
- try:
- PcdValueInImg = int(Pcd.InfDefaultValue, Base1)
- PcdValueInDscOrFdf = int(DefaultValue, Base2)
- if PcdValueInImg == PcdValueInDscOrFdf:
- continue
- except:
- continue
- # Check the Pcd size and data type
- if Pcd.DatumType == TAB_VOID:
- if int(MaxDatumSize) > int(Pcd.MaxDatumSize):
- EdkLogger.error("GenFds", GENFDS_ERROR, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \
- % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, int(MaxDatumSize) - int(Pcd.MaxDatumSize)))
- else:
- if PcdValueInDscOrFdf > MAX_VAL_TYPE[Pcd.DatumType] \
- or PcdValueInImg > MAX_VAL_TYPE[Pcd.DatumType]:
- EdkLogger.error("GenFds", GENFDS_ERROR, "The size of %s type PCD '%s.%s' doesn't match its data type." \
- % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
- self.PatchPcds.append((Pcd, DefaultValue))
-
- self.InfModule = Inf
- self.PcdIsDriver = Inf.PcdIsDriver
- self.IsBinaryModule = Inf.IsBinaryModule
- if len(Inf.Depex.data) > 0 and len(Inf.DepexExpression.data) > 0:
- self.Depex = True
-
- GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName)
- GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid)
- GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType)
- GenFdsGlobalVariable.VerboseLogger("VersionString : %s" % self.VersionString)
- GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" % self.InfFileName)
-
- #
- # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${ModuleName}\
- #
- if IsGenFfs:
- Rule = self.__GetRule__()
- if GlobalData.gGuidPatternEnd.match(Rule.NameGuid):
- self.ModuleGuid = Rule.NameGuid
- self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \
- self.ModuleGuid + self.BaseName)
- if not os.path.exists(self.OutputPath) :
- os.makedirs(self.OutputPath)
-
- self.EfiOutputPath, self.EfiDebugPath = self.__GetEFIOutPutPath__()
- GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)
-
- ## PatchEfiFile
- #
- # Patch EFI file with patch PCD
- #
- # @param EfiFile: EFI file needs to be patched.
- # @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name
- # If passed in file does not end with efi, return as is
- #
- def PatchEfiFile(self, EfiFile, FileType):
- #
- # If the module does not have any patches, then return path to input file
- #
- if not self.PatchPcds:
- return EfiFile
-
- #
- # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED
- #
- if FileType != BINARY_FILE_TYPE_PE32 and self.ModuleType != SUP_MODULE_USER_DEFINED and self.ModuleType != SUP_MODULE_HOST_APPLICATION:
- return EfiFile
-
- #
- # Generate path to patched output file
- #
- Basename = os.path.basename(EfiFile)
- Output = os.path.normpath (os.path.join(self.OutputPath, Basename))
-
- #
- # If this file has already been patched, then return the path to the patched file
- #
- if self.PatchedBinFile == Output:
- return Output
-
- #
- # If a different file from the same module has already been patched, then generate an error
- #
- if self.PatchedBinFile:
- EdkLogger.error("GenFds", GENFDS_ERROR,
- 'Only one binary file can be patched:\n'
- ' a binary file has been patched: %s\n'
- ' current file: %s' % (self.PatchedBinFile, EfiFile),
- File=self.InfFileName)
-
- #
- # Copy unpatched file contents to output file location to perform patching
- #
- CopyLongFilePath(EfiFile, Output)
-
- #
- # Apply patches to patched output file
- #
- for Pcd, Value in self.PatchPcds:
- RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Value, Pcd.MaxDatumSize)
- if RetVal:
- EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName)
-
- #
- # Save the path of the patched output file
- #
- self.PatchedBinFile = Output
-
- #
- # Return path to patched output file
- #
- return Output
-
- ## GenFfs() method
- #
- # Generate FFS
- #
- # @param self The object pointer
- # @param Dict dictionary contains macro and value pair
- # @param FvChildAddr Array of the inside FvImage base address
- # @param FvParentAddr Parent Fv base address
- # @retval string Generated FFS file name
- #
- def GenFfs(self, Dict = None, FvChildAddr = [], FvParentAddr=None, IsMakefile=False, FvName=None):
- #
- # Parse Inf file get Module related information
- #
- if Dict is None:
- Dict = {}
- self.__InfParse__(Dict, IsGenFfs=True)
- Arch = self.GetCurrentArch()
- SrcFile = mws.join( GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName);
- DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')
-
- SrcFileDir = "."
- SrcPath = os.path.dirname(SrcFile)
- SrcFileName = os.path.basename(SrcFile)
- SrcFileBase, SrcFileExt = os.path.splitext(SrcFileName)
- DestPath = os.path.dirname(DestFile)
- DestFileName = os.path.basename(DestFile)
- DestFileBase, DestFileExt = os.path.splitext(DestFileName)
- self.MacroDict = {
- # source file
- "${src}" : SrcFile,
- "${s_path}" : SrcPath,
- "${s_dir}" : SrcFileDir,
- "${s_name}" : SrcFileName,
- "${s_base}" : SrcFileBase,
- "${s_ext}" : SrcFileExt,
- # destination file
- "${dst}" : DestFile,
- "${d_path}" : DestPath,
- "${d_name}" : DestFileName,
- "${d_base}" : DestFileBase,
- "${d_ext}" : DestFileExt
- }
- #
- # Allow binary type module not specify override rule in FDF file.
- #
- if len(self.BinFileList) > 0:
- if self.Rule is None or self.Rule == "":
- self.Rule = "BINARY"
-
- if not IsMakefile and GenFdsGlobalVariable.EnableGenfdsMultiThread and self.Rule != 'BINARY':
- IsMakefile = True
- #
- # Get the rule of how to generate Ffs file
- #
- Rule = self.__GetRule__()
- GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName)
- #
- # Convert Fv File Type for PI1.1 SMM driver.
- #
- if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) >= 0x0001000A:
- if Rule.FvFileType == 'DRIVER':
- Rule.FvFileType = 'SMM'
- #
- # Framework SMM Driver has no SMM FV file type
- #
- if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) < 0x0001000A:
- if Rule.FvFileType == 'SMM' or Rule.FvFileType == SUP_MODULE_SMM_CORE:
- EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File=self.InfFileName)
- #
- # For the rule only has simpleFile
- #
- MakefilePath = None
- if self.IsBinaryModule:
- IsMakefile = False
- if IsMakefile:
- PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)
- if self.OverrideGuid:
- PathClassObj = ProcessDuplicatedInf(PathClassObj, self.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir)
- MakefilePath = PathClassObj.Path, Arch
- if isinstance (Rule, RuleSimpleFile.RuleSimpleFile):
- SectionOutputList = self.__GenSimpleFileSection__(Rule, IsMakefile=IsMakefile)
- FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList, MakefilePath=MakefilePath)
- return FfsOutput
- #
- # For Rule has ComplexFile
- #
- elif isinstance(Rule, RuleComplexFile.RuleComplexFile):
- InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr, IsMakefile=IsMakefile)
- FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments, MakefilePath=MakefilePath)
- return FfsOutput
-
- ## __ExtendMacro__() method
- #
- # Replace macro with its value
- #
- # @param self The object pointer
- # @param String The string to be replaced
- # @retval string Macro replaced string
- #
- def __ExtendMacro__ (self, String):
- MacroDict = {
- '$(INF_OUTPUT)' : self.EfiOutputPath,
- '$(MODULE_NAME)' : self.BaseName,
- '$(BUILD_NUMBER)': self.BuildNum,
- '$(INF_VERSION)' : self.VersionString,
- '$(NAMED_GUID)' : self.ModuleGuid
- }
- String = GenFdsGlobalVariable.MacroExtend(String, MacroDict)
- String = GenFdsGlobalVariable.MacroExtend(String, self.MacroDict)
- return String
-
- ## __GetRule__() method
- #
- # Get correct rule for generating FFS for this INF
- #
- # @param self The object pointer
- # @retval Rule Rule object
- #
- def __GetRule__ (self) :
- CurrentArchList = []
- if self.CurrentArch is None:
- CurrentArchList = ['common']
- else:
- CurrentArchList.append(self.CurrentArch)
-
- for CurrentArch in CurrentArchList:
- RuleName = 'RULE' + \
- '.' + \
- CurrentArch.upper() + \
- '.' + \
- self.ModuleType.upper()
- if self.Rule is not None:
- RuleName = RuleName + \
- '.' + \
- self.Rule.upper()
-
- Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)
- if Rule is not None:
- GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)
- return Rule
-
- RuleName = 'RULE' + \
- '.' + \
- TAB_COMMON + \
- '.' + \
- self.ModuleType.upper()
-
- if self.Rule is not None:
- RuleName = RuleName + \
- '.' + \
- self.Rule.upper()
-
- GenFdsGlobalVariable.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName, self.InfFileName))
-
- Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)
- if Rule is not None:
- GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)
- return Rule
-
- if Rule is None :
- EdkLogger.error("GenFds", GENFDS_ERROR, 'Don\'t Find common rule %s for INF %s' \
- % (RuleName, self.InfFileName))
-
- ## __GetPlatformArchList__() method
- #
- # Get Arch list this INF built under
- #
- # @param self The object pointer
- # @retval list Arch list
- #
- def __GetPlatformArchList__(self):
-
- InfFileKey = os.path.normpath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))
- DscArchList = []
- for Arch in GenFdsGlobalVariable.ArchList :
- PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
- if PlatformDataBase is not None:
- if InfFileKey in PlatformDataBase.Modules:
- DscArchList.append (Arch)
- else:
- #
- # BaseTools support build same module more than once, the module path with FILE_GUID overridden has
- # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key,
- # but the path (self.MetaFile.Path) is the real path
- #
- for key in PlatformDataBase.Modules:
- if InfFileKey == str((PlatformDataBase.Modules[key]).MetaFile.Path):
- DscArchList.append (Arch)
- break
-
- return DscArchList
-
- ## GetCurrentArch() method
- #
- # Get Arch list of the module from this INF is to be placed into flash
- #
- # @param self The object pointer
- # @retval list Arch list
- #
- def GetCurrentArch(self) :
-
- TargetArchList = GenFdsGlobalVariable.ArchList
-
- PlatformArchList = self.__GetPlatformArchList__()
-
- CurArchList = TargetArchList
- if PlatformArchList != []:
- CurArchList = list(set (TargetArchList) & set (PlatformArchList))
- GenFdsGlobalVariable.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList))
-
- ArchList = []
- if self.KeyStringList != []:
- for Key in self.KeyStringList:
- Key = GenFdsGlobalVariable.MacroExtend(Key)
- Target, Tag, Arch = Key.split('_')
- if Arch in CurArchList:
- ArchList.append(Arch)
- if Target not in self.TargetOverrideList:
- self.TargetOverrideList.append(Target)
- else:
- ArchList = CurArchList
-
- UseArchList = TargetArchList
- if self.UseArch is not None:
- UseArchList = []
- UseArchList.append(self.UseArch)
- ArchList = list(set (UseArchList) & set (ArchList))
-
- self.InfFileName = NormPath(self.InfFileName)
- if len(PlatformArchList) == 0:
- self.InDsc = False
- PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)
- ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")
- if ErrorCode != 0:
- EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
- if len(ArchList) == 1:
- Arch = ArchList[0]
- return Arch
- elif len(ArchList) > 1:
- if len(PlatformArchList) == 0:
- EdkLogger.error("GenFds", GENFDS_ERROR, "GenFds command line option has multiple ARCHs %s. Not able to determine which ARCH is valid for Module %s !" % (str(ArchList), self.InfFileName))
- else:
- EdkLogger.error("GenFds", GENFDS_ERROR, "Module built under multiple ARCHs %s. Not able to determine which output to put into flash for Module %s !" % (str(ArchList), self.InfFileName))
- else:
- EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s appears under ARCH %s in platform %s, but current deduced ARCH is %s, so NO build output could be put into flash." \
- % (self.InfFileName, str(PlatformArchList), GenFdsGlobalVariable.ActivePlatform, str(set (UseArchList) & set (TargetArchList))))
-
- ## __GetEFIOutPutPath__() method
- #
- # Get the output path for generated files
- #
- # @param self The object pointer
- # @retval string Path that output files from this INF go to
- #
- def __GetEFIOutPutPath__(self):
- Arch = ''
- OutputPath = ''
- DebugPath = ''
- (ModulePath, FileName) = os.path.split(self.InfFileName)
- Index = FileName.rfind('.')
- FileName = FileName[0:Index]
- if self.OverrideGuid:
- FileName = self.OverrideGuid
- Arch = "NoneArch"
- if self.CurrentArch is not None:
- Arch = self.CurrentArch
-
- OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],
- Arch,
- ModulePath,
- FileName,
- 'OUTPUT'
- )
- DebugPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],
- Arch,
- ModulePath,
- FileName,
- 'DEBUG'
- )
- OutputPath = os.path.abspath(OutputPath)
- DebugPath = os.path.abspath(DebugPath)
- return OutputPath, DebugPath
-
- ## __GenSimpleFileSection__() method
- #
- # Generate section by specified file name or a list of files with file extension
- #
- # @param self The object pointer
- # @param Rule The rule object used to generate section
- # @retval string File name of the generated section file
- #
- def __GenSimpleFileSection__(self, Rule, IsMakefile = False):
- #
- # Prepare the parameter of GenSection
- #
- FileList = []
- OutputFileList = []
- GenSecInputFile = None
- if Rule.FileName is not None:
- GenSecInputFile = self.__ExtendMacro__(Rule.FileName)
- if os.path.isabs(GenSecInputFile):
- GenSecInputFile = os.path.normpath(GenSecInputFile)
- else:
- GenSecInputFile = os.path.normpath(os.path.join(self.EfiOutputPath, GenSecInputFile))
- else:
- FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension)
-
- Index = 1
- SectionType = Rule.SectionType
- #
- # Convert Fv Section Type for PI1.1 SMM driver.
- #
- if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) >= 0x0001000A:
- if SectionType == BINARY_FILE_TYPE_DXE_DEPEX:
- SectionType = BINARY_FILE_TYPE_SMM_DEPEX
- #
- # Framework SMM Driver has no SMM_DEPEX section type
- #
- if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) < 0x0001000A:
- if SectionType == BINARY_FILE_TYPE_SMM_DEPEX:
- EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)
- NoStrip = True
- if self.ModuleType in (SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM):
- if self.KeepReloc is not None:
- NoStrip = self.KeepReloc
- elif Rule.KeepReloc is not None:
- NoStrip = Rule.KeepReloc
- elif self.ShadowFromInfFile is not None:
- NoStrip = self.ShadowFromInfFile
-
- if FileList != [] :
- for File in FileList:
-
- SecNum = '%d' %Index
- GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
- SectionSuffix[SectionType] + SUP_MODULE_SEC + SecNum
- Index = Index + 1
- OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)
- File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)
-
- #Get PE Section alignment when align is set to AUTO
- if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_TE):
- ImageObj = PeImageClass (File)
- if ImageObj.SectionAlignment < 0x400:
- self.Alignment = str (ImageObj.SectionAlignment)
- elif ImageObj.SectionAlignment < 0x100000:
- self.Alignment = str (ImageObj.SectionAlignment // 0x400) + 'K'
- else:
- self.Alignment = str (ImageObj.SectionAlignment // 0x100000) + 'M'
-
- if not NoStrip:
- FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
- if not os.path.exists(FileBeforeStrip) or \
- (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
- CopyLongFilePath(File, FileBeforeStrip)
- StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
- GenFdsGlobalVariable.GenerateFirmwareImage(
- StrippedFile,
- [File],
- Strip=True,
- IsMakefile=IsMakefile
- )
- File = StrippedFile
-
- if SectionType == BINARY_FILE_TYPE_TE:
- TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
- GenFdsGlobalVariable.GenerateFirmwareImage(
- TeFile,
- [File],
- Type='te',
- IsMakefile=IsMakefile
- )
- File = TeFile
- GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile)
- OutputFileList.append(OutputFile)
- else:
- SecNum = '%d' %Index
- GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
- SectionSuffix[SectionType] + SUP_MODULE_SEC + SecNum
- OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)
- GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch)
-
- #Get PE Section alignment when align is set to AUTO
- if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_TE):
- ImageObj = PeImageClass (GenSecInputFile)
- if ImageObj.SectionAlignment < 0x400:
- self.Alignment = str (ImageObj.SectionAlignment)
- elif ImageObj.SectionAlignment < 0x100000:
- self.Alignment = str (ImageObj.SectionAlignment // 0x400) + 'K'
- else:
- self.Alignment = str (ImageObj.SectionAlignment // 0x100000) + 'M'
-
- if not NoStrip:
- FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
- if not os.path.exists(FileBeforeStrip) or \
- (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)):
- CopyLongFilePath(GenSecInputFile, FileBeforeStrip)
-
- StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
- GenFdsGlobalVariable.GenerateFirmwareImage(
- StrippedFile,
- [GenSecInputFile],
- Strip=True,
- IsMakefile=IsMakefile
- )
- GenSecInputFile = StrippedFile
-
- if SectionType == BINARY_FILE_TYPE_TE:
- TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
- GenFdsGlobalVariable.GenerateFirmwareImage(
- TeFile,
- [GenSecInputFile],
- Type='te',
- IsMakefile=IsMakefile
- )
- GenSecInputFile = TeFile
- GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile)
- OutputFileList.append(OutputFile)
-
- return OutputFileList
-
- ## __GenSimpleFileFfs__() method
- #
- # Generate FFS
- #
- # @param self The object pointer
- # @param Rule The rule object used to generate section
- # @param InputFileList The output file list from GenSection
- # @retval string Generated FFS file name
- #
- def __GenSimpleFileFfs__(self, Rule, InputFileList, MakefilePath = None):
- FfsOutput = self.OutputPath + \
- os.sep + \
- self.__ExtendMacro__(Rule.NameGuid) + \
- '.ffs'
-
- GenFdsGlobalVariable.VerboseLogger(self.__ExtendMacro__(Rule.NameGuid))
- InputSection = []
- SectionAlignments = []
- for InputFile in InputFileList:
- InputSection.append(InputFile)
- SectionAlignments.append(Rule.SectAlignment)
-
- if Rule.NameGuid is not None and Rule.NameGuid.startswith('PCD('):
- PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
- if len(PcdValue) == 0:
- EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
- % (Rule.NameGuid))
- if PcdValue.startswith('{'):
- PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
- RegistryGuidStr = PcdValue
- if len(RegistryGuidStr) == 0:
- EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
- % (Rule.NameGuid))
- self.ModuleGuid = RegistryGuidStr
-
- GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,
- FdfFvFileTypeToFileType[Rule.FvFileType],
- self.ModuleGuid, Fixed=Rule.Fixed,
- CheckSum=Rule.CheckSum, Align=Rule.Alignment,
- SectionAlign=SectionAlignments,
- MakefilePath=MakefilePath
- )
- return FfsOutput
-
- ## __GenComplexFileSection__() method
- #
- # Generate section by sections in Rule
- #
- # @param self The object pointer
- # @param Rule The rule object used to generate section
- # @param FvChildAddr Array of the inside FvImage base address
- # @param FvParentAddr Parent Fv base address
- # @retval string File name of the generated section file
- #
- def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr, IsMakefile = False):
- if self.ModuleType in (SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE):
- if Rule.KeepReloc is not None:
- self.KeepRelocFromRule = Rule.KeepReloc
- SectFiles = []
- SectAlignments = []
- Index = 1
- HasGeneratedFlag = False
- if self.PcdIsDriver == 'PEI_PCD_DRIVER':
- if self.IsBinaryModule:
- PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "PEIPcdDataBase.raw")
- else:
- PcdExDbFileName = os.path.join(self.EfiOutputPath, "PEIPcdDataBase.raw")
- PcdExDbSecName = os.path.join(self.OutputPath, "PEIPcdDataBaseSec.raw")
- GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,
- [PcdExDbFileName],
- "EFI_SECTION_RAW",
- IsMakefile = IsMakefile
- )
- SectFiles.append(PcdExDbSecName)
- SectAlignments.append(None)
- elif self.PcdIsDriver == 'DXE_PCD_DRIVER':
- if self.IsBinaryModule:
- PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "DXEPcdDataBase.raw")
- else:
- PcdExDbFileName = os.path.join(self.EfiOutputPath, "DXEPcdDataBase.raw")
- PcdExDbSecName = os.path.join(self.OutputPath, "DXEPcdDataBaseSec.raw")
- GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,
- [PcdExDbFileName],
- "EFI_SECTION_RAW",
- IsMakefile = IsMakefile
- )
- SectFiles.append(PcdExDbSecName)
- SectAlignments.append(None)
- for Sect in Rule.SectionList:
- SecIndex = '%d' %Index
- SectList = []
- #
- # Convert Fv Section Type for PI1.1 SMM driver.
- #
- if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) >= 0x0001000A:
- if Sect.SectionType == BINARY_FILE_TYPE_DXE_DEPEX:
- Sect.SectionType = BINARY_FILE_TYPE_SMM_DEPEX
- #
- # Framework SMM Driver has no SMM_DEPEX section type
- #
- if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) < 0x0001000A:
- if Sect.SectionType == BINARY_FILE_TYPE_SMM_DEPEX:
- EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)
- #
- # process the inside FvImage from FvSection or GuidSection
- #
- if FvChildAddr != []:
- if isinstance(Sect, FvImageSection):
- Sect.FvAddr = FvChildAddr.pop(0)
- elif isinstance(Sect, GuidSection):
- Sect.FvAddr = FvChildAddr
- if FvParentAddr is not None and isinstance(Sect, GuidSection):
- Sect.FvParentAddr = FvParentAddr
-
- if Rule.KeyStringList != []:
- SectList, Align = Sect.GenSection(self.OutputPath, self.ModuleGuid, SecIndex, Rule.KeyStringList, self, IsMakefile = IsMakefile)
- else :
- SectList, Align = Sect.GenSection(self.OutputPath, self.ModuleGuid, SecIndex, self.KeyStringList, self, IsMakefile = IsMakefile)
-
- if not HasGeneratedFlag:
- UniVfrOffsetFileSection = ""
- ModuleFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)
- InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch]
- #
- # Search the source list in InfData to find if there are .vfr file exist.
- #
- VfrUniBaseName = {}
- VfrUniOffsetList = []
- for SourceFile in InfData.Sources:
- if SourceFile.Type.upper() == ".VFR" :
- #
- # search the .map file to find the offset of vfr binary in the PE32+/TE file.
- #
- VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin")
- if SourceFile.Type.upper() == ".UNI" :
- #
- # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
- #
- VfrUniBaseName["UniOffsetName"] = (self.BaseName + "Strings")
-
-
- if len(VfrUniBaseName) > 0:
- if IsMakefile:
- if InfData.BuildType != 'UEFI_HII':
- UniVfrOffsetFileName = os.path.join(self.OutputPath, self.BaseName + '.offset')
- UniVfrOffsetFileSection = os.path.join(self.OutputPath, self.BaseName + 'Offset' + '.raw')
- UniVfrOffsetFileNameList = []
- UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)
- TrimCmd = "Trim --Vfr-Uni-Offset -o %s --ModuleName=%s --DebugDir=%s " % (UniVfrOffsetFileName, self.BaseName, self.EfiDebugPath)
- GenFdsGlobalVariable.SecCmdList.append(TrimCmd)
- GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,
- [UniVfrOffsetFileName],
- "EFI_SECTION_RAW",
- IsMakefile = True
- )
- else:
- VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName)
- #
- # Generate the Raw data of raw section
- #
- if VfrUniOffsetList:
- UniVfrOffsetFileName = os.path.join(self.OutputPath, self.BaseName + '.offset')
- UniVfrOffsetFileSection = os.path.join(self.OutputPath, self.BaseName + 'Offset' + '.raw')
- FfsInfStatement.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName)
- UniVfrOffsetFileNameList = []
- UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)
- """Call GenSection"""
-
- GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,
- UniVfrOffsetFileNameList,
- "EFI_SECTION_RAW"
- )
- #os.remove(UniVfrOffsetFileName)
- if UniVfrOffsetFileSection:
- SectList.append(UniVfrOffsetFileSection)
- HasGeneratedFlag = True
-
- for SecName in SectList :
- SectFiles.append(SecName)
- SectAlignments.append(Align)
- Index = Index + 1
- return SectFiles, SectAlignments
-
- ## __GenComplexFileFfs__() method
- #
- # Generate FFS
- #
- # @param self The object pointer
- # @param Rule The rule object used to generate section
- # @param InputFileList The output file list from GenSection
- # @retval string Generated FFS file name
- #
- def __GenComplexFileFfs__(self, Rule, InputFile, Alignments, MakefilePath = None):
-
- if Rule.NameGuid is not None and Rule.NameGuid.startswith('PCD('):
- PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
- if len(PcdValue) == 0:
- EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
- % (Rule.NameGuid))
- if PcdValue.startswith('{'):
- PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
- RegistryGuidStr = PcdValue
- if len(RegistryGuidStr) == 0:
- EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
- % (Rule.NameGuid))
- self.ModuleGuid = RegistryGuidStr
-
- FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')
- GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile,
- FdfFvFileTypeToFileType[Rule.FvFileType],
- self.ModuleGuid, Fixed=Rule.Fixed,
- CheckSum=Rule.CheckSum, Align=Rule.Alignment,
- SectionAlign=Alignments,
- MakefilePath=MakefilePath
- )
- return FfsOutput
-
- ## __GetBuildOutputMapFileVfrUniInfo() method
- #
- # Find the offset of UNI/INF object offset in the EFI image file.
- #
- # @param self The object pointer
- # @param VfrUniBaseName A name list contain the UNI/INF object name.
- # @retval RetValue A list contain offset of UNI/INF object.
- #
- def __GetBuildOutputMapFileVfrUniInfo(self, VfrUniBaseName):
- MapFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".map")
- EfiFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".efi")
- return GetVariableOffset(MapFileName, EfiFileName, list(VfrUniBaseName.values()))
-
- ## __GenUniVfrOffsetFile() method
- #
- # Generate the offset file for the module which contain VFR or UNI file.
- #
- # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
- # @param UniVfrOffsetFileName The output offset file name.
- #
- @staticmethod
- def __GenUniVfrOffsetFile(VfrUniOffsetList, UniVfrOffsetFileName):
-
- # Use a instance of StringIO to cache data
- fStringIO = BytesIO()
-
- for Item in VfrUniOffsetList:
- if (Item[0].find("Strings") != -1):
- #
- # UNI offset in image.
- # GUID + Offset
- # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
- #
- UniGuid = b'\xe0\xc5\x13\x89\xf63\x86M\x9b\xf1C\xef\x89\xfc\x06f'
- fStringIO.write(UniGuid)
- UniValue = pack ('Q', int (Item[1], 16))
- fStringIO.write (UniValue)
- else:
- #
- # VFR binary offset in image.
- # GUID + Offset
- # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
- #
- VfrGuid = b'\xb4|\xbc\xd0Gj_I\xaa\x11q\x07F\xda\x06\xa2'
- fStringIO.write(VfrGuid)
- type (Item[1])
- VfrValue = pack ('Q', int (Item[1], 16))
- fStringIO.write (VfrValue)
-
- #
- # write data into file.
- #
- try :
- SaveFileOnChange(UniVfrOffsetFileName, fStringIO.getvalue())
- except:
- EdkLogger.error("GenFds", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %UniVfrOffsetFileName, None)
-
- fStringIO.close ()
-
-
+## @file +# process FFS generation from INF statement +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2014-2016 Hewlett-Packard Development Company, L.P.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from . import Rule +import Common.LongFilePathOs as os +from io import BytesIO +from struct import * +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from .Ffs import SectionSuffix,FdfFvFileTypeToFileType +import subprocess +import sys +from pathlib import Path +from . import Section +from . import RuleSimpleFile +from . import RuleComplexFile +from CommonDataClass.FdfClass import FfsInfStatementClassObject +from Common.MultipleWorkspace import MultipleWorkspace as mws +from Common.DataType import SUP_MODULE_USER_DEFINED +from Common.DataType import SUP_MODULE_HOST_APPLICATION +from Common.StringUtils import * +from Common.Misc import PathClass +from Common.Misc import GuidStructureByteArrayToGuidString +from Common.Misc import ProcessDuplicatedInf +from Common.Misc import GetVariableOffset +from Common import EdkLogger +from Common.BuildToolError import * +from .GuidSection import GuidSection +from .FvImageSection import FvImageSection +from Common.Misc import PeImageClass +from AutoGen.GenDepex import DependencyExpression +from PatchPcdValue.PatchPcdValue import PatchBinaryFile +from Common.LongFilePathSupport import CopyLongFilePath +from Common.LongFilePathSupport import OpenLongFilePath as open +import Common.GlobalData as GlobalData +from .DepexSection import DepexSection +from Common.Misc import SaveFileOnChange +from Common.Expression import * +from Common.DataType import * + +## generate FFS from INF +# +# +class FfsInfStatement(FfsInfStatementClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FfsInfStatementClassObject.__init__(self) + self.TargetOverrideList = [] + self.ShadowFromInfFile = None + self.KeepRelocFromRule = None + self.InDsc = True + self.OptRomDefs = {} + self.PiSpecVersion = '0x00000000' + self.InfModule = None + self.FinalTargetSuffixMap = {} + self.CurrentLineNum = None + self.CurrentLineContent = None + self.FileName = None + self.InfFileName = None + self.OverrideGuid = None + self.PatchedBinFile = '' + self.MacroDict = {} + self.Depex = False + + ## GetFinalTargetSuffixMap() method + # + # Get final build target list + def GetFinalTargetSuffixMap(self): + if not self.InfModule or not self.CurrentArch: + return [] + if not self.FinalTargetSuffixMap: + FinalBuildTargetList = GenFdsGlobalVariable.GetModuleCodaTargetList(self.InfModule, self.CurrentArch) + for File in FinalBuildTargetList: + self.FinalTargetSuffixMap.setdefault(os.path.splitext(File)[1], []).append(File) + + # Check if current INF module has DEPEX + if '.depex' not in self.FinalTargetSuffixMap and self.InfModule.ModuleType != SUP_MODULE_USER_DEFINED and self.InfModule.ModuleType != SUP_MODULE_HOST_APPLICATION \ + and not self.InfModule.DxsFile and not self.InfModule.LibraryClass: + ModuleType = self.InfModule.ModuleType + PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] + + if ModuleType != SUP_MODULE_USER_DEFINED and ModuleType != SUP_MODULE_HOST_APPLICATION: + for LibraryClass in PlatformDataBase.LibraryClasses.GetKeys(): + if LibraryClass.startswith("NULL") and LibraryClass[4:].isdigit() and PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]: + self.InfModule.LibraryClasses[LibraryClass] = PlatformDataBase.LibraryClasses[LibraryClass, ModuleType] + + StrModule = str(self.InfModule) + PlatformModule = None + if StrModule in PlatformDataBase.Modules: + PlatformModule = PlatformDataBase.Modules[StrModule] + for LibraryClass in PlatformModule.LibraryClasses: + if LibraryClass.startswith("NULL") and LibraryClass[4:].isdigit(): + self.InfModule.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass] + + DependencyList = [self.InfModule] + LibraryInstance = {} + DepexList = [] + while len(DependencyList) > 0: + Module = DependencyList.pop(0) + if not Module: + continue + for Dep in Module.Depex[self.CurrentArch, ModuleType]: + if DepexList != []: + DepexList.append('AND') + DepexList.append('(') + DepexList.extend(Dep) + if DepexList[-1] == 'END': # no need of a END at this time + DepexList.pop() + DepexList.append(')') + if 'BEFORE' in DepexList or 'AFTER' in DepexList: + break + for LibName in Module.LibraryClasses: + if LibName in LibraryInstance: + continue + if PlatformModule and LibName in PlatformModule.LibraryClasses: + LibraryPath = PlatformModule.LibraryClasses[LibName] + else: + LibraryPath = PlatformDataBase.LibraryClasses[LibName, ModuleType] + if not LibraryPath: + LibraryPath = Module.LibraryClasses[LibName] + if not LibraryPath: + continue + LibraryModule = GenFdsGlobalVariable.WorkSpace.BuildObject[LibraryPath, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] + LibraryInstance[LibName] = LibraryModule + DependencyList.append(LibraryModule) + if DepexList: + Dpx = DependencyExpression(DepexList, ModuleType, True) + if len(Dpx.PostfixNotation) != 0: + # It means this module has DEPEX + self.FinalTargetSuffixMap['.depex'] = [os.path.join(self.EfiOutputPath, self.BaseName) + '.depex'] + return self.FinalTargetSuffixMap + + ## __InfParse() method + # + # Parse inf file to get module information + # + # @param self The object pointer + # @param Dict dictionary contains macro and value pair + # + def __InfParse__(self, Dict = None, IsGenFfs=False): + + GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName) + + self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '') + if len(self.InfFileName) > 1 and self.InfFileName[0] == '\\' and self.InfFileName[1] == '\\': + pass + elif self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' : + ws_path = Path(GenFdsGlobalVariable.WorkSpaceDir) + inf_path = Path(self.InfFileName) + if ws_path in inf_path.parents: + self.InfFileName = str(inf_path.relative_to(ws_path)) + else: + self.InfFileName = self.InfFileName[1:] + + if self.InfFileName.find('$') == -1: + InfPath = NormPath(self.InfFileName) + if not os.path.exists(InfPath): + InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath) + if not os.path.exists(InfPath): + EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName)) + + self.CurrentArch = self.GetCurrentArch() + # + # Get the InfClass object + # + + PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir) + ErrorCode, ErrorInfo = PathClassObj.Validate(".inf") + if ErrorCode != 0: + EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) + + # + # Cache lower case version of INF path before processing FILE_GUID override + # + InfLowerPath = str(PathClassObj).lower() + if self.OverrideGuid: + PathClassObj = ProcessDuplicatedInf(PathClassObj, self.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir) + if self.CurrentArch is not None: + + Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] + # + # Set Ffs BaseName, ModuleGuid, ModuleType, Version, OutputPath + # + self.BaseName = Inf.BaseName + self.ModuleGuid = Inf.Guid + self.ModuleType = Inf.ModuleType + if Inf.Specification is not None and 'PI_SPECIFICATION_VERSION' in Inf.Specification: + self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION'] + if Inf.AutoGenVersion < 0x00010005: + self.ModuleType = Inf.ComponentType + self.VersionString = Inf.Version + self.BinFileList = Inf.Binaries + self.SourceFileList = Inf.Sources + if self.KeepReloc is None and Inf.Shadow: + self.ShadowFromInfFile = Inf.Shadow + + else: + Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] + self.BaseName = Inf.BaseName + self.ModuleGuid = Inf.Guid + self.ModuleType = Inf.ModuleType + if Inf.Specification is not None and 'PI_SPECIFICATION_VERSION' in Inf.Specification: + self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION'] + self.VersionString = Inf.Version + self.BinFileList = Inf.Binaries + self.SourceFileList = Inf.Sources + if self.BinFileList == []: + EdkLogger.error("GenFds", GENFDS_ERROR, + "INF %s specified in FDF could not be found in build ARCH %s!" \ + % (self.InfFileName, GenFdsGlobalVariable.ArchList)) + + if self.OverrideGuid: + self.ModuleGuid = self.OverrideGuid + + if len(self.SourceFileList) != 0 and not self.InDsc: + EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName)) + + if self.ModuleType == SUP_MODULE_SMM_CORE and int(self.PiSpecVersion, 16) < 0x0001000A: + EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.InfFileName) + + if self.ModuleType == SUP_MODULE_MM_CORE_STANDALONE and int(self.PiSpecVersion, 16) < 0x00010032: + EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "MM_CORE_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.InfFileName) + + if Inf._Defs is not None and len(Inf._Defs) > 0: + self.OptRomDefs.update(Inf._Defs) + + self.PatchPcds = [] + InfPcds = Inf.Pcds + Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] + FdfPcdDict = GenFdsGlobalVariable.FdfParser.Profile.PcdDict + PlatformPcds = Platform.Pcds + + # Workaround here: both build and GenFds tool convert the workspace path to lower case + # But INF file path in FDF and DSC file may have real case characters. + # Try to convert the path to lower case to see if PCDs value are override by DSC. + DscModules = {} + for DscModule in Platform.Modules: + DscModules[str(DscModule).lower()] = Platform.Modules[DscModule] + for PcdKey in InfPcds: + Pcd = InfPcds[PcdKey] + if not hasattr(Pcd, 'Offset'): + continue + if Pcd.Type != TAB_PCDS_PATCHABLE_IN_MODULE: + continue + # Override Patchable PCD value by the value from DSC + PatchPcd = None + if InfLowerPath in DscModules and PcdKey in DscModules[InfLowerPath].Pcds: + PatchPcd = DscModules[InfLowerPath].Pcds[PcdKey] + elif PcdKey in Platform.Pcds: + PatchPcd = Platform.Pcds[PcdKey] + DscOverride = False + if PatchPcd and Pcd.Type == PatchPcd.Type: + DefaultValue = PatchPcd.DefaultValue + DscOverride = True + + # Override Patchable PCD value by the value from FDF + FdfOverride = False + if PcdKey in FdfPcdDict: + DefaultValue = FdfPcdDict[PcdKey] + FdfOverride = True + + # Override Patchable PCD value by the value from Build Option + BuildOptionOverride = False + if GlobalData.BuildOptionPcd: + for pcd in GlobalData.BuildOptionPcd: + if PcdKey == (pcd[1], pcd[0]): + if pcd[2]: + continue + DefaultValue = pcd[3] + BuildOptionOverride = True + break + + if not DscOverride and not FdfOverride and not BuildOptionOverride: + continue + + # Support Flexible PCD format + if DefaultValue: + try: + DefaultValue = ValueExpressionEx(DefaultValue, Pcd.DatumType, Platform._GuidDict)(True) + except BadExpression: + EdkLogger.error("GenFds", GENFDS_ERROR, 'PCD [%s.%s] Value "%s"' %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValue), File=self.InfFileName) + + if Pcd.InfDefaultValue: + try: + Pcd.InfDefaultValue = ValueExpressionEx(Pcd.InfDefaultValue, Pcd.DatumType, Platform._GuidDict)(True) + except BadExpression: + EdkLogger.error("GenFds", GENFDS_ERROR, 'PCD [%s.%s] Value "%s"' %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DefaultValue), File=self.InfFileName) + + # Check value, if value are equal, no need to patch + if Pcd.DatumType == TAB_VOID: + if Pcd.InfDefaultValue == DefaultValue or not DefaultValue: + continue + # Get the string size from FDF or DSC + if DefaultValue[0] == 'L': + # Remove L"", but the '\0' must be appended + MaxDatumSize = str((len(DefaultValue) - 2) * 2) + elif DefaultValue[0] == '{': + MaxDatumSize = str(len(DefaultValue.split(','))) + else: + MaxDatumSize = str(len(DefaultValue) - 1) + if DscOverride: + Pcd.MaxDatumSize = PatchPcd.MaxDatumSize + # If no defined the maximum size in DSC, try to get current size from INF + if not Pcd.MaxDatumSize: + Pcd.MaxDatumSize = str(len(Pcd.InfDefaultValue.split(','))) + else: + Base1 = Base2 = 10 + if Pcd.InfDefaultValue.upper().startswith('0X'): + Base1 = 16 + if DefaultValue.upper().startswith('0X'): + Base2 = 16 + try: + PcdValueInImg = int(Pcd.InfDefaultValue, Base1) + PcdValueInDscOrFdf = int(DefaultValue, Base2) + if PcdValueInImg == PcdValueInDscOrFdf: + continue + except: + continue + # Check the Pcd size and data type + if Pcd.DatumType == TAB_VOID: + if int(MaxDatumSize) > int(Pcd.MaxDatumSize): + EdkLogger.error("GenFds", GENFDS_ERROR, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \ + % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, int(MaxDatumSize) - int(Pcd.MaxDatumSize))) + else: + if PcdValueInDscOrFdf > MAX_VAL_TYPE[Pcd.DatumType] \ + or PcdValueInImg > MAX_VAL_TYPE[Pcd.DatumType]: + EdkLogger.error("GenFds", GENFDS_ERROR, "The size of %s type PCD '%s.%s' doesn't match its data type." \ + % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)) + self.PatchPcds.append((Pcd, DefaultValue)) + + self.InfModule = Inf + self.PcdIsDriver = Inf.PcdIsDriver + self.IsBinaryModule = Inf.IsBinaryModule + if len(Inf.Depex.data) > 0 and len(Inf.DepexExpression.data) > 0: + self.Depex = True + + GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName) + GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid) + GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType) + GenFdsGlobalVariable.VerboseLogger("VersionString : %s" % self.VersionString) + GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" % self.InfFileName) + + # + # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${ModuleName}\ + # + if IsGenFfs: + Rule = self.__GetRule__() + if GlobalData.gGuidPatternEnd.match(Rule.NameGuid): + self.ModuleGuid = Rule.NameGuid + self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \ + self.ModuleGuid + self.BaseName) + if not os.path.exists(self.OutputPath) : + os.makedirs(self.OutputPath) + + self.EfiOutputPath, self.EfiDebugPath = self.__GetEFIOutPutPath__() + GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath) + + ## PatchEfiFile + # + # Patch EFI file with patch PCD + # + # @param EfiFile: EFI file needs to be patched. + # @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name + # If passed in file does not end with efi, return as is + # + def PatchEfiFile(self, EfiFile, FileType): + # + # If the module does not have any patches, then return path to input file + # + if not self.PatchPcds: + return EfiFile + + # + # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED + # + if FileType != BINARY_FILE_TYPE_PE32 and self.ModuleType != SUP_MODULE_USER_DEFINED and self.ModuleType != SUP_MODULE_HOST_APPLICATION: + return EfiFile + + # + # Generate path to patched output file + # + Basename = os.path.basename(EfiFile) + Output = os.path.normpath (os.path.join(self.OutputPath, Basename)) + + # + # If this file has already been patched, then return the path to the patched file + # + if self.PatchedBinFile == Output: + return Output + + # + # If a different file from the same module has already been patched, then generate an error + # + if self.PatchedBinFile: + EdkLogger.error("GenFds", GENFDS_ERROR, + 'Only one binary file can be patched:\n' + ' a binary file has been patched: %s\n' + ' current file: %s' % (self.PatchedBinFile, EfiFile), + File=self.InfFileName) + + # + # Copy unpatched file contents to output file location to perform patching + # + CopyLongFilePath(EfiFile, Output) + + # + # Apply patches to patched output file + # + for Pcd, Value in self.PatchPcds: + RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Value, Pcd.MaxDatumSize) + if RetVal: + EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName) + + # + # Save the path of the patched output file + # + self.PatchedBinFile = Output + + # + # Return path to patched output file + # + return Output + + ## GenFfs() method + # + # Generate FFS + # + # @param self The object pointer + # @param Dict dictionary contains macro and value pair + # @param FvChildAddr Array of the inside FvImage base address + # @param FvParentAddr Parent Fv base address + # @retval string Generated FFS file name + # + def GenFfs(self, Dict = None, FvChildAddr = [], FvParentAddr=None, IsMakefile=False, FvName=None): + # + # Parse Inf file get Module related information + # + if Dict is None: + Dict = {} + self.__InfParse__(Dict, IsGenFfs=True) + Arch = self.GetCurrentArch() + SrcFile = mws.join( GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName); + DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs') + + SrcFileDir = "." + SrcPath = os.path.dirname(SrcFile) + SrcFileName = os.path.basename(SrcFile) + SrcFileBase, SrcFileExt = os.path.splitext(SrcFileName) + DestPath = os.path.dirname(DestFile) + DestFileName = os.path.basename(DestFile) + DestFileBase, DestFileExt = os.path.splitext(DestFileName) + self.MacroDict = { + # source file + "${src}" : SrcFile, + "${s_path}" : SrcPath, + "${s_dir}" : SrcFileDir, + "${s_name}" : SrcFileName, + "${s_base}" : SrcFileBase, + "${s_ext}" : SrcFileExt, + # destination file + "${dst}" : DestFile, + "${d_path}" : DestPath, + "${d_name}" : DestFileName, + "${d_base}" : DestFileBase, + "${d_ext}" : DestFileExt + } + # + # Allow binary type module not specify override rule in FDF file. + # + if len(self.BinFileList) > 0: + if self.Rule is None or self.Rule == "": + self.Rule = "BINARY" + + if not IsMakefile and GenFdsGlobalVariable.EnableGenfdsMultiThread and self.Rule != 'BINARY': + IsMakefile = True + # + # Get the rule of how to generate Ffs file + # + Rule = self.__GetRule__() + GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName) + # + # Convert Fv File Type for PI1.1 SMM driver. + # + if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) >= 0x0001000A: + if Rule.FvFileType == 'DRIVER': + Rule.FvFileType = 'SMM' + # + # Framework SMM Driver has no SMM FV file type + # + if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) < 0x0001000A: + if Rule.FvFileType == 'SMM' or Rule.FvFileType == SUP_MODULE_SMM_CORE: + EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File=self.InfFileName) + # + # For the rule only has simpleFile + # + MakefilePath = None + if self.IsBinaryModule: + IsMakefile = False + if IsMakefile: + PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir) + if self.OverrideGuid: + PathClassObj = ProcessDuplicatedInf(PathClassObj, self.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir) + MakefilePath = PathClassObj.Path, Arch + if isinstance (Rule, RuleSimpleFile.RuleSimpleFile): + SectionOutputList = self.__GenSimpleFileSection__(Rule, IsMakefile=IsMakefile) + FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList, MakefilePath=MakefilePath) + return FfsOutput + # + # For Rule has ComplexFile + # + elif isinstance(Rule, RuleComplexFile.RuleComplexFile): + InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr, IsMakefile=IsMakefile) + FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments, MakefilePath=MakefilePath) + return FfsOutput + + ## __ExtendMacro__() method + # + # Replace macro with its value + # + # @param self The object pointer + # @param String The string to be replaced + # @retval string Macro replaced string + # + def __ExtendMacro__ (self, String): + MacroDict = { + '$(INF_OUTPUT)' : self.EfiOutputPath, + '$(MODULE_NAME)' : self.BaseName, + '$(BUILD_NUMBER)': self.BuildNum, + '$(INF_VERSION)' : self.VersionString, + '$(NAMED_GUID)' : self.ModuleGuid + } + String = GenFdsGlobalVariable.MacroExtend(String, MacroDict) + String = GenFdsGlobalVariable.MacroExtend(String, self.MacroDict) + return String + + ## __GetRule__() method + # + # Get correct rule for generating FFS for this INF + # + # @param self The object pointer + # @retval Rule Rule object + # + def __GetRule__ (self) : + CurrentArchList = [] + if self.CurrentArch is None: + CurrentArchList = ['common'] + else: + CurrentArchList.append(self.CurrentArch) + + for CurrentArch in CurrentArchList: + RuleName = 'RULE' + \ + '.' + \ + CurrentArch.upper() + \ + '.' + \ + self.ModuleType.upper() + if self.Rule is not None: + RuleName = RuleName + \ + '.' + \ + self.Rule.upper() + + Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName) + if Rule is not None: + GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName) + return Rule + + RuleName = 'RULE' + \ + '.' + \ + TAB_COMMON + \ + '.' + \ + self.ModuleType.upper() + + if self.Rule is not None: + RuleName = RuleName + \ + '.' + \ + self.Rule.upper() + + GenFdsGlobalVariable.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName, self.InfFileName)) + + Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName) + if Rule is not None: + GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName) + return Rule + + if Rule is None : + EdkLogger.error("GenFds", GENFDS_ERROR, 'Don\'t Find common rule %s for INF %s' \ + % (RuleName, self.InfFileName)) + + ## __GetPlatformArchList__() method + # + # Get Arch list this INF built under + # + # @param self The object pointer + # @retval list Arch list + # + def __GetPlatformArchList__(self): + + InfFileKey = os.path.normpath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)) + DscArchList = [] + for Arch in GenFdsGlobalVariable.ArchList : + PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] + if PlatformDataBase is not None: + if InfFileKey in PlatformDataBase.Modules: + DscArchList.append (Arch) + else: + # + # BaseTools support build same module more than once, the module path with FILE_GUID overridden has + # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key, + # but the path (self.MetaFile.Path) is the real path + # + for key in PlatformDataBase.Modules: + if InfFileKey == str((PlatformDataBase.Modules[key]).MetaFile.Path): + DscArchList.append (Arch) + break + + return DscArchList + + ## GetCurrentArch() method + # + # Get Arch list of the module from this INF is to be placed into flash + # + # @param self The object pointer + # @retval list Arch list + # + def GetCurrentArch(self) : + + TargetArchList = GenFdsGlobalVariable.ArchList + + PlatformArchList = self.__GetPlatformArchList__() + + CurArchList = TargetArchList + if PlatformArchList != []: + CurArchList = list(set (TargetArchList) & set (PlatformArchList)) + GenFdsGlobalVariable.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList)) + + ArchList = [] + if self.KeyStringList != []: + for Key in self.KeyStringList: + Key = GenFdsGlobalVariable.MacroExtend(Key) + Target, Tag, Arch = Key.split('_') + if Arch in CurArchList: + ArchList.append(Arch) + if Target not in self.TargetOverrideList: + self.TargetOverrideList.append(Target) + else: + ArchList = CurArchList + + UseArchList = TargetArchList + if self.UseArch is not None: + UseArchList = [] + UseArchList.append(self.UseArch) + ArchList = list(set (UseArchList) & set (ArchList)) + + self.InfFileName = NormPath(self.InfFileName) + if len(PlatformArchList) == 0: + self.InDsc = False + PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir) + ErrorCode, ErrorInfo = PathClassObj.Validate(".inf") + if ErrorCode != 0: + EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) + if len(ArchList) == 1: + Arch = ArchList[0] + return Arch + elif len(ArchList) > 1: + if len(PlatformArchList) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, "GenFds command line option has multiple ARCHs %s. Not able to determine which ARCH is valid for Module %s !" % (str(ArchList), self.InfFileName)) + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "Module built under multiple ARCHs %s. Not able to determine which output to put into flash for Module %s !" % (str(ArchList), self.InfFileName)) + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s appears under ARCH %s in platform %s, but current deduced ARCH is %s, so NO build output could be put into flash." \ + % (self.InfFileName, str(PlatformArchList), GenFdsGlobalVariable.ActivePlatform, str(set (UseArchList) & set (TargetArchList)))) + + ## __GetEFIOutPutPath__() method + # + # Get the output path for generated files + # + # @param self The object pointer + # @retval string Path that output files from this INF go to + # + def __GetEFIOutPutPath__(self): + Arch = '' + OutputPath = '' + DebugPath = '' + (ModulePath, FileName) = os.path.split(self.InfFileName) + Index = FileName.rfind('.') + FileName = FileName[0:Index] + if self.OverrideGuid: + FileName = self.OverrideGuid + Arch = "NoneArch" + if self.CurrentArch is not None: + Arch = self.CurrentArch + + OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], + Arch, + ModulePath, + FileName, + 'OUTPUT' + ) + DebugPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], + Arch, + ModulePath, + FileName, + 'DEBUG' + ) + OutputPath = os.path.abspath(OutputPath) + DebugPath = os.path.abspath(DebugPath) + return OutputPath, DebugPath + + ## __GenSimpleFileSection__() method + # + # Generate section by specified file name or a list of files with file extension + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @retval string File name of the generated section file + # + def __GenSimpleFileSection__(self, Rule, IsMakefile = False): + # + # Prepare the parameter of GenSection + # + FileList = [] + OutputFileList = [] + GenSecInputFile = None + if Rule.FileName is not None: + GenSecInputFile = self.__ExtendMacro__(Rule.FileName) + if os.path.isabs(GenSecInputFile): + GenSecInputFile = os.path.normpath(GenSecInputFile) + else: + GenSecInputFile = os.path.normpath(os.path.join(self.EfiOutputPath, GenSecInputFile)) + else: + FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension) + + Index = 1 + SectionType = Rule.SectionType + # + # Convert Fv Section Type for PI1.1 SMM driver. + # + if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) >= 0x0001000A: + if SectionType == BINARY_FILE_TYPE_DXE_DEPEX: + SectionType = BINARY_FILE_TYPE_SMM_DEPEX + # + # Framework SMM Driver has no SMM_DEPEX section type + # + if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) < 0x0001000A: + if SectionType == BINARY_FILE_TYPE_SMM_DEPEX: + EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName) + NoStrip = True + if self.ModuleType in (SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM): + if self.KeepReloc is not None: + NoStrip = self.KeepReloc + elif Rule.KeepReloc is not None: + NoStrip = Rule.KeepReloc + elif self.ShadowFromInfFile is not None: + NoStrip = self.ShadowFromInfFile + + if FileList != [] : + for File in FileList: + + SecNum = '%d' %Index + GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \ + SectionSuffix[SectionType] + SUP_MODULE_SEC + SecNum + Index = Index + 1 + OutputFile = os.path.join(self.OutputPath, GenSecOutputFile) + File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch) + + #Get PE Section alignment when align is set to AUTO + if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_TE): + ImageObj = PeImageClass (File) + if ImageObj.SectionAlignment < 0x400: + self.Alignment = str (ImageObj.SectionAlignment) + elif ImageObj.SectionAlignment < 0x100000: + self.Alignment = str (ImageObj.SectionAlignment // 0x400) + 'K' + else: + self.Alignment = str (ImageObj.SectionAlignment // 0x100000) + 'M' + + if not NoStrip: + FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc') + if not os.path.exists(FileBeforeStrip) or \ + (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)): + CopyLongFilePath(File, FileBeforeStrip) + StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') + GenFdsGlobalVariable.GenerateFirmwareImage( + StrippedFile, + [File], + Strip=True, + IsMakefile=IsMakefile + ) + File = StrippedFile + + if SectionType == BINARY_FILE_TYPE_TE: + TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + TeFile, + [File], + Type='te', + IsMakefile=IsMakefile + ) + File = TeFile + GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile) + OutputFileList.append(OutputFile) + else: + SecNum = '%d' %Index + GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \ + SectionSuffix[SectionType] + SUP_MODULE_SEC + SecNum + OutputFile = os.path.join(self.OutputPath, GenSecOutputFile) + GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch) + + #Get PE Section alignment when align is set to AUTO + if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_TE): + ImageObj = PeImageClass (GenSecInputFile) + if ImageObj.SectionAlignment < 0x400: + self.Alignment = str (ImageObj.SectionAlignment) + elif ImageObj.SectionAlignment < 0x100000: + self.Alignment = str (ImageObj.SectionAlignment // 0x400) + 'K' + else: + self.Alignment = str (ImageObj.SectionAlignment // 0x100000) + 'M' + + if not NoStrip: + FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc') + if not os.path.exists(FileBeforeStrip) or \ + (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)): + CopyLongFilePath(GenSecInputFile, FileBeforeStrip) + + StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') + GenFdsGlobalVariable.GenerateFirmwareImage( + StrippedFile, + [GenSecInputFile], + Strip=True, + IsMakefile=IsMakefile + ) + GenSecInputFile = StrippedFile + + if SectionType == BINARY_FILE_TYPE_TE: + TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + TeFile, + [GenSecInputFile], + Type='te', + IsMakefile=IsMakefile + ) + GenSecInputFile = TeFile + GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile) + OutputFileList.append(OutputFile) + + return OutputFileList + + ## __GenSimpleFileFfs__() method + # + # Generate FFS + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @param InputFileList The output file list from GenSection + # @retval string Generated FFS file name + # + def __GenSimpleFileFfs__(self, Rule, InputFileList, MakefilePath = None): + FfsOutput = self.OutputPath + \ + os.sep + \ + self.__ExtendMacro__(Rule.NameGuid) + \ + '.ffs' + + GenFdsGlobalVariable.VerboseLogger(self.__ExtendMacro__(Rule.NameGuid)) + InputSection = [] + SectionAlignments = [] + for InputFile in InputFileList: + InputSection.append(InputFile) + SectionAlignments.append(Rule.SectAlignment) + + if Rule.NameGuid is not None and Rule.NameGuid.startswith('PCD('): + PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid) + if len(PcdValue) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \ + % (Rule.NameGuid)) + if PcdValue.startswith('{'): + PcdValue = GuidStructureByteArrayToGuidString(PcdValue) + RegistryGuidStr = PcdValue + if len(RegistryGuidStr) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \ + % (Rule.NameGuid)) + self.ModuleGuid = RegistryGuidStr + + GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection, + FdfFvFileTypeToFileType[Rule.FvFileType], + self.ModuleGuid, Fixed=Rule.Fixed, + CheckSum=Rule.CheckSum, Align=Rule.Alignment, + SectionAlign=SectionAlignments, + MakefilePath=MakefilePath + ) + return FfsOutput + + ## __GenComplexFileSection__() method + # + # Generate section by sections in Rule + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @param FvChildAddr Array of the inside FvImage base address + # @param FvParentAddr Parent Fv base address + # @retval string File name of the generated section file + # + def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr, IsMakefile = False): + if self.ModuleType in (SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE): + if Rule.KeepReloc is not None: + self.KeepRelocFromRule = Rule.KeepReloc + SectFiles = [] + SectAlignments = [] + Index = 1 + HasGeneratedFlag = False + if self.PcdIsDriver == 'PEI_PCD_DRIVER': + if self.IsBinaryModule: + PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "PEIPcdDataBase.raw") + else: + PcdExDbFileName = os.path.join(self.EfiOutputPath, "PEIPcdDataBase.raw") + PcdExDbSecName = os.path.join(self.OutputPath, "PEIPcdDataBaseSec.raw") + GenFdsGlobalVariable.GenerateSection(PcdExDbSecName, + [PcdExDbFileName], + "EFI_SECTION_RAW", + IsMakefile = IsMakefile + ) + SectFiles.append(PcdExDbSecName) + SectAlignments.append(None) + elif self.PcdIsDriver == 'DXE_PCD_DRIVER': + if self.IsBinaryModule: + PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "DXEPcdDataBase.raw") + else: + PcdExDbFileName = os.path.join(self.EfiOutputPath, "DXEPcdDataBase.raw") + PcdExDbSecName = os.path.join(self.OutputPath, "DXEPcdDataBaseSec.raw") + GenFdsGlobalVariable.GenerateSection(PcdExDbSecName, + [PcdExDbFileName], + "EFI_SECTION_RAW", + IsMakefile = IsMakefile + ) + SectFiles.append(PcdExDbSecName) + SectAlignments.append(None) + for Sect in Rule.SectionList: + SecIndex = '%d' %Index + SectList = [] + # + # Convert Fv Section Type for PI1.1 SMM driver. + # + if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) >= 0x0001000A: + if Sect.SectionType == BINARY_FILE_TYPE_DXE_DEPEX: + Sect.SectionType = BINARY_FILE_TYPE_SMM_DEPEX + # + # Framework SMM Driver has no SMM_DEPEX section type + # + if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) < 0x0001000A: + if Sect.SectionType == BINARY_FILE_TYPE_SMM_DEPEX: + EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName) + # + # process the inside FvImage from FvSection or GuidSection + # + if FvChildAddr != []: + if isinstance(Sect, FvImageSection): + Sect.FvAddr = FvChildAddr.pop(0) + elif isinstance(Sect, GuidSection): + Sect.FvAddr = FvChildAddr + if FvParentAddr is not None and isinstance(Sect, GuidSection): + Sect.FvParentAddr = FvParentAddr + + if Rule.KeyStringList != []: + SectList, Align = Sect.GenSection(self.OutputPath, self.ModuleGuid, SecIndex, Rule.KeyStringList, self, IsMakefile = IsMakefile) + else : + SectList, Align = Sect.GenSection(self.OutputPath, self.ModuleGuid, SecIndex, self.KeyStringList, self, IsMakefile = IsMakefile) + + if not HasGeneratedFlag: + UniVfrOffsetFileSection = "" + ModuleFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName) + InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch] + # + # Search the source list in InfData to find if there are .vfr file exist. + # + VfrUniBaseName = {} + VfrUniOffsetList = [] + for SourceFile in InfData.Sources: + if SourceFile.Type.upper() == ".VFR" : + # + # search the .map file to find the offset of vfr binary in the PE32+/TE file. + # + VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin") + if SourceFile.Type.upper() == ".UNI" : + # + # search the .map file to find the offset of Uni strings binary in the PE32+/TE file. + # + VfrUniBaseName["UniOffsetName"] = (self.BaseName + "Strings") + + + if len(VfrUniBaseName) > 0: + if IsMakefile: + if InfData.BuildType != 'UEFI_HII': + UniVfrOffsetFileName = os.path.join(self.OutputPath, self.BaseName + '.offset') + UniVfrOffsetFileSection = os.path.join(self.OutputPath, self.BaseName + 'Offset' + '.raw') + UniVfrOffsetFileNameList = [] + UniVfrOffsetFileNameList.append(UniVfrOffsetFileName) + TrimCmd = "Trim --Vfr-Uni-Offset -o %s --ModuleName=%s --DebugDir=%s " % (UniVfrOffsetFileName, self.BaseName, self.EfiDebugPath) + GenFdsGlobalVariable.SecCmdList.append(TrimCmd) + GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection, + [UniVfrOffsetFileName], + "EFI_SECTION_RAW", + IsMakefile = True + ) + else: + VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName) + # + # Generate the Raw data of raw section + # + if VfrUniOffsetList: + UniVfrOffsetFileName = os.path.join(self.OutputPath, self.BaseName + '.offset') + UniVfrOffsetFileSection = os.path.join(self.OutputPath, self.BaseName + 'Offset' + '.raw') + FfsInfStatement.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName) + UniVfrOffsetFileNameList = [] + UniVfrOffsetFileNameList.append(UniVfrOffsetFileName) + """Call GenSection""" + + GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection, + UniVfrOffsetFileNameList, + "EFI_SECTION_RAW" + ) + #os.remove(UniVfrOffsetFileName) + if UniVfrOffsetFileSection: + SectList.append(UniVfrOffsetFileSection) + HasGeneratedFlag = True + + for SecName in SectList : + SectFiles.append(SecName) + SectAlignments.append(Align) + Index = Index + 1 + return SectFiles, SectAlignments + + ## __GenComplexFileFfs__() method + # + # Generate FFS + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @param InputFileList The output file list from GenSection + # @retval string Generated FFS file name + # + def __GenComplexFileFfs__(self, Rule, InputFile, Alignments, MakefilePath = None): + + if Rule.NameGuid is not None and Rule.NameGuid.startswith('PCD('): + PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid) + if len(PcdValue) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \ + % (Rule.NameGuid)) + if PcdValue.startswith('{'): + PcdValue = GuidStructureByteArrayToGuidString(PcdValue) + RegistryGuidStr = PcdValue + if len(RegistryGuidStr) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \ + % (Rule.NameGuid)) + self.ModuleGuid = RegistryGuidStr + + FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs') + GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile, + FdfFvFileTypeToFileType[Rule.FvFileType], + self.ModuleGuid, Fixed=Rule.Fixed, + CheckSum=Rule.CheckSum, Align=Rule.Alignment, + SectionAlign=Alignments, + MakefilePath=MakefilePath + ) + return FfsOutput + + ## __GetBuildOutputMapFileVfrUniInfo() method + # + # Find the offset of UNI/INF object offset in the EFI image file. + # + # @param self The object pointer + # @param VfrUniBaseName A name list contain the UNI/INF object name. + # @retval RetValue A list contain offset of UNI/INF object. + # + def __GetBuildOutputMapFileVfrUniInfo(self, VfrUniBaseName): + MapFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".map") + EfiFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".efi") + return GetVariableOffset(MapFileName, EfiFileName, list(VfrUniBaseName.values())) + + ## __GenUniVfrOffsetFile() method + # + # Generate the offset file for the module which contain VFR or UNI file. + # + # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file. + # @param UniVfrOffsetFileName The output offset file name. + # + @staticmethod + def __GenUniVfrOffsetFile(VfrUniOffsetList, UniVfrOffsetFileName): + + # Use a instance of StringIO to cache data + fStringIO = BytesIO() + + for Item in VfrUniOffsetList: + if (Item[0].find("Strings") != -1): + # + # UNI offset in image. + # GUID + Offset + # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } } + # + UniGuid = b'\xe0\xc5\x13\x89\xf63\x86M\x9b\xf1C\xef\x89\xfc\x06f' + fStringIO.write(UniGuid) + UniValue = pack ('Q', int (Item[1], 16)) + fStringIO.write (UniValue) + else: + # + # VFR binary offset in image. + # GUID + Offset + # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } }; + # + VfrGuid = b'\xb4|\xbc\xd0Gj_I\xaa\x11q\x07F\xda\x06\xa2' + fStringIO.write(VfrGuid) + type (Item[1]) + VfrValue = pack ('Q', int (Item[1], 16)) + fStringIO.write (VfrValue) + + # + # write data into file. + # + try : + SaveFileOnChange(UniVfrOffsetFileName, fStringIO.getvalue()) + except: + EdkLogger.error("GenFds", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %UniVfrOffsetFileName, None) + + fStringIO.close () + + |
