diff options
Diffstat (limited to 'BaseTools/Source/Python/GenFds')
29 files changed, 11158 insertions, 11158 deletions
diff --git a/BaseTools/Source/Python/GenFds/AprioriSection.py b/BaseTools/Source/Python/GenFds/AprioriSection.py index 9f64c613eb..84ec09768c 100644 --- a/BaseTools/Source/Python/GenFds/AprioriSection.py +++ b/BaseTools/Source/Python/GenFds/AprioriSection.py @@ -1,121 +1,121 @@ -## @file
-# process APRIORI file data and generate PEI/DXE APRIORI file
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from struct import pack
-import Common.LongFilePathOs as os
-from io import BytesIO
-from .FfsFileStatement import FileStatement
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-from Common.StringUtils import NormPath
-from Common.Misc import SaveFileOnChange, PathClass
-from Common.EdkLogger import error as EdkLoggerError
-from Common.BuildToolError import RESOURCE_NOT_AVAILABLE
-from Common.DataType import TAB_COMMON
-
-DXE_APRIORI_GUID = "FC510EE7-FFDC-11D4-BD41-0080C73C8881"
-PEI_APRIORI_GUID = "1B45CC0A-156A-428A-AF62-49864DA0E6E6"
-
-## process APRIORI file data and generate PEI/DXE APRIORI file
-#
-#
-class AprioriSection (object):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- self.DefineVarDict = {}
- self.FfsList = []
- self.AprioriType = ""
-
- ## GenFfs() method
- #
- # Generate FFS for APRIORI file
- #
- # @param self The object pointer
- # @param FvName for whom apriori file generated
- # @param Dict dictionary contains macro and its value
- # @retval string Generated file name
- #
- def GenFfs (self, FvName, Dict = None, IsMakefile = False):
- if Dict is None:
- Dict = {}
- Buffer = BytesIO()
- if self.AprioriType == "PEI":
- AprioriFileGuid = PEI_APRIORI_GUID
- else:
- AprioriFileGuid = DXE_APRIORI_GUID
-
- OutputAprFilePath = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, \
- GenFdsGlobalVariable.FfsDir,\
- AprioriFileGuid + FvName)
- if not os.path.exists(OutputAprFilePath):
- os.makedirs(OutputAprFilePath)
-
- OutputAprFileName = os.path.join( OutputAprFilePath, \
- AprioriFileGuid + FvName + '.Apri' )
- AprFfsFileName = os.path.join (OutputAprFilePath,\
- AprioriFileGuid + FvName + '.Ffs')
-
- Dict.update(self.DefineVarDict)
- InfFileName = None
- for FfsObj in self.FfsList:
- Guid = ""
- if isinstance(FfsObj, FileStatement):
- Guid = FfsObj.NameGuid
- else:
- InfFileName = NormPath(FfsObj.InfFileName)
- Arch = FfsObj.GetCurrentArch()
-
- if Arch:
- Dict['$(ARCH)'] = Arch
- InfFileName = GenFdsGlobalVariable.MacroExtend(InfFileName, Dict, Arch)
-
- if Arch:
- Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
- Guid = Inf.Guid
- else:
- Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
- Guid = Inf.Guid
-
- if not Inf.Module.Binaries:
- EdkLoggerError("GenFds", RESOURCE_NOT_AVAILABLE,
- "INF %s not found in build ARCH %s!" \
- % (InfFileName, GenFdsGlobalVariable.ArchList))
-
- GuidPart = Guid.split('-')
- Buffer.write(pack('I', int(GuidPart[0], 16)))
- Buffer.write(pack('H', int(GuidPart[1], 16)))
- Buffer.write(pack('H', int(GuidPart[2], 16)))
-
- for Num in range(2):
- Char = GuidPart[3][Num*2:Num*2+2]
- Buffer.write(pack('B', int(Char, 16)))
-
- for Num in range(6):
- Char = GuidPart[4][Num*2:Num*2+2]
- Buffer.write(pack('B', int(Char, 16)))
-
- SaveFileOnChange(OutputAprFileName, Buffer.getvalue())
-
- RawSectionFileName = os.path.join( OutputAprFilePath, \
- AprioriFileGuid + FvName + '.raw' )
- MakefilePath = None
- if IsMakefile:
- if not InfFileName:
- return None
- MakefilePath = InfFileName, Arch
- GenFdsGlobalVariable.GenerateSection(RawSectionFileName, [OutputAprFileName], 'EFI_SECTION_RAW', IsMakefile=IsMakefile)
- GenFdsGlobalVariable.GenerateFfs(AprFfsFileName, [RawSectionFileName],
- 'EFI_FV_FILETYPE_FREEFORM', AprioriFileGuid, MakefilePath=MakefilePath)
-
- return AprFfsFileName
+## @file +# process APRIORI file data and generate PEI/DXE APRIORI file +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from struct import pack +import Common.LongFilePathOs as os +from io import BytesIO +from .FfsFileStatement import FileStatement +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from Common.StringUtils import NormPath +from Common.Misc import SaveFileOnChange, PathClass +from Common.EdkLogger import error as EdkLoggerError +from Common.BuildToolError import RESOURCE_NOT_AVAILABLE +from Common.DataType import TAB_COMMON + +DXE_APRIORI_GUID = "FC510EE7-FFDC-11D4-BD41-0080C73C8881" +PEI_APRIORI_GUID = "1B45CC0A-156A-428A-AF62-49864DA0E6E6" + +## process APRIORI file data and generate PEI/DXE APRIORI file +# +# +class AprioriSection (object): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.DefineVarDict = {} + self.FfsList = [] + self.AprioriType = "" + + ## GenFfs() method + # + # Generate FFS for APRIORI file + # + # @param self The object pointer + # @param FvName for whom apriori file generated + # @param Dict dictionary contains macro and its value + # @retval string Generated file name + # + def GenFfs (self, FvName, Dict = None, IsMakefile = False): + if Dict is None: + Dict = {} + Buffer = BytesIO() + if self.AprioriType == "PEI": + AprioriFileGuid = PEI_APRIORI_GUID + else: + AprioriFileGuid = DXE_APRIORI_GUID + + OutputAprFilePath = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, \ + GenFdsGlobalVariable.FfsDir,\ + AprioriFileGuid + FvName) + if not os.path.exists(OutputAprFilePath): + os.makedirs(OutputAprFilePath) + + OutputAprFileName = os.path.join( OutputAprFilePath, \ + AprioriFileGuid + FvName + '.Apri' ) + AprFfsFileName = os.path.join (OutputAprFilePath,\ + AprioriFileGuid + FvName + '.Ffs') + + Dict.update(self.DefineVarDict) + InfFileName = None + for FfsObj in self.FfsList: + Guid = "" + if isinstance(FfsObj, FileStatement): + Guid = FfsObj.NameGuid + else: + InfFileName = NormPath(FfsObj.InfFileName) + Arch = FfsObj.GetCurrentArch() + + if Arch: + Dict['$(ARCH)'] = Arch + InfFileName = GenFdsGlobalVariable.MacroExtend(InfFileName, Dict, Arch) + + if Arch: + Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] + Guid = Inf.Guid + else: + Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(InfFileName, GenFdsGlobalVariable.WorkSpaceDir), TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] + Guid = Inf.Guid + + if not Inf.Module.Binaries: + EdkLoggerError("GenFds", RESOURCE_NOT_AVAILABLE, + "INF %s not found in build ARCH %s!" \ + % (InfFileName, GenFdsGlobalVariable.ArchList)) + + GuidPart = Guid.split('-') + Buffer.write(pack('I', int(GuidPart[0], 16))) + Buffer.write(pack('H', int(GuidPart[1], 16))) + Buffer.write(pack('H', int(GuidPart[2], 16))) + + for Num in range(2): + Char = GuidPart[3][Num*2:Num*2+2] + Buffer.write(pack('B', int(Char, 16))) + + for Num in range(6): + Char = GuidPart[4][Num*2:Num*2+2] + Buffer.write(pack('B', int(Char, 16))) + + SaveFileOnChange(OutputAprFileName, Buffer.getvalue()) + + RawSectionFileName = os.path.join( OutputAprFilePath, \ + AprioriFileGuid + FvName + '.raw' ) + MakefilePath = None + if IsMakefile: + if not InfFileName: + return None + MakefilePath = InfFileName, Arch + GenFdsGlobalVariable.GenerateSection(RawSectionFileName, [OutputAprFileName], 'EFI_SECTION_RAW', IsMakefile=IsMakefile) + GenFdsGlobalVariable.GenerateFfs(AprFfsFileName, [RawSectionFileName], + 'EFI_FV_FILETYPE_FREEFORM', AprioriFileGuid, MakefilePath=MakefilePath) + + return AprFfsFileName diff --git a/BaseTools/Source/Python/GenFds/Capsule.py b/BaseTools/Source/Python/GenFds/Capsule.py index 42788b43ce..969acdc50f 100644 --- a/BaseTools/Source/Python/GenFds/Capsule.py +++ b/BaseTools/Source/Python/GenFds/Capsule.py @@ -1,253 +1,253 @@ -## @file
-# generate capsule
-#
-# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR>
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from .GenFdsGlobalVariable import GenFdsGlobalVariable, FindExtendTool
-from CommonDataClass.FdfClass import CapsuleClassObject
-import Common.LongFilePathOs as os
-from io import BytesIO
-from Common.Misc import SaveFileOnChange, PackGUID
-import uuid
-from struct import pack
-from Common import EdkLogger
-from Common.BuildToolError import GENFDS_ERROR
-from Common.DataType import TAB_LINE_BREAK
-
-WIN_CERT_REVISION = 0x0200
-WIN_CERT_TYPE_EFI_GUID = 0x0EF1
-EFI_CERT_TYPE_PKCS7_GUID = uuid.UUID('{4aafd29d-68df-49ee-8aa9-347d375665a7}')
-EFI_CERT_TYPE_RSA2048_SHA256_GUID = uuid.UUID('{a7717414-c616-4977-9420-844712a735bf}')
-
-## create inf file describes what goes into capsule and call GenFv to generate capsule
-#
-#
-class Capsule (CapsuleClassObject):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- CapsuleClassObject.__init__(self)
- # For GenFv
- self.BlockSize = None
- # For GenFv
- self.BlockNum = None
- self.CapsuleName = None
-
- ## Generate FMP capsule
- #
- # @retval string Generated Capsule file path
- #
- def GenFmpCapsule(self):
- #
- # Generate capsule header
- # typedef struct {
- # EFI_GUID CapsuleGuid;
- # UINT32 HeaderSize;
- # UINT32 Flags;
- # UINT32 CapsuleImageSize;
- # } EFI_CAPSULE_HEADER;
- #
- Header = BytesIO()
- #
- # Use FMP capsule GUID: 6DCBD5ED-E82D-4C44-BDA1-7194199AD92A
- #
- Header.write(PackGUID('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A'.split('-')))
- HdrSize = 0
- if 'CAPSULE_HEADER_SIZE' in self.TokensDict:
- Header.write(pack('=I', int(self.TokensDict['CAPSULE_HEADER_SIZE'], 16)))
- HdrSize = int(self.TokensDict['CAPSULE_HEADER_SIZE'], 16)
- else:
- Header.write(pack('=I', 0x20))
- HdrSize = 0x20
- Flags = 0
- if 'CAPSULE_FLAGS' in self.TokensDict:
- for flag in self.TokensDict['CAPSULE_FLAGS'].split(','):
- flag = flag.strip()
- if flag == 'PopulateSystemTable':
- Flags |= 0x00010000 | 0x00020000
- elif flag == 'PersistAcrossReset':
- Flags |= 0x00010000
- elif flag == 'InitiateReset':
- Flags |= 0x00040000
- if 'OEM_CAPSULE_FLAGS' in self.TokensDict:
- Flags |= int(self.TokensDict['OEM_CAPSULE_FLAGS'],16)
- Header.write(pack('=I', Flags))
- #
- # typedef struct {
- # UINT32 Version;
- # UINT16 EmbeddedDriverCount;
- # UINT16 PayloadItemCount;
- # // UINT64 ItemOffsetList[];
- # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER;
- #
- FwMgrHdr = BytesIO()
- if 'CAPSULE_HEADER_INIT_VERSION' in self.TokensDict:
- FwMgrHdr.write(pack('=I', int(self.TokensDict['CAPSULE_HEADER_INIT_VERSION'], 16)))
- else:
- FwMgrHdr.write(pack('=I', 0x00000001))
- FwMgrHdr.write(pack('=HH', len(self.CapsuleDataList), len(self.FmpPayloadList)))
- FwMgrHdrSize = 4+2+2+8*(len(self.CapsuleDataList)+len(self.FmpPayloadList))
-
- #
- # typedef struct _WIN_CERTIFICATE {
- # UINT32 dwLength;
- # UINT16 wRevision;
- # UINT16 wCertificateType;
- # //UINT8 bCertificate[ANYSIZE_ARRAY];
- # } WIN_CERTIFICATE;
- #
- # typedef struct _WIN_CERTIFICATE_UEFI_GUID {
- # WIN_CERTIFICATE Hdr;
- # EFI_GUID CertType;
- # //UINT8 CertData[ANYSIZE_ARRAY];
- # } WIN_CERTIFICATE_UEFI_GUID;
- #
- # typedef struct {
- # UINT64 MonotonicCount;
- # WIN_CERTIFICATE_UEFI_GUID AuthInfo;
- # } EFI_FIRMWARE_IMAGE_AUTHENTICATION;
- #
- # typedef struct _EFI_CERT_BLOCK_RSA_2048_SHA256 {
- # EFI_GUID HashType;
- # UINT8 PublicKey[256];
- # UINT8 Signature[256];
- # } EFI_CERT_BLOCK_RSA_2048_SHA256;
- #
-
- PreSize = FwMgrHdrSize
- Content = BytesIO()
- for driver in self.CapsuleDataList:
- FileName = driver.GenCapsuleSubItem()
- FwMgrHdr.write(pack('=Q', PreSize))
- PreSize += os.path.getsize(FileName)
- File = open(FileName, 'rb')
- Content.write(File.read())
- File.close()
- for fmp in self.FmpPayloadList:
- if fmp.Existed:
- FwMgrHdr.write(pack('=Q', PreSize))
- PreSize += len(fmp.Buffer)
- Content.write(fmp.Buffer)
- continue
- if fmp.ImageFile:
- for Obj in fmp.ImageFile:
- fmp.ImageFile = Obj.GenCapsuleSubItem()
- if fmp.VendorCodeFile:
- for Obj in fmp.VendorCodeFile:
- fmp.VendorCodeFile = Obj.GenCapsuleSubItem()
- if fmp.Certificate_Guid:
- ExternalTool, ExternalOption = FindExtendTool([], GenFdsGlobalVariable.ArchList, fmp.Certificate_Guid)
- CmdOption = ''
- CapInputFile = fmp.ImageFile
- if not os.path.isabs(fmp.ImageFile):
- CapInputFile = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, fmp.ImageFile)
- CapOutputTmp = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName) + '.tmp'
- if ExternalTool is None:
- EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % fmp.Certificate_Guid)
- else:
- CmdOption += ExternalTool
- if ExternalOption:
- CmdOption = CmdOption + ' ' + ExternalOption
- CmdOption += ' -e ' + ' --monotonic-count ' + str(fmp.MonotonicCount) + ' -o ' + CapOutputTmp + ' ' + CapInputFile
- CmdList = CmdOption.split()
- GenFdsGlobalVariable.CallExternalTool(CmdList, "Failed to generate FMP auth capsule")
- if uuid.UUID(fmp.Certificate_Guid) == EFI_CERT_TYPE_PKCS7_GUID:
- dwLength = 4 + 2 + 2 + 16 + os.path.getsize(CapOutputTmp) - os.path.getsize(CapInputFile)
- else:
- dwLength = 4 + 2 + 2 + 16 + 16 + 256 + 256
- fmp.ImageFile = CapOutputTmp
- AuthData = [fmp.MonotonicCount, dwLength, WIN_CERT_REVISION, WIN_CERT_TYPE_EFI_GUID, fmp.Certificate_Guid]
- fmp.Buffer = fmp.GenCapsuleSubItem(AuthData)
- else:
- fmp.Buffer = fmp.GenCapsuleSubItem()
- FwMgrHdr.write(pack('=Q', PreSize))
- PreSize += len(fmp.Buffer)
- Content.write(fmp.Buffer)
- BodySize = len(FwMgrHdr.getvalue()) + len(Content.getvalue())
- Header.write(pack('=I', HdrSize + BodySize))
- #
- # The real capsule header structure is 28 bytes
- #
- Header.write(b'\x00'*(HdrSize-28))
- Header.write(FwMgrHdr.getvalue())
- Header.write(Content.getvalue())
- #
- # Generate FMP capsule file
- #
- CapOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName) + '.Cap'
- SaveFileOnChange(CapOutputFile, Header.getvalue(), True)
- return CapOutputFile
-
- ## Generate capsule
- #
- # @param self The object pointer
- # @retval string Generated Capsule file path
- #
- def GenCapsule(self):
- if self.UiCapsuleName.upper() + 'cap' in GenFdsGlobalVariable.ImageBinDict:
- return GenFdsGlobalVariable.ImageBinDict[self.UiCapsuleName.upper() + 'cap']
-
- GenFdsGlobalVariable.InfLogger( "\nGenerate %s Capsule" %self.UiCapsuleName)
- if ('CAPSULE_GUID' in self.TokensDict and
- uuid.UUID(self.TokensDict['CAPSULE_GUID']) == uuid.UUID('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A')):
- return self.GenFmpCapsule()
-
- CapInfFile = self.GenCapInf()
- CapInfFile.append("[files]" + TAB_LINE_BREAK)
- CapFileList = []
- for CapsuleDataObj in self.CapsuleDataList:
- CapsuleDataObj.CapsuleName = self.CapsuleName
- FileName = CapsuleDataObj.GenCapsuleSubItem()
- CapsuleDataObj.CapsuleName = None
- CapFileList.append(FileName)
- CapInfFile.append("EFI_FILE_NAME = " + \
- FileName + \
- TAB_LINE_BREAK)
- SaveFileOnChange(self.CapInfFileName, ''.join(CapInfFile), False)
- #
- # Call GenFv tool to generate capsule
- #
- CapOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName)
- CapOutputFile = CapOutputFile + '.Cap'
- GenFdsGlobalVariable.GenerateFirmwareVolume(
- CapOutputFile,
- [self.CapInfFileName],
- Capsule=True,
- FfsList=CapFileList
- )
-
- GenFdsGlobalVariable.VerboseLogger( "\nGenerate %s Capsule Successfully" %self.UiCapsuleName)
- GenFdsGlobalVariable.SharpCounter = 0
- GenFdsGlobalVariable.ImageBinDict[self.UiCapsuleName.upper() + 'cap'] = CapOutputFile
- return CapOutputFile
-
- ## Generate inf file for capsule
- #
- # @param self The object pointer
- # @retval file inf file object
- #
- def GenCapInf(self):
- self.CapInfFileName = os.path.join(GenFdsGlobalVariable.FvDir,
- self.UiCapsuleName + "_Cap" + '.inf')
- CapInfFile = []
-
- CapInfFile.append("[options]" + TAB_LINE_BREAK)
-
- for Item in self.TokensDict:
- CapInfFile.append("EFI_" + \
- Item + \
- ' = ' + \
- self.TokensDict[Item] + \
- TAB_LINE_BREAK)
-
- return CapInfFile
+## @file +# generate capsule +# +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from .GenFdsGlobalVariable import GenFdsGlobalVariable, FindExtendTool +from CommonDataClass.FdfClass import CapsuleClassObject +import Common.LongFilePathOs as os +from io import BytesIO +from Common.Misc import SaveFileOnChange, PackGUID +import uuid +from struct import pack +from Common import EdkLogger +from Common.BuildToolError import GENFDS_ERROR +from Common.DataType import TAB_LINE_BREAK + +WIN_CERT_REVISION = 0x0200 +WIN_CERT_TYPE_EFI_GUID = 0x0EF1 +EFI_CERT_TYPE_PKCS7_GUID = uuid.UUID('{4aafd29d-68df-49ee-8aa9-347d375665a7}') +EFI_CERT_TYPE_RSA2048_SHA256_GUID = uuid.UUID('{a7717414-c616-4977-9420-844712a735bf}') + +## create inf file describes what goes into capsule and call GenFv to generate capsule +# +# +class Capsule (CapsuleClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + CapsuleClassObject.__init__(self) + # For GenFv + self.BlockSize = None + # For GenFv + self.BlockNum = None + self.CapsuleName = None + + ## Generate FMP capsule + # + # @retval string Generated Capsule file path + # + def GenFmpCapsule(self): + # + # Generate capsule header + # typedef struct { + # EFI_GUID CapsuleGuid; + # UINT32 HeaderSize; + # UINT32 Flags; + # UINT32 CapsuleImageSize; + # } EFI_CAPSULE_HEADER; + # + Header = BytesIO() + # + # Use FMP capsule GUID: 6DCBD5ED-E82D-4C44-BDA1-7194199AD92A + # + Header.write(PackGUID('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A'.split('-'))) + HdrSize = 0 + if 'CAPSULE_HEADER_SIZE' in self.TokensDict: + Header.write(pack('=I', int(self.TokensDict['CAPSULE_HEADER_SIZE'], 16))) + HdrSize = int(self.TokensDict['CAPSULE_HEADER_SIZE'], 16) + else: + Header.write(pack('=I', 0x20)) + HdrSize = 0x20 + Flags = 0 + if 'CAPSULE_FLAGS' in self.TokensDict: + for flag in self.TokensDict['CAPSULE_FLAGS'].split(','): + flag = flag.strip() + if flag == 'PopulateSystemTable': + Flags |= 0x00010000 | 0x00020000 + elif flag == 'PersistAcrossReset': + Flags |= 0x00010000 + elif flag == 'InitiateReset': + Flags |= 0x00040000 + if 'OEM_CAPSULE_FLAGS' in self.TokensDict: + Flags |= int(self.TokensDict['OEM_CAPSULE_FLAGS'],16) + Header.write(pack('=I', Flags)) + # + # typedef struct { + # UINT32 Version; + # UINT16 EmbeddedDriverCount; + # UINT16 PayloadItemCount; + # // UINT64 ItemOffsetList[]; + # } EFI_FIRMWARE_MANAGEMENT_CAPSULE_HEADER; + # + FwMgrHdr = BytesIO() + if 'CAPSULE_HEADER_INIT_VERSION' in self.TokensDict: + FwMgrHdr.write(pack('=I', int(self.TokensDict['CAPSULE_HEADER_INIT_VERSION'], 16))) + else: + FwMgrHdr.write(pack('=I', 0x00000001)) + FwMgrHdr.write(pack('=HH', len(self.CapsuleDataList), len(self.FmpPayloadList))) + FwMgrHdrSize = 4+2+2+8*(len(self.CapsuleDataList)+len(self.FmpPayloadList)) + + # + # typedef struct _WIN_CERTIFICATE { + # UINT32 dwLength; + # UINT16 wRevision; + # UINT16 wCertificateType; + # //UINT8 bCertificate[ANYSIZE_ARRAY]; + # } WIN_CERTIFICATE; + # + # typedef struct _WIN_CERTIFICATE_UEFI_GUID { + # WIN_CERTIFICATE Hdr; + # EFI_GUID CertType; + # //UINT8 CertData[ANYSIZE_ARRAY]; + # } WIN_CERTIFICATE_UEFI_GUID; + # + # typedef struct { + # UINT64 MonotonicCount; + # WIN_CERTIFICATE_UEFI_GUID AuthInfo; + # } EFI_FIRMWARE_IMAGE_AUTHENTICATION; + # + # typedef struct _EFI_CERT_BLOCK_RSA_2048_SHA256 { + # EFI_GUID HashType; + # UINT8 PublicKey[256]; + # UINT8 Signature[256]; + # } EFI_CERT_BLOCK_RSA_2048_SHA256; + # + + PreSize = FwMgrHdrSize + Content = BytesIO() + for driver in self.CapsuleDataList: + FileName = driver.GenCapsuleSubItem() + FwMgrHdr.write(pack('=Q', PreSize)) + PreSize += os.path.getsize(FileName) + File = open(FileName, 'rb') + Content.write(File.read()) + File.close() + for fmp in self.FmpPayloadList: + if fmp.Existed: + FwMgrHdr.write(pack('=Q', PreSize)) + PreSize += len(fmp.Buffer) + Content.write(fmp.Buffer) + continue + if fmp.ImageFile: + for Obj in fmp.ImageFile: + fmp.ImageFile = Obj.GenCapsuleSubItem() + if fmp.VendorCodeFile: + for Obj in fmp.VendorCodeFile: + fmp.VendorCodeFile = Obj.GenCapsuleSubItem() + if fmp.Certificate_Guid: + ExternalTool, ExternalOption = FindExtendTool([], GenFdsGlobalVariable.ArchList, fmp.Certificate_Guid) + CmdOption = '' + CapInputFile = fmp.ImageFile + if not os.path.isabs(fmp.ImageFile): + CapInputFile = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, fmp.ImageFile) + CapOutputTmp = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName) + '.tmp' + if ExternalTool is None: + EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % fmp.Certificate_Guid) + else: + CmdOption += ExternalTool + if ExternalOption: + CmdOption = CmdOption + ' ' + ExternalOption + CmdOption += ' -e ' + ' --monotonic-count ' + str(fmp.MonotonicCount) + ' -o ' + CapOutputTmp + ' ' + CapInputFile + CmdList = CmdOption.split() + GenFdsGlobalVariable.CallExternalTool(CmdList, "Failed to generate FMP auth capsule") + if uuid.UUID(fmp.Certificate_Guid) == EFI_CERT_TYPE_PKCS7_GUID: + dwLength = 4 + 2 + 2 + 16 + os.path.getsize(CapOutputTmp) - os.path.getsize(CapInputFile) + else: + dwLength = 4 + 2 + 2 + 16 + 16 + 256 + 256 + fmp.ImageFile = CapOutputTmp + AuthData = [fmp.MonotonicCount, dwLength, WIN_CERT_REVISION, WIN_CERT_TYPE_EFI_GUID, fmp.Certificate_Guid] + fmp.Buffer = fmp.GenCapsuleSubItem(AuthData) + else: + fmp.Buffer = fmp.GenCapsuleSubItem() + FwMgrHdr.write(pack('=Q', PreSize)) + PreSize += len(fmp.Buffer) + Content.write(fmp.Buffer) + BodySize = len(FwMgrHdr.getvalue()) + len(Content.getvalue()) + Header.write(pack('=I', HdrSize + BodySize)) + # + # The real capsule header structure is 28 bytes + # + Header.write(b'\x00'*(HdrSize-28)) + Header.write(FwMgrHdr.getvalue()) + Header.write(Content.getvalue()) + # + # Generate FMP capsule file + # + CapOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName) + '.Cap' + SaveFileOnChange(CapOutputFile, Header.getvalue(), True) + return CapOutputFile + + ## Generate capsule + # + # @param self The object pointer + # @retval string Generated Capsule file path + # + def GenCapsule(self): + if self.UiCapsuleName.upper() + 'cap' in GenFdsGlobalVariable.ImageBinDict: + return GenFdsGlobalVariable.ImageBinDict[self.UiCapsuleName.upper() + 'cap'] + + GenFdsGlobalVariable.InfLogger( "\nGenerate %s Capsule" %self.UiCapsuleName) + if ('CAPSULE_GUID' in self.TokensDict and + uuid.UUID(self.TokensDict['CAPSULE_GUID']) == uuid.UUID('6DCBD5ED-E82D-4C44-BDA1-7194199AD92A')): + return self.GenFmpCapsule() + + CapInfFile = self.GenCapInf() + CapInfFile.append("[files]" + TAB_LINE_BREAK) + CapFileList = [] + for CapsuleDataObj in self.CapsuleDataList: + CapsuleDataObj.CapsuleName = self.CapsuleName + FileName = CapsuleDataObj.GenCapsuleSubItem() + CapsuleDataObj.CapsuleName = None + CapFileList.append(FileName) + CapInfFile.append("EFI_FILE_NAME = " + \ + FileName + \ + TAB_LINE_BREAK) + SaveFileOnChange(self.CapInfFileName, ''.join(CapInfFile), False) + # + # Call GenFv tool to generate capsule + # + CapOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiCapsuleName) + CapOutputFile = CapOutputFile + '.Cap' + GenFdsGlobalVariable.GenerateFirmwareVolume( + CapOutputFile, + [self.CapInfFileName], + Capsule=True, + FfsList=CapFileList + ) + + GenFdsGlobalVariable.VerboseLogger( "\nGenerate %s Capsule Successfully" %self.UiCapsuleName) + GenFdsGlobalVariable.SharpCounter = 0 + GenFdsGlobalVariable.ImageBinDict[self.UiCapsuleName.upper() + 'cap'] = CapOutputFile + return CapOutputFile + + ## Generate inf file for capsule + # + # @param self The object pointer + # @retval file inf file object + # + def GenCapInf(self): + self.CapInfFileName = os.path.join(GenFdsGlobalVariable.FvDir, + self.UiCapsuleName + "_Cap" + '.inf') + CapInfFile = [] + + CapInfFile.append("[options]" + TAB_LINE_BREAK) + + for Item in self.TokensDict: + CapInfFile.append("EFI_" + \ + Item + \ + ' = ' + \ + self.TokensDict[Item] + \ + TAB_LINE_BREAK) + + return CapInfFile diff --git a/BaseTools/Source/Python/GenFds/CapsuleData.py b/BaseTools/Source/Python/GenFds/CapsuleData.py index ebbde7f870..c7b3b0ca03 100644 --- a/BaseTools/Source/Python/GenFds/CapsuleData.py +++ b/BaseTools/Source/Python/GenFds/CapsuleData.py @@ -1,239 +1,239 @@ -## @file
-# generate capsule
-#
-# Copyright (c) 2007-2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-from io import BytesIO
-from struct import pack
-import os
-from Common.Misc import SaveFileOnChange
-import uuid
-
-## base class for capsule data
-#
-#
-class CapsuleData:
- ## The constructor
- #
- # @param self The object pointer
- def __init__(self):
- pass
-
- ## generate capsule data
- #
- # @param self The object pointer
- def GenCapsuleSubItem(self):
- pass
-
-## FFS class for capsule data
-#
-#
-class CapsuleFfs (CapsuleData):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self) :
- self.Ffs = None
- self.FvName = None
-
- ## generate FFS capsule data
- #
- # @param self The object pointer
- # @retval string Generated file name
- #
- def GenCapsuleSubItem(self):
- FfsFile = self.Ffs.GenFfs()
- return FfsFile
-
-## FV class for capsule data
-#
-#
-class CapsuleFv (CapsuleData):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self) :
- self.Ffs = None
- self.FvName = None
- self.CapsuleName = None
-
- ## generate FV capsule data
- #
- # @param self The object pointer
- # @retval string Generated file name
- #
- def GenCapsuleSubItem(self):
- if self.FvName.find('.fv') == -1:
- if self.FvName.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict:
- FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[self.FvName.upper()]
- FdBuffer = BytesIO()
- FvObj.CapsuleName = self.CapsuleName
- FvFile = FvObj.AddToBuffer(FdBuffer)
- FvObj.CapsuleName = None
- FdBuffer.close()
- return FvFile
- else:
- FvFile = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvName)
- return FvFile
-
-## FD class for capsule data
-#
-#
-class CapsuleFd (CapsuleData):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self) :
- self.Ffs = None
- self.FdName = None
- self.CapsuleName = None
-
- ## generate FD capsule data
- #
- # @param self The object pointer
- # @retval string Generated file name
- #
- def GenCapsuleSubItem(self):
- if self.FdName.find('.fd') == -1:
- if self.FdName.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict:
- FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[self.FdName.upper()]
- FdFile = FdObj.GenFd()
- return FdFile
- else:
- FdFile = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FdName)
- return FdFile
-
-## AnyFile class for capsule data
-#
-#
-class CapsuleAnyFile (CapsuleData):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self) :
- self.Ffs = None
- self.FileName = None
-
- ## generate AnyFile capsule data
- #
- # @param self The object pointer
- # @retval string Generated file name
- #
- def GenCapsuleSubItem(self):
- return self.FileName
-
-## Afile class for capsule data
-#
-#
-class CapsuleAfile (CapsuleData):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self) :
- self.Ffs = None
- self.FileName = None
-
- ## generate Afile capsule data
- #
- # @param self The object pointer
- # @retval string Generated file name
- #
- def GenCapsuleSubItem(self):
- return self.FileName
-
-class CapsulePayload(CapsuleData):
- '''Generate payload file, the header is defined below:
- #pragma pack(1)
- typedef struct {
- UINT32 Version;
- EFI_GUID UpdateImageTypeId;
- UINT8 UpdateImageIndex;
- UINT8 reserved_bytes[3];
- UINT32 UpdateImageSize;
- UINT32 UpdateVendorCodeSize;
- UINT64 UpdateHardwareInstance; //Introduced in v2
- } EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER;
- '''
- def __init__(self):
- self.UiName = None
- self.Version = None
- self.ImageTypeId = None
- self.ImageIndex = None
- self.HardwareInstance = None
- self.ImageFile = []
- self.VendorCodeFile = []
- self.Certificate_Guid = None
- self.MonotonicCount = None
- self.Existed = False
- self.Buffer = None
-
- def GenCapsuleSubItem(self, AuthData=[]):
- if not self.Version:
- self.Version = '0x00000002'
- if not self.ImageIndex:
- self.ImageIndex = '0x1'
- if not self.HardwareInstance:
- self.HardwareInstance = '0x0'
- ImageFileSize = os.path.getsize(self.ImageFile)
- if AuthData:
- # the ImageFileSize need include the full authenticated info size. From first bytes of MonotonicCount to last bytes of certificate.
- # the 32 bit is the MonotonicCount, dwLength, wRevision, wCertificateType and CertType
- ImageFileSize += 32
- VendorFileSize = 0
- if self.VendorCodeFile:
- VendorFileSize = os.path.getsize(self.VendorCodeFile)
-
- #
- # Fill structure
- #
- Guid = self.ImageTypeId.split('-')
- Buffer = pack('=ILHHBBBBBBBBBBBBIIQ',
- int(self.Version, 16),
- int(Guid[0], 16),
- int(Guid[1], 16),
- int(Guid[2], 16),
- int(Guid[3][-4:-2], 16),
- int(Guid[3][-2:], 16),
- int(Guid[4][-12:-10], 16),
- int(Guid[4][-10:-8], 16),
- int(Guid[4][-8:-6], 16),
- int(Guid[4][-6:-4], 16),
- int(Guid[4][-4:-2], 16),
- int(Guid[4][-2:], 16),
- int(self.ImageIndex, 16),
- 0,
- 0,
- 0,
- ImageFileSize,
- VendorFileSize,
- int(self.HardwareInstance, 16)
- )
- if AuthData:
- Buffer += pack('QIHH', AuthData[0], AuthData[1], AuthData[2], AuthData[3])
- Buffer += uuid.UUID(AuthData[4]).bytes_le
-
- #
- # Append file content to the structure
- #
- ImageFile = open(self.ImageFile, 'rb')
- Buffer += ImageFile.read()
- ImageFile.close()
- if self.VendorCodeFile:
- VendorFile = open(self.VendorCodeFile, 'rb')
- Buffer += VendorFile.read()
- VendorFile.close()
- self.Existed = True
- return Buffer
+## @file +# generate capsule +# +# Copyright (c) 2007-2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from io import BytesIO +from struct import pack +import os +from Common.Misc import SaveFileOnChange +import uuid + +## base class for capsule data +# +# +class CapsuleData: + ## The constructor + # + # @param self The object pointer + def __init__(self): + pass + + ## generate capsule data + # + # @param self The object pointer + def GenCapsuleSubItem(self): + pass + +## FFS class for capsule data +# +# +class CapsuleFfs (CapsuleData): + ## The constructor + # + # @param self The object pointer + # + def __init__(self) : + self.Ffs = None + self.FvName = None + + ## generate FFS capsule data + # + # @param self The object pointer + # @retval string Generated file name + # + def GenCapsuleSubItem(self): + FfsFile = self.Ffs.GenFfs() + return FfsFile + +## FV class for capsule data +# +# +class CapsuleFv (CapsuleData): + ## The constructor + # + # @param self The object pointer + # + def __init__(self) : + self.Ffs = None + self.FvName = None + self.CapsuleName = None + + ## generate FV capsule data + # + # @param self The object pointer + # @retval string Generated file name + # + def GenCapsuleSubItem(self): + if self.FvName.find('.fv') == -1: + if self.FvName.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict: + FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[self.FvName.upper()] + FdBuffer = BytesIO() + FvObj.CapsuleName = self.CapsuleName + FvFile = FvObj.AddToBuffer(FdBuffer) + FvObj.CapsuleName = None + FdBuffer.close() + return FvFile + else: + FvFile = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvName) + return FvFile + +## FD class for capsule data +# +# +class CapsuleFd (CapsuleData): + ## The constructor + # + # @param self The object pointer + # + def __init__(self) : + self.Ffs = None + self.FdName = None + self.CapsuleName = None + + ## generate FD capsule data + # + # @param self The object pointer + # @retval string Generated file name + # + def GenCapsuleSubItem(self): + if self.FdName.find('.fd') == -1: + if self.FdName.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict: + FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[self.FdName.upper()] + FdFile = FdObj.GenFd() + return FdFile + else: + FdFile = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FdName) + return FdFile + +## AnyFile class for capsule data +# +# +class CapsuleAnyFile (CapsuleData): + ## The constructor + # + # @param self The object pointer + # + def __init__(self) : + self.Ffs = None + self.FileName = None + + ## generate AnyFile capsule data + # + # @param self The object pointer + # @retval string Generated file name + # + def GenCapsuleSubItem(self): + return self.FileName + +## Afile class for capsule data +# +# +class CapsuleAfile (CapsuleData): + ## The constructor + # + # @param self The object pointer + # + def __init__(self) : + self.Ffs = None + self.FileName = None + + ## generate Afile capsule data + # + # @param self The object pointer + # @retval string Generated file name + # + def GenCapsuleSubItem(self): + return self.FileName + +class CapsulePayload(CapsuleData): + '''Generate payload file, the header is defined below: + #pragma pack(1) + typedef struct { + UINT32 Version; + EFI_GUID UpdateImageTypeId; + UINT8 UpdateImageIndex; + UINT8 reserved_bytes[3]; + UINT32 UpdateImageSize; + UINT32 UpdateVendorCodeSize; + UINT64 UpdateHardwareInstance; //Introduced in v2 + } EFI_FIRMWARE_MANAGEMENT_CAPSULE_IMAGE_HEADER; + ''' + def __init__(self): + self.UiName = None + self.Version = None + self.ImageTypeId = None + self.ImageIndex = None + self.HardwareInstance = None + self.ImageFile = [] + self.VendorCodeFile = [] + self.Certificate_Guid = None + self.MonotonicCount = None + self.Existed = False + self.Buffer = None + + def GenCapsuleSubItem(self, AuthData=[]): + if not self.Version: + self.Version = '0x00000002' + if not self.ImageIndex: + self.ImageIndex = '0x1' + if not self.HardwareInstance: + self.HardwareInstance = '0x0' + ImageFileSize = os.path.getsize(self.ImageFile) + if AuthData: + # the ImageFileSize need include the full authenticated info size. From first bytes of MonotonicCount to last bytes of certificate. + # the 32 bit is the MonotonicCount, dwLength, wRevision, wCertificateType and CertType + ImageFileSize += 32 + VendorFileSize = 0 + if self.VendorCodeFile: + VendorFileSize = os.path.getsize(self.VendorCodeFile) + + # + # Fill structure + # + Guid = self.ImageTypeId.split('-') + Buffer = pack('=ILHHBBBBBBBBBBBBIIQ', + int(self.Version, 16), + int(Guid[0], 16), + int(Guid[1], 16), + int(Guid[2], 16), + int(Guid[3][-4:-2], 16), + int(Guid[3][-2:], 16), + int(Guid[4][-12:-10], 16), + int(Guid[4][-10:-8], 16), + int(Guid[4][-8:-6], 16), + int(Guid[4][-6:-4], 16), + int(Guid[4][-4:-2], 16), + int(Guid[4][-2:], 16), + int(self.ImageIndex, 16), + 0, + 0, + 0, + ImageFileSize, + VendorFileSize, + int(self.HardwareInstance, 16) + ) + if AuthData: + Buffer += pack('QIHH', AuthData[0], AuthData[1], AuthData[2], AuthData[3]) + Buffer += uuid.UUID(AuthData[4]).bytes_le + + # + # Append file content to the structure + # + ImageFile = open(self.ImageFile, 'rb') + Buffer += ImageFile.read() + ImageFile.close() + if self.VendorCodeFile: + VendorFile = open(self.VendorCodeFile, 'rb') + Buffer += VendorFile.read() + VendorFile.close() + self.Existed = True + return Buffer diff --git a/BaseTools/Source/Python/GenFds/CompressSection.py b/BaseTools/Source/Python/GenFds/CompressSection.py index e62280fc16..8d9e20e942 100644 --- a/BaseTools/Source/Python/GenFds/CompressSection.py +++ b/BaseTools/Source/Python/GenFds/CompressSection.py @@ -1,96 +1,96 @@ -## @file
-# process compress section generation
-#
-# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from .Ffs import SectionSuffix
-from . import Section
-import subprocess
-import Common.LongFilePathOs as os
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-from CommonDataClass.FdfClass import CompressSectionClassObject
-from Common.DataType import *
-
-## generate compress section
-#
-#
-class CompressSection (CompressSectionClassObject) :
-
- ## compress types: PI standard and non PI standard
- CompTypeDict = {
- 'PI_STD' : 'PI_STD',
- 'PI_NONE' : 'PI_NONE'
- }
-
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- CompressSectionClassObject.__init__(self)
-
- ## GenSection() method
- #
- # Generate compressed section
- #
- # @param self The object pointer
- # @param OutputPath Where to place output file
- # @param ModuleName Which module this section belongs to
- # @param SecNum Index of section
- # @param KeyStringList Filter for inputs of section generation
- # @param FfsInf FfsInfStatement object that contains this section data
- # @param Dict dictionary contains macro and its value
- # @retval tuple (Generated file name, section alignment)
- #
- def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = None, IsMakefile = False):
-
- if FfsInf is not None:
- self.CompType = FfsInf.__ExtendMacro__(self.CompType)
- self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
-
- SectFiles = tuple()
- SectAlign = []
- Index = 0
- MaxAlign = None
- if Dict is None:
- Dict = {}
- for Sect in self.SectionList:
- Index = Index + 1
- SecIndex = '%s.%d' %(SecNum, Index)
- ReturnSectList, AlignValue = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict, IsMakefile=IsMakefile)
- if AlignValue is not None:
- if MaxAlign is None:
- MaxAlign = AlignValue
- if GenFdsGlobalVariable.GetAlignment (AlignValue) > GenFdsGlobalVariable.GetAlignment (MaxAlign):
- MaxAlign = AlignValue
- if ReturnSectList != []:
- if AlignValue is None:
- AlignValue = "1"
- for FileData in ReturnSectList:
- SectFiles += (FileData,)
- SectAlign.append(AlignValue)
-
- OutputFile = OutputPath + \
- os.sep + \
- ModuleName + \
- SUP_MODULE_SEC + \
- SecNum + \
- SectionSuffix['COMPRESS']
- OutputFile = os.path.normpath(OutputFile)
- DummyFile = OutputFile + '.dummy'
- GenFdsGlobalVariable.GenerateSection(DummyFile, SectFiles, InputAlign=SectAlign, IsMakefile=IsMakefile)
-
- GenFdsGlobalVariable.GenerateSection(OutputFile, [DummyFile], Section.Section.SectionType['COMPRESS'],
- CompressionType=self.CompTypeDict[self.CompType], IsMakefile=IsMakefile)
- OutputFileList = []
- OutputFileList.append(OutputFile)
- return OutputFileList, self.Alignment
-
-
+## @file +# process compress section generation +# +# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from .Ffs import SectionSuffix +from . import Section +import subprocess +import Common.LongFilePathOs as os +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import CompressSectionClassObject +from Common.DataType import * + +## generate compress section +# +# +class CompressSection (CompressSectionClassObject) : + + ## compress types: PI standard and non PI standard + CompTypeDict = { + 'PI_STD' : 'PI_STD', + 'PI_NONE' : 'PI_NONE' + } + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + CompressSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate compressed section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = None, IsMakefile = False): + + if FfsInf is not None: + self.CompType = FfsInf.__ExtendMacro__(self.CompType) + self.Alignment = FfsInf.__ExtendMacro__(self.Alignment) + + SectFiles = tuple() + SectAlign = [] + Index = 0 + MaxAlign = None + if Dict is None: + Dict = {} + for Sect in self.SectionList: + Index = Index + 1 + SecIndex = '%s.%d' %(SecNum, Index) + ReturnSectList, AlignValue = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict, IsMakefile=IsMakefile) + if AlignValue is not None: + if MaxAlign is None: + MaxAlign = AlignValue + if GenFdsGlobalVariable.GetAlignment (AlignValue) > GenFdsGlobalVariable.GetAlignment (MaxAlign): + MaxAlign = AlignValue + if ReturnSectList != []: + if AlignValue is None: + AlignValue = "1" + for FileData in ReturnSectList: + SectFiles += (FileData,) + SectAlign.append(AlignValue) + + OutputFile = OutputPath + \ + os.sep + \ + ModuleName + \ + SUP_MODULE_SEC + \ + SecNum + \ + SectionSuffix['COMPRESS'] + OutputFile = os.path.normpath(OutputFile) + DummyFile = OutputFile + '.dummy' + GenFdsGlobalVariable.GenerateSection(DummyFile, SectFiles, InputAlign=SectAlign, IsMakefile=IsMakefile) + + GenFdsGlobalVariable.GenerateSection(OutputFile, [DummyFile], Section.Section.SectionType['COMPRESS'], + CompressionType=self.CompTypeDict[self.CompType], IsMakefile=IsMakefile) + OutputFileList = [] + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment + + diff --git a/BaseTools/Source/Python/GenFds/DataSection.py b/BaseTools/Source/Python/GenFds/DataSection.py index 5af3ee7b7f..4391d333c1 100644 --- a/BaseTools/Source/Python/GenFds/DataSection.py +++ b/BaseTools/Source/Python/GenFds/DataSection.py @@ -1,117 +1,117 @@ -## @file
-# process data section generation
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from . import Section
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-import subprocess
-from .Ffs import SectionSuffix
-import Common.LongFilePathOs as os
-from CommonDataClass.FdfClass import DataSectionClassObject
-from Common.Misc import PeImageClass
-from Common.LongFilePathSupport import CopyLongFilePath
-from Common.DataType import *
-
-## generate data section
-#
-#
-class DataSection (DataSectionClassObject):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- DataSectionClassObject.__init__(self)
-
- ## GenSection() method
- #
- # Generate compressed section
- #
- # @param self The object pointer
- # @param OutputPath Where to place output file
- # @param ModuleName Which module this section belongs to
- # @param SecNum Index of section
- # @param KeyStringList Filter for inputs of section generation
- # @param FfsInf FfsInfStatement object that contains this section data
- # @param Dict dictionary contains macro and its value
- # @retval tuple (Generated file name list, section alignment)
- #
- def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = None, IsMakefile = False):
- #
- # Prepare the parameter of GenSection
- #
- if Dict is None:
- Dict = {}
- if FfsFile is not None:
- self.SectFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.SectFileName)
- self.SectFileName = GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict, FfsFile.CurrentArch)
- else:
- self.SectFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.SectFileName)
- self.SectFileName = GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)
-
- """Check Section file exist or not !"""
-
- if not os.path.exists(self.SectFileName):
- self.SectFileName = os.path.join (GenFdsGlobalVariable.WorkSpaceDir,
- self.SectFileName)
-
- """Copy Map file to Ffs output"""
- Filename = GenFdsGlobalVariable.MacroExtend(self.SectFileName)
- if Filename[(len(Filename)-4):] == '.efi':
- MapFile = Filename.replace('.efi', '.map')
- CopyMapFile = os.path.join(OutputPath, ModuleName + '.map')
- if IsMakefile:
- if GenFdsGlobalVariable.CopyList == []:
- GenFdsGlobalVariable.CopyList = [(MapFile, CopyMapFile)]
- else:
- GenFdsGlobalVariable.CopyList.append((MapFile, CopyMapFile))
- else:
- if os.path.exists(MapFile):
- if not os.path.exists(CopyMapFile) or (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)):
- CopyLongFilePath(MapFile, CopyMapFile)
-
- #Get PE Section alignment when align is set to AUTO
- if self.Alignment == 'Auto' and self.SecType in (BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32):
- self.Alignment = "0"
- NoStrip = True
- if self.SecType in (BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32):
- if self.KeepReloc is not None:
- NoStrip = self.KeepReloc
-
- if not NoStrip:
- FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi')
- if not os.path.exists(FileBeforeStrip) or \
- (os.path.getmtime(self.SectFileName) > os.path.getmtime(FileBeforeStrip)):
- CopyLongFilePath(self.SectFileName, FileBeforeStrip)
- StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped')
- GenFdsGlobalVariable.GenerateFirmwareImage(
- StrippedFile,
- [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)],
- Strip=True,
- IsMakefile = IsMakefile
- )
- self.SectFileName = StrippedFile
-
- if self.SecType == BINARY_FILE_TYPE_TE:
- TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw')
- GenFdsGlobalVariable.GenerateFirmwareImage(
- TeFile,
- [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)],
- Type='te',
- IsMakefile = IsMakefile
- )
- self.SectFileName = TeFile
-
- OutputFile = os.path.join (OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + SectionSuffix.get(self.SecType))
- OutputFile = os.path.normpath(OutputFile)
- GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], Section.Section.SectionType.get(self.SecType), IsMakefile = IsMakefile)
- FileList = [OutputFile]
- return FileList, self.Alignment
+## @file +# process data section generation +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from . import Section +from .GenFdsGlobalVariable import GenFdsGlobalVariable +import subprocess +from .Ffs import SectionSuffix +import Common.LongFilePathOs as os +from CommonDataClass.FdfClass import DataSectionClassObject +from Common.Misc import PeImageClass +from Common.LongFilePathSupport import CopyLongFilePath +from Common.DataType import * + +## generate data section +# +# +class DataSection (DataSectionClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + DataSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate compressed section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name list, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = None, IsMakefile = False): + # + # Prepare the parameter of GenSection + # + if Dict is None: + Dict = {} + if FfsFile is not None: + self.SectFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.SectFileName) + self.SectFileName = GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict, FfsFile.CurrentArch) + else: + self.SectFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.SectFileName) + self.SectFileName = GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict) + + """Check Section file exist or not !""" + + if not os.path.exists(self.SectFileName): + self.SectFileName = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, + self.SectFileName) + + """Copy Map file to Ffs output""" + Filename = GenFdsGlobalVariable.MacroExtend(self.SectFileName) + if Filename[(len(Filename)-4):] == '.efi': + MapFile = Filename.replace('.efi', '.map') + CopyMapFile = os.path.join(OutputPath, ModuleName + '.map') + if IsMakefile: + if GenFdsGlobalVariable.CopyList == []: + GenFdsGlobalVariable.CopyList = [(MapFile, CopyMapFile)] + else: + GenFdsGlobalVariable.CopyList.append((MapFile, CopyMapFile)) + else: + if os.path.exists(MapFile): + if not os.path.exists(CopyMapFile) or (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)): + CopyLongFilePath(MapFile, CopyMapFile) + + #Get PE Section alignment when align is set to AUTO + if self.Alignment == 'Auto' and self.SecType in (BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32): + self.Alignment = "0" + NoStrip = True + if self.SecType in (BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32): + if self.KeepReloc is not None: + NoStrip = self.KeepReloc + + if not NoStrip: + FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi') + if not os.path.exists(FileBeforeStrip) or \ + (os.path.getmtime(self.SectFileName) > os.path.getmtime(FileBeforeStrip)): + CopyLongFilePath(self.SectFileName, FileBeforeStrip) + StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped') + GenFdsGlobalVariable.GenerateFirmwareImage( + StrippedFile, + [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)], + Strip=True, + IsMakefile = IsMakefile + ) + self.SectFileName = StrippedFile + + if self.SecType == BINARY_FILE_TYPE_TE: + TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + TeFile, + [GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)], + Type='te', + IsMakefile = IsMakefile + ) + self.SectFileName = TeFile + + OutputFile = os.path.join (OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + SectionSuffix.get(self.SecType)) + OutputFile = os.path.normpath(OutputFile) + GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], Section.Section.SectionType.get(self.SecType), IsMakefile = IsMakefile) + FileList = [OutputFile] + return FileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/DepexSection.py b/BaseTools/Source/Python/GenFds/DepexSection.py index 6cabac38c4..b2bcf26ae7 100644 --- a/BaseTools/Source/Python/GenFds/DepexSection.py +++ b/BaseTools/Source/Python/GenFds/DepexSection.py @@ -1,111 +1,111 @@ -## @file
-# process depex section generation
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from . import Section
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-import Common.LongFilePathOs as os
-from CommonDataClass.FdfClass import DepexSectionClassObject
-from AutoGen.GenDepex import DependencyExpression
-from Common import EdkLogger
-from Common.BuildToolError import *
-from Common.Misc import PathClass
-from Common.DataType import *
-
-## generate data section
-#
-#
-class DepexSection (DepexSectionClassObject):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- DepexSectionClassObject.__init__(self)
-
- def __FindGuidValue(self, CName):
- for Arch in GenFdsGlobalVariable.ArchList:
- PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,
- Arch,
- GenFdsGlobalVariable.TargetName,
- GenFdsGlobalVariable.ToolChainTag)
- for Inf in GenFdsGlobalVariable.FdfParser.Profile.InfList:
- ModuleData = GenFdsGlobalVariable.WorkSpace.BuildObject[
- PathClass(Inf, GenFdsGlobalVariable.WorkSpaceDir),
- Arch,
- GenFdsGlobalVariable.TargetName,
- GenFdsGlobalVariable.ToolChainTag
- ]
- for Pkg in ModuleData.Packages:
- if Pkg not in PkgList:
- PkgList.append(Pkg)
- for PkgDb in PkgList:
- if CName in PkgDb.Ppis:
- return PkgDb.Ppis[CName]
- if CName in PkgDb.Protocols:
- return PkgDb.Protocols[CName]
- if CName in PkgDb.Guids:
- return PkgDb.Guids[CName]
- return None
-
- ## GenSection() method
- #
- # Generate compressed section
- #
- # @param self The object pointer
- # @param OutputPath Where to place output file
- # @param ModuleName Which module this section belongs to
- # @param SecNum Index of section
- # @param KeyStringList Filter for inputs of section generation
- # @param FfsInf FfsInfStatement object that contains this section data
- # @param Dict dictionary contains macro and its value
- # @retval tuple (Generated file name list, section alignment)
- #
- def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = None, IsMakefile = False):
- if self.ExpressionProcessed == False:
- self.Expression = self.Expression.replace("\n", " ").replace("\r", " ")
- ExpList = self.Expression.split()
-
- for Exp in ExpList:
- if Exp.upper() not in ('AND', 'OR', 'NOT', 'TRUE', 'FALSE', 'SOR', 'BEFORE', 'AFTER', 'END'):
- GuidStr = self.__FindGuidValue(Exp)
- if GuidStr is None:
- EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE,
- "Depex GUID %s could not be found in build DB! (ModuleName: %s)" % (Exp, ModuleName))
-
- self.Expression = self.Expression.replace(Exp, GuidStr)
-
- self.Expression = self.Expression.strip()
- self.ExpressionProcessed = True
-
- if self.DepexType == 'PEI_DEPEX_EXP':
- ModuleType = SUP_MODULE_PEIM
- SecType = BINARY_FILE_TYPE_PEI_DEPEX
- elif self.DepexType == 'DXE_DEPEX_EXP':
- ModuleType = SUP_MODULE_DXE_DRIVER
- SecType = BINARY_FILE_TYPE_DXE_DEPEX
- elif self.DepexType == 'SMM_DEPEX_EXP':
- ModuleType = SUP_MODULE_DXE_SMM_DRIVER
- SecType = BINARY_FILE_TYPE_SMM_DEPEX
- else:
- EdkLogger.error("GenFds", FORMAT_INVALID,
- "Depex type %s is not valid for module %s" % (self.DepexType, ModuleName))
-
- InputFile = os.path.join (OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + '.depex')
- InputFile = os.path.normpath(InputFile)
- Depex = DependencyExpression(self.Expression, ModuleType)
- Depex.Generate(InputFile)
-
- OutputFile = os.path.join (OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + '.dpx')
- OutputFile = os.path.normpath(OutputFile)
-
- GenFdsGlobalVariable.GenerateSection(OutputFile, [InputFile], Section.Section.SectionType.get (SecType), IsMakefile=IsMakefile)
- return [OutputFile], self.Alignment
+## @file +# process depex section generation +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from . import Section +from .GenFdsGlobalVariable import GenFdsGlobalVariable +import Common.LongFilePathOs as os +from CommonDataClass.FdfClass import DepexSectionClassObject +from AutoGen.GenDepex import DependencyExpression +from Common import EdkLogger +from Common.BuildToolError import * +from Common.Misc import PathClass +from Common.DataType import * + +## generate data section +# +# +class DepexSection (DepexSectionClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + DepexSectionClassObject.__init__(self) + + def __FindGuidValue(self, CName): + for Arch in GenFdsGlobalVariable.ArchList: + PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, + Arch, + GenFdsGlobalVariable.TargetName, + GenFdsGlobalVariable.ToolChainTag) + for Inf in GenFdsGlobalVariable.FdfParser.Profile.InfList: + ModuleData = GenFdsGlobalVariable.WorkSpace.BuildObject[ + PathClass(Inf, GenFdsGlobalVariable.WorkSpaceDir), + Arch, + GenFdsGlobalVariable.TargetName, + GenFdsGlobalVariable.ToolChainTag + ] + for Pkg in ModuleData.Packages: + if Pkg not in PkgList: + PkgList.append(Pkg) + for PkgDb in PkgList: + if CName in PkgDb.Ppis: + return PkgDb.Ppis[CName] + if CName in PkgDb.Protocols: + return PkgDb.Protocols[CName] + if CName in PkgDb.Guids: + return PkgDb.Guids[CName] + return None + + ## GenSection() method + # + # Generate compressed section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name list, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile = None, Dict = None, IsMakefile = False): + if self.ExpressionProcessed == False: + self.Expression = self.Expression.replace("\n", " ").replace("\r", " ") + ExpList = self.Expression.split() + + for Exp in ExpList: + if Exp.upper() not in ('AND', 'OR', 'NOT', 'TRUE', 'FALSE', 'SOR', 'BEFORE', 'AFTER', 'END'): + GuidStr = self.__FindGuidValue(Exp) + if GuidStr is None: + EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, + "Depex GUID %s could not be found in build DB! (ModuleName: %s)" % (Exp, ModuleName)) + + self.Expression = self.Expression.replace(Exp, GuidStr) + + self.Expression = self.Expression.strip() + self.ExpressionProcessed = True + + if self.DepexType == 'PEI_DEPEX_EXP': + ModuleType = SUP_MODULE_PEIM + SecType = BINARY_FILE_TYPE_PEI_DEPEX + elif self.DepexType == 'DXE_DEPEX_EXP': + ModuleType = SUP_MODULE_DXE_DRIVER + SecType = BINARY_FILE_TYPE_DXE_DEPEX + elif self.DepexType == 'SMM_DEPEX_EXP': + ModuleType = SUP_MODULE_DXE_SMM_DRIVER + SecType = BINARY_FILE_TYPE_SMM_DEPEX + else: + EdkLogger.error("GenFds", FORMAT_INVALID, + "Depex type %s is not valid for module %s" % (self.DepexType, ModuleName)) + + InputFile = os.path.join (OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + '.depex') + InputFile = os.path.normpath(InputFile) + Depex = DependencyExpression(self.Expression, ModuleType) + Depex.Generate(InputFile) + + OutputFile = os.path.join (OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + '.dpx') + OutputFile = os.path.normpath(OutputFile) + + GenFdsGlobalVariable.GenerateSection(OutputFile, [InputFile], Section.Section.SectionType.get (SecType), IsMakefile=IsMakefile) + return [OutputFile], self.Alignment diff --git a/BaseTools/Source/Python/GenFds/EfiSection.py b/BaseTools/Source/Python/GenFds/EfiSection.py index fd58391dac..0e0c0dffa3 100644 --- a/BaseTools/Source/Python/GenFds/EfiSection.py +++ b/BaseTools/Source/Python/GenFds/EfiSection.py @@ -1,318 +1,318 @@ -## @file
-# process rule section generation
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from struct import *
-from . import Section
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-import subprocess
-from .Ffs import SectionSuffix
-import Common.LongFilePathOs as os
-from CommonDataClass.FdfClass import EfiSectionClassObject
-from Common import EdkLogger
-from Common.BuildToolError import *
-from Common.Misc import PeImageClass
-from Common.LongFilePathSupport import OpenLongFilePath as open
-from Common.LongFilePathSupport import CopyLongFilePath
-from Common.DataType import *
-
-## generate rule section
-#
-#
-class EfiSection (EfiSectionClassObject):
-
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- EfiSectionClassObject.__init__(self)
-
- ## GenSection() method
- #
- # Generate rule section
- #
- # @param self The object pointer
- # @param OutputPath Where to place output file
- # @param ModuleName Which module this section belongs to
- # @param SecNum Index of section
- # @param KeyStringList Filter for inputs of section generation
- # @param FfsInf FfsInfStatement object that contains this section data
- # @param Dict dictionary contains macro and its value
- # @retval tuple (Generated file name list, section alignment)
- #
- def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = None, IsMakefile = False) :
-
- if self.FileName is not None and self.FileName.startswith('PCD('):
- self.FileName = GenFdsGlobalVariable.GetPcdValue(self.FileName)
- """Prepare the parameter of GenSection"""
- if FfsInf is not None :
- InfFileName = FfsInf.InfFileName
- SectionType = FfsInf.__ExtendMacro__(self.SectionType)
- Filename = FfsInf.__ExtendMacro__(self.FileName)
- BuildNum = FfsInf.__ExtendMacro__(self.BuildNum)
- StringData = FfsInf.__ExtendMacro__(self.StringData)
- ModuleNameStr = FfsInf.__ExtendMacro__('$(MODULE_NAME)')
- NoStrip = True
- if FfsInf.ModuleType in (SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE) and SectionType in (BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32):
- if FfsInf.KeepReloc is not None:
- NoStrip = FfsInf.KeepReloc
- elif FfsInf.KeepRelocFromRule is not None:
- NoStrip = FfsInf.KeepRelocFromRule
- elif self.KeepReloc is not None:
- NoStrip = self.KeepReloc
- elif FfsInf.ShadowFromInfFile is not None:
- NoStrip = FfsInf.ShadowFromInfFile
- else:
- EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s apply rule for None!" %ModuleName)
-
- """If the file name was pointed out, add it in FileList"""
- FileList = []
- if Dict is None:
- Dict = {}
- if Filename is not None:
- Filename = GenFdsGlobalVariable.MacroExtend(Filename, Dict)
- # check if the path is absolute or relative
- if os.path.isabs(Filename):
- Filename = os.path.normpath(Filename)
- else:
- Filename = os.path.normpath(os.path.join(FfsInf.EfiOutputPath, Filename))
-
- if not self.Optional:
- FileList.append(Filename)
- elif os.path.exists(Filename):
- FileList.append(Filename)
- elif IsMakefile:
- SuffixMap = FfsInf.GetFinalTargetSuffixMap()
- if '.depex' in SuffixMap:
- FileList.append(Filename)
- else:
- FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FileType, self.FileExtension, Dict, IsMakefile=IsMakefile, SectionType=SectionType)
- if IsSect :
- return FileList, self.Alignment
-
- Index = 0
- Align = self.Alignment
-
- """ If Section type is 'VERSION'"""
- OutputFileList = []
- if SectionType == 'VERSION':
-
- InfOverrideVerString = False
- if FfsInf.Version is not None:
- #StringData = FfsInf.Version
- BuildNum = FfsInf.Version
- InfOverrideVerString = True
-
- if InfOverrideVerString:
- #VerTuple = ('-n', '"' + StringData + '"')
- if BuildNum is not None and BuildNum != '':
- BuildNumTuple = ('-j', BuildNum)
- else:
- BuildNumTuple = tuple()
-
- Num = SecNum
- OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType))
- GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
- #Ui=StringData,
- Ver=BuildNum,
- IsMakefile=IsMakefile)
- OutputFileList.append(OutputFile)
-
- elif FileList != []:
- for File in FileList:
- Index = Index + 1
- Num = '%s.%d' %(SecNum, Index)
- OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get(SectionType))
- f = open(File, 'r')
- VerString = f.read()
- f.close()
- BuildNum = VerString
- if BuildNum is not None and BuildNum != '':
- BuildNumTuple = ('-j', BuildNum)
- GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
- #Ui=VerString,
- Ver=BuildNum,
- IsMakefile=IsMakefile)
- OutputFileList.append(OutputFile)
-
- else:
- BuildNum = StringData
- if BuildNum is not None and BuildNum != '':
- BuildNumTuple = ('-j', BuildNum)
- else:
- BuildNumTuple = tuple()
- BuildNumString = ' ' + ' '.join(BuildNumTuple)
-
- #if VerString == '' and
- if BuildNumString == '':
- if self.Optional == True :
- GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!")
- return [], None
- else:
- EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss Version Section value" %InfFileName)
- Num = SecNum
- OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType))
- GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
- #Ui=VerString,
- Ver=BuildNum,
- IsMakefile=IsMakefile)
- OutputFileList.append(OutputFile)
-
- #
- # If Section Type is BINARY_FILE_TYPE_UI
- #
- elif SectionType == BINARY_FILE_TYPE_UI:
-
- InfOverrideUiString = False
- if FfsInf.Ui is not None:
- StringData = FfsInf.Ui
- InfOverrideUiString = True
-
- if InfOverrideUiString:
- Num = SecNum
- if IsMakefile and StringData == ModuleNameStr:
- StringData = "$(MODULE_NAME)"
- OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType))
- GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
- Ui=StringData, IsMakefile=IsMakefile)
- OutputFileList.append(OutputFile)
-
- elif FileList != []:
- for File in FileList:
- Index = Index + 1
- Num = '%s.%d' %(SecNum, Index)
- OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get(SectionType))
- f = open(File, 'r')
- UiString = f.read()
- f.close()
- if IsMakefile and UiString == ModuleNameStr:
- UiString = "$(MODULE_NAME)"
- GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
- Ui=UiString, IsMakefile=IsMakefile)
- OutputFileList.append(OutputFile)
- else:
- if StringData is not None and len(StringData) > 0:
- UiTuple = ('-n', '"' + StringData + '"')
- else:
- UiTuple = tuple()
-
- if self.Optional == True :
- GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!")
- return '', None
- else:
- EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss UI Section value" %InfFileName)
-
- Num = SecNum
- if IsMakefile and StringData == ModuleNameStr:
- StringData = "$(MODULE_NAME)"
- OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType))
- GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
- Ui=StringData, IsMakefile=IsMakefile)
- OutputFileList.append(OutputFile)
-
- #
- # If Section Type is BINARY_FILE_TYPE_RAW
- #
- elif SectionType == BINARY_FILE_TYPE_RAW:
- """If File List is empty"""
- if FileList == []:
- if self.Optional == True:
- GenFdsGlobalVariable.VerboseLogger("Optional Section don't exist!")
- return [], None
- else:
- EdkLogger.error("GenFds", GENFDS_ERROR, "Output file for %s section could not be found for %s" % (SectionType, InfFileName))
-
- elif len(FileList) > 1:
- EdkLogger.error("GenFds", GENFDS_ERROR,
- "Files suffixed with %s are not allowed to have more than one file in %s[Binaries] section" % (
- self.FileExtension, InfFileName))
- else:
- for File in FileList:
- File = GenFdsGlobalVariable.MacroExtend(File, Dict)
- OutputFileList.append(File)
-
- else:
- """If File List is empty"""
- if FileList == [] :
- if self.Optional == True:
- GenFdsGlobalVariable.VerboseLogger("Optional Section don't exist!")
- return [], None
- else:
- EdkLogger.error("GenFds", GENFDS_ERROR, "Output file for %s section could not be found for %s" % (SectionType, InfFileName))
-
- else:
- """Convert the File to Section file one by one """
- for File in FileList:
- """ Copy Map file to FFS output path """
- Index = Index + 1
- Num = '%s.%d' %(SecNum, Index)
- OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get(SectionType))
- File = GenFdsGlobalVariable.MacroExtend(File, Dict)
-
- #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):
- Align = "0"
- if File[(len(File)-4):] == '.efi' and FfsInf.InfModule.BaseName == os.path.basename(File)[:-4]:
- MapFile = File.replace('.efi', '.map')
- CopyMapFile = os.path.join(OutputPath, ModuleName + '.map')
- if IsMakefile:
- if GenFdsGlobalVariable.CopyList == []:
- GenFdsGlobalVariable.CopyList = [(MapFile, CopyMapFile)]
- else:
- GenFdsGlobalVariable.CopyList.append((MapFile, CopyMapFile))
- else:
- if os.path.exists(MapFile):
- if not os.path.exists(CopyMapFile) or \
- (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)):
- CopyLongFilePath(MapFile, CopyMapFile)
-
- if not NoStrip:
- FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi')
- if IsMakefile:
- if GenFdsGlobalVariable.CopyList == []:
- GenFdsGlobalVariable.CopyList = [(File, FileBeforeStrip)]
- else:
- GenFdsGlobalVariable.CopyList.append((File, FileBeforeStrip))
- else:
- if not os.path.exists(FileBeforeStrip) or \
- (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
- CopyLongFilePath(File, FileBeforeStrip)
- StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped')
- GenFdsGlobalVariable.GenerateFirmwareImage(
- StrippedFile,
- [File],
- Strip=True,
- IsMakefile = IsMakefile
- )
- File = StrippedFile
-
- """For TE Section call GenFw to generate TE image"""
-
- if SectionType == BINARY_FILE_TYPE_TE:
- TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw')
- GenFdsGlobalVariable.GenerateFirmwareImage(
- TeFile,
- [File],
- Type='te',
- IsMakefile = IsMakefile
- )
- File = TeFile
-
- """Call GenSection"""
- GenFdsGlobalVariable.GenerateSection(OutputFile,
- [File],
- Section.Section.SectionType.get (SectionType),
- IsMakefile=IsMakefile
- )
- OutputFileList.append(OutputFile)
-
- return OutputFileList, Align
+## @file +# process rule section generation +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from struct import * +from . import Section +from .GenFdsGlobalVariable import GenFdsGlobalVariable +import subprocess +from .Ffs import SectionSuffix +import Common.LongFilePathOs as os +from CommonDataClass.FdfClass import EfiSectionClassObject +from Common import EdkLogger +from Common.BuildToolError import * +from Common.Misc import PeImageClass +from Common.LongFilePathSupport import OpenLongFilePath as open +from Common.LongFilePathSupport import CopyLongFilePath +from Common.DataType import * + +## generate rule section +# +# +class EfiSection (EfiSectionClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + EfiSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate rule section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name list, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = None, IsMakefile = False) : + + if self.FileName is not None and self.FileName.startswith('PCD('): + self.FileName = GenFdsGlobalVariable.GetPcdValue(self.FileName) + """Prepare the parameter of GenSection""" + if FfsInf is not None : + InfFileName = FfsInf.InfFileName + SectionType = FfsInf.__ExtendMacro__(self.SectionType) + Filename = FfsInf.__ExtendMacro__(self.FileName) + BuildNum = FfsInf.__ExtendMacro__(self.BuildNum) + StringData = FfsInf.__ExtendMacro__(self.StringData) + ModuleNameStr = FfsInf.__ExtendMacro__('$(MODULE_NAME)') + NoStrip = True + if FfsInf.ModuleType in (SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE) and SectionType in (BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32): + if FfsInf.KeepReloc is not None: + NoStrip = FfsInf.KeepReloc + elif FfsInf.KeepRelocFromRule is not None: + NoStrip = FfsInf.KeepRelocFromRule + elif self.KeepReloc is not None: + NoStrip = self.KeepReloc + elif FfsInf.ShadowFromInfFile is not None: + NoStrip = FfsInf.ShadowFromInfFile + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s apply rule for None!" %ModuleName) + + """If the file name was pointed out, add it in FileList""" + FileList = [] + if Dict is None: + Dict = {} + if Filename is not None: + Filename = GenFdsGlobalVariable.MacroExtend(Filename, Dict) + # check if the path is absolute or relative + if os.path.isabs(Filename): + Filename = os.path.normpath(Filename) + else: + Filename = os.path.normpath(os.path.join(FfsInf.EfiOutputPath, Filename)) + + if not self.Optional: + FileList.append(Filename) + elif os.path.exists(Filename): + FileList.append(Filename) + elif IsMakefile: + SuffixMap = FfsInf.GetFinalTargetSuffixMap() + if '.depex' in SuffixMap: + FileList.append(Filename) + else: + FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FileType, self.FileExtension, Dict, IsMakefile=IsMakefile, SectionType=SectionType) + if IsSect : + return FileList, self.Alignment + + Index = 0 + Align = self.Alignment + + """ If Section type is 'VERSION'""" + OutputFileList = [] + if SectionType == 'VERSION': + + InfOverrideVerString = False + if FfsInf.Version is not None: + #StringData = FfsInf.Version + BuildNum = FfsInf.Version + InfOverrideVerString = True + + if InfOverrideVerString: + #VerTuple = ('-n', '"' + StringData + '"') + if BuildNum is not None and BuildNum != '': + BuildNumTuple = ('-j', BuildNum) + else: + BuildNumTuple = tuple() + + Num = SecNum + OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType)) + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', + #Ui=StringData, + Ver=BuildNum, + IsMakefile=IsMakefile) + OutputFileList.append(OutputFile) + + elif FileList != []: + for File in FileList: + Index = Index + 1 + Num = '%s.%d' %(SecNum, Index) + OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get(SectionType)) + f = open(File, 'r') + VerString = f.read() + f.close() + BuildNum = VerString + if BuildNum is not None and BuildNum != '': + BuildNumTuple = ('-j', BuildNum) + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', + #Ui=VerString, + Ver=BuildNum, + IsMakefile=IsMakefile) + OutputFileList.append(OutputFile) + + else: + BuildNum = StringData + if BuildNum is not None and BuildNum != '': + BuildNumTuple = ('-j', BuildNum) + else: + BuildNumTuple = tuple() + BuildNumString = ' ' + ' '.join(BuildNumTuple) + + #if VerString == '' and + if BuildNumString == '': + if self.Optional == True : + GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!") + return [], None + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss Version Section value" %InfFileName) + Num = SecNum + OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType)) + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', + #Ui=VerString, + Ver=BuildNum, + IsMakefile=IsMakefile) + OutputFileList.append(OutputFile) + + # + # If Section Type is BINARY_FILE_TYPE_UI + # + elif SectionType == BINARY_FILE_TYPE_UI: + + InfOverrideUiString = False + if FfsInf.Ui is not None: + StringData = FfsInf.Ui + InfOverrideUiString = True + + if InfOverrideUiString: + Num = SecNum + if IsMakefile and StringData == ModuleNameStr: + StringData = "$(MODULE_NAME)" + OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType)) + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE', + Ui=StringData, IsMakefile=IsMakefile) + OutputFileList.append(OutputFile) + + elif FileList != []: + for File in FileList: + Index = Index + 1 + Num = '%s.%d' %(SecNum, Index) + OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get(SectionType)) + f = open(File, 'r') + UiString = f.read() + f.close() + if IsMakefile and UiString == ModuleNameStr: + UiString = "$(MODULE_NAME)" + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE', + Ui=UiString, IsMakefile=IsMakefile) + OutputFileList.append(OutputFile) + else: + if StringData is not None and len(StringData) > 0: + UiTuple = ('-n', '"' + StringData + '"') + else: + UiTuple = tuple() + + if self.Optional == True : + GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!") + return '', None + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss UI Section value" %InfFileName) + + Num = SecNum + if IsMakefile and StringData == ModuleNameStr: + StringData = "$(MODULE_NAME)" + OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType)) + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE', + Ui=StringData, IsMakefile=IsMakefile) + OutputFileList.append(OutputFile) + + # + # If Section Type is BINARY_FILE_TYPE_RAW + # + elif SectionType == BINARY_FILE_TYPE_RAW: + """If File List is empty""" + if FileList == []: + if self.Optional == True: + GenFdsGlobalVariable.VerboseLogger("Optional Section don't exist!") + return [], None + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "Output file for %s section could not be found for %s" % (SectionType, InfFileName)) + + elif len(FileList) > 1: + EdkLogger.error("GenFds", GENFDS_ERROR, + "Files suffixed with %s are not allowed to have more than one file in %s[Binaries] section" % ( + self.FileExtension, InfFileName)) + else: + for File in FileList: + File = GenFdsGlobalVariable.MacroExtend(File, Dict) + OutputFileList.append(File) + + else: + """If File List is empty""" + if FileList == [] : + if self.Optional == True: + GenFdsGlobalVariable.VerboseLogger("Optional Section don't exist!") + return [], None + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "Output file for %s section could not be found for %s" % (SectionType, InfFileName)) + + else: + """Convert the File to Section file one by one """ + for File in FileList: + """ Copy Map file to FFS output path """ + Index = Index + 1 + Num = '%s.%d' %(SecNum, Index) + OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get(SectionType)) + File = GenFdsGlobalVariable.MacroExtend(File, Dict) + + #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): + Align = "0" + if File[(len(File)-4):] == '.efi' and FfsInf.InfModule.BaseName == os.path.basename(File)[:-4]: + MapFile = File.replace('.efi', '.map') + CopyMapFile = os.path.join(OutputPath, ModuleName + '.map') + if IsMakefile: + if GenFdsGlobalVariable.CopyList == []: + GenFdsGlobalVariable.CopyList = [(MapFile, CopyMapFile)] + else: + GenFdsGlobalVariable.CopyList.append((MapFile, CopyMapFile)) + else: + if os.path.exists(MapFile): + if not os.path.exists(CopyMapFile) or \ + (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)): + CopyLongFilePath(MapFile, CopyMapFile) + + if not NoStrip: + FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi') + if IsMakefile: + if GenFdsGlobalVariable.CopyList == []: + GenFdsGlobalVariable.CopyList = [(File, FileBeforeStrip)] + else: + GenFdsGlobalVariable.CopyList.append((File, FileBeforeStrip)) + else: + if not os.path.exists(FileBeforeStrip) or \ + (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)): + CopyLongFilePath(File, FileBeforeStrip) + StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped') + GenFdsGlobalVariable.GenerateFirmwareImage( + StrippedFile, + [File], + Strip=True, + IsMakefile = IsMakefile + ) + File = StrippedFile + + """For TE Section call GenFw to generate TE image""" + + if SectionType == BINARY_FILE_TYPE_TE: + TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw') + GenFdsGlobalVariable.GenerateFirmwareImage( + TeFile, + [File], + Type='te', + IsMakefile = IsMakefile + ) + File = TeFile + + """Call GenSection""" + GenFdsGlobalVariable.GenerateSection(OutputFile, + [File], + Section.Section.SectionType.get (SectionType), + IsMakefile=IsMakefile + ) + OutputFileList.append(OutputFile) + + return OutputFileList, Align diff --git a/BaseTools/Source/Python/GenFds/Fd.py b/BaseTools/Source/Python/GenFds/Fd.py index 973936b6f2..097f62448f 100644 --- a/BaseTools/Source/Python/GenFds/Fd.py +++ b/BaseTools/Source/Python/GenFds/Fd.py @@ -1,155 +1,155 @@ -## @file
-# process FD generation
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from . import Region
-from . import Fv
-import Common.LongFilePathOs as os
-from io import BytesIO
-import sys
-from struct import *
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-from CommonDataClass.FdfClass import FDClassObject
-from Common import EdkLogger
-from Common.BuildToolError import *
-from Common.Misc import SaveFileOnChange
-from Common.DataType import BINARY_FILE_TYPE_FV
-
-## generate FD
-#
-#
-class FD(FDClassObject):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- FDClassObject.__init__(self)
-
- ## GenFd() method
- #
- # Generate FD
- #
- # @retval string Generated FD file name
- #
- def GenFd (self, Flag = False):
- if self.FdUiName.upper() + 'fd' in GenFdsGlobalVariable.ImageBinDict:
- return GenFdsGlobalVariable.ImageBinDict[self.FdUiName.upper() + 'fd']
-
- #
- # Print Information
- #
- FdFileName = os.path.join(GenFdsGlobalVariable.FvDir, self.FdUiName + '.fd')
- if not Flag:
- GenFdsGlobalVariable.InfLogger("\nFd File Name:%s (%s)" %(self.FdUiName, FdFileName))
-
- Offset = 0x00
- for item in self.BlockSizeList:
- Offset = Offset + item[0] * item[1]
- if Offset != self.Size:
- EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s Size not consistent with block array' % self.FdUiName)
- GenFdsGlobalVariable.VerboseLogger('Following Fv will be add to Fd !!!')
- for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict:
- GenFdsGlobalVariable.VerboseLogger(FvObj)
-
- HasCapsuleRegion = False
- for RegionObj in self.RegionList:
- if RegionObj.RegionType == 'CAPSULE':
- HasCapsuleRegion = True
- break
- if HasCapsuleRegion:
- TempFdBuffer = BytesIO()
- PreviousRegionStart = -1
- PreviousRegionSize = 1
-
- for RegionObj in self.RegionList :
- if RegionObj.RegionType == 'CAPSULE':
- continue
- if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart:
- pass
- elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
- pass
- elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
- if not Flag:
- GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
- PadRegion = Region.Region()
- PadRegion.Offset = PreviousRegionStart + PreviousRegionSize
- PadRegion.Size = RegionObj.Offset - PadRegion.Offset
- if not Flag:
- PadRegion.AddToBuffer(TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict)
- PreviousRegionStart = RegionObj.Offset
- PreviousRegionSize = RegionObj.Size
- #
- # Call each region's AddToBuffer function
- #
- if PreviousRegionSize > self.Size:
- pass
- GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function')
- RegionObj.AddToBuffer (TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict)
-
- FdBuffer = BytesIO()
- PreviousRegionStart = -1
- PreviousRegionSize = 1
- for RegionObj in self.RegionList :
- if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart:
- EdkLogger.error("GenFds", GENFDS_ERROR,
- 'Region offset 0x%X in wrong order with Region starting from 0x%X, size 0x%X\nRegions in FDF must have offsets appear in ascending order.'\
- % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize))
- elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize):
- EdkLogger.error("GenFds", GENFDS_ERROR,
- 'Region offset 0x%X overlaps with Region starting from 0x%X, size 0x%X' \
- % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize))
- elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize:
- if not Flag:
- GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize)))
- PadRegion = Region.Region()
- PadRegion.Offset = PreviousRegionStart + PreviousRegionSize
- PadRegion.Size = RegionObj.Offset - PadRegion.Offset
- if not Flag:
- PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict)
- PreviousRegionStart = RegionObj.Offset
- PreviousRegionSize = RegionObj.Size
- #
- # Verify current region fits within allocated FD section Size
- #
- if PreviousRegionStart + PreviousRegionSize > self.Size:
- EdkLogger.error("GenFds", GENFDS_ERROR,
- 'FD %s size too small to fit region with offset 0x%X and size 0x%X'
- % (self.FdUiName, PreviousRegionStart, PreviousRegionSize))
- #
- # Call each region's AddToBuffer function
- #
- GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function')
- RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict, Flag=Flag)
- #
- # Write the buffer contents to Fd file
- #
- GenFdsGlobalVariable.VerboseLogger('Write the buffer contents to Fd file')
- if not Flag:
- SaveFileOnChange(FdFileName, FdBuffer.getvalue())
- FdBuffer.close()
- GenFdsGlobalVariable.ImageBinDict[self.FdUiName.upper() + 'fd'] = FdFileName
- return FdFileName
-
- ## generate flash map file
- #
- # @param self The object pointer
- #
- def GenFlashMap (self):
- pass
-
-
-
-
-
-
-
-
+## @file +# process FD generation +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from . import Region +from . import Fv +import Common.LongFilePathOs as os +from io import BytesIO +import sys +from struct import * +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import FDClassObject +from Common import EdkLogger +from Common.BuildToolError import * +from Common.Misc import SaveFileOnChange +from Common.DataType import BINARY_FILE_TYPE_FV + +## generate FD +# +# +class FD(FDClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FDClassObject.__init__(self) + + ## GenFd() method + # + # Generate FD + # + # @retval string Generated FD file name + # + def GenFd (self, Flag = False): + if self.FdUiName.upper() + 'fd' in GenFdsGlobalVariable.ImageBinDict: + return GenFdsGlobalVariable.ImageBinDict[self.FdUiName.upper() + 'fd'] + + # + # Print Information + # + FdFileName = os.path.join(GenFdsGlobalVariable.FvDir, self.FdUiName + '.fd') + if not Flag: + GenFdsGlobalVariable.InfLogger("\nFd File Name:%s (%s)" %(self.FdUiName, FdFileName)) + + Offset = 0x00 + for item in self.BlockSizeList: + Offset = Offset + item[0] * item[1] + if Offset != self.Size: + EdkLogger.error("GenFds", GENFDS_ERROR, 'FD %s Size not consistent with block array' % self.FdUiName) + GenFdsGlobalVariable.VerboseLogger('Following Fv will be add to Fd !!!') + for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict: + GenFdsGlobalVariable.VerboseLogger(FvObj) + + HasCapsuleRegion = False + for RegionObj in self.RegionList: + if RegionObj.RegionType == 'CAPSULE': + HasCapsuleRegion = True + break + if HasCapsuleRegion: + TempFdBuffer = BytesIO() + PreviousRegionStart = -1 + PreviousRegionSize = 1 + + for RegionObj in self.RegionList : + if RegionObj.RegionType == 'CAPSULE': + continue + if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart: + pass + elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize): + pass + elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize: + if not Flag: + GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize))) + PadRegion = Region.Region() + PadRegion.Offset = PreviousRegionStart + PreviousRegionSize + PadRegion.Size = RegionObj.Offset - PadRegion.Offset + if not Flag: + PadRegion.AddToBuffer(TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict) + PreviousRegionStart = RegionObj.Offset + PreviousRegionSize = RegionObj.Size + # + # Call each region's AddToBuffer function + # + if PreviousRegionSize > self.Size: + pass + GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function') + RegionObj.AddToBuffer (TempFdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict) + + FdBuffer = BytesIO() + PreviousRegionStart = -1 + PreviousRegionSize = 1 + for RegionObj in self.RegionList : + if RegionObj.Offset + RegionObj.Size <= PreviousRegionStart: + EdkLogger.error("GenFds", GENFDS_ERROR, + 'Region offset 0x%X in wrong order with Region starting from 0x%X, size 0x%X\nRegions in FDF must have offsets appear in ascending order.'\ + % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize)) + elif RegionObj.Offset <= PreviousRegionStart or (RegionObj.Offset >=PreviousRegionStart and RegionObj.Offset < PreviousRegionStart + PreviousRegionSize): + EdkLogger.error("GenFds", GENFDS_ERROR, + 'Region offset 0x%X overlaps with Region starting from 0x%X, size 0x%X' \ + % (RegionObj.Offset, PreviousRegionStart, PreviousRegionSize)) + elif RegionObj.Offset > PreviousRegionStart + PreviousRegionSize: + if not Flag: + GenFdsGlobalVariable.InfLogger('Padding region starting from offset 0x%X, with size 0x%X' %(PreviousRegionStart + PreviousRegionSize, RegionObj.Offset - (PreviousRegionStart + PreviousRegionSize))) + PadRegion = Region.Region() + PadRegion.Offset = PreviousRegionStart + PreviousRegionSize + PadRegion.Size = RegionObj.Offset - PadRegion.Offset + if not Flag: + PadRegion.AddToBuffer(FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict) + PreviousRegionStart = RegionObj.Offset + PreviousRegionSize = RegionObj.Size + # + # Verify current region fits within allocated FD section Size + # + if PreviousRegionStart + PreviousRegionSize > self.Size: + EdkLogger.error("GenFds", GENFDS_ERROR, + 'FD %s size too small to fit region with offset 0x%X and size 0x%X' + % (self.FdUiName, PreviousRegionStart, PreviousRegionSize)) + # + # Call each region's AddToBuffer function + # + GenFdsGlobalVariable.VerboseLogger('Call each region\'s AddToBuffer function') + RegionObj.AddToBuffer (FdBuffer, self.BaseAddress, self.BlockSizeList, self.ErasePolarity, GenFdsGlobalVariable.ImageBinDict, self.DefineVarDict, Flag=Flag) + # + # Write the buffer contents to Fd file + # + GenFdsGlobalVariable.VerboseLogger('Write the buffer contents to Fd file') + if not Flag: + SaveFileOnChange(FdFileName, FdBuffer.getvalue()) + FdBuffer.close() + GenFdsGlobalVariable.ImageBinDict[self.FdUiName.upper() + 'fd'] = FdFileName + return FdFileName + + ## generate flash map file + # + # @param self The object pointer + # + def GenFlashMap (self): + pass + + + + + + + + diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py index feb4c72779..e3a780f302 100644 --- a/BaseTools/Source/Python/GenFds/FdfParser.py +++ b/BaseTools/Source/Python/GenFds/FdfParser.py @@ -1,4548 +1,4548 @@ -## @file
-# parse FDF file
-#
-# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
-# Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import print_function
-from __future__ import absolute_import
-from re import compile, DOTALL
-from string import hexdigits
-from uuid import UUID
-
-from Common.BuildToolError import *
-from Common import EdkLogger
-from Common.Misc import PathClass, tdict, ProcessDuplicatedInf, GuidStructureStringToGuidString
-from Common.StringUtils import NormPath, ReplaceMacro
-from Common import GlobalData
-from Common.Expression import *
-from Common.DataType import *
-from Common.MultipleWorkspace import MultipleWorkspace as mws
-import Common.LongFilePathOs as os
-from Common.LongFilePathSupport import OpenLongFilePath as open
-from Common.RangeExpression import RangeExpression
-from collections import OrderedDict
-
-from .Fd import FD
-from .Region import Region
-from .Fv import FV
-from .AprioriSection import AprioriSection
-from .FfsInfStatement import FfsInfStatement
-from .FfsFileStatement import FileStatement
-from .VerSection import VerSection
-from .UiSection import UiSection
-from .FvImageSection import FvImageSection
-from .DataSection import DataSection
-from .DepexSection import DepexSection
-from .CompressSection import CompressSection
-from .GuidSection import GuidSection
-from .SubTypeGuidSection import SubTypeGuidSection
-from .Capsule import EFI_CERT_TYPE_PKCS7_GUID, EFI_CERT_TYPE_RSA2048_SHA256_GUID, Capsule
-from .CapsuleData import CapsuleFfs, CapsulePayload, CapsuleFv, CapsuleFd, CapsuleAnyFile, CapsuleAfile
-from .RuleComplexFile import RuleComplexFile
-from .RuleSimpleFile import RuleSimpleFile
-from .EfiSection import EfiSection
-from .OptionRom import OPTIONROM
-from .OptRomInfStatement import OptRomInfStatement, OverrideAttribs
-from .OptRomFileStatement import OptRomFileStatement
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-
-T_CHAR_CR = '\r'
-T_CHAR_TAB = '\t'
-T_CHAR_DOUBLE_QUOTE = '\"'
-T_CHAR_SINGLE_QUOTE = '\''
-T_CHAR_BRACE_R = '}'
-
-SEPARATORS = {TAB_EQUAL_SPLIT, TAB_VALUE_SPLIT, TAB_COMMA_SPLIT, '{', T_CHAR_BRACE_R}
-ALIGNMENTS = {"Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K", "64K", "128K",
- "256K", "512K", "1M", "2M", "4M", "8M", "16M"}
-ALIGNMENT_NOAUTO = ALIGNMENTS - {"Auto"}
-CR_LB_SET = {T_CHAR_CR, TAB_LINE_BREAK}
-
-RegionSizePattern = compile(r"\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
-RegionSizeGuidPattern = compile(r"\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*")
-RegionOffsetPcdPattern = compile(r"\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$")
-ShortcutPcdPattern = compile(r"\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
-BaseAddrValuePattern = compile(r'^0[xX][0-9a-fA-F]+')
-FileExtensionPattern = compile(r'([a-zA-Z][a-zA-Z0-9]*)')
-TokenFindPattern = compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
-AllIncludeFileList = []
-
-# Get the closest parent
-def GetParentAtLine (Line):
- for Profile in AllIncludeFileList:
- if Profile.IsLineInFile(Line):
- return Profile
- return None
-
-# Check include loop
-def IsValidInclude (File, Line):
- for Profile in AllIncludeFileList:
- if Profile.IsLineInFile(Line) and Profile.FileName == File:
- return False
-
- return True
-
-def GetRealFileLine (File, Line):
- InsertedLines = 0
- for Profile in AllIncludeFileList:
- if Profile.IsLineInFile(Line):
- return Profile.GetLineInFile(Line)
- elif Line >= Profile.InsertStartLineNumber and Profile.Level == 1:
- InsertedLines += Profile.GetTotalLines()
-
- return (File, Line - InsertedLines)
-
-## The exception class that used to report error messages when parsing FDF
-#
-# Currently the "ToolName" is set to be "FdfParser".
-#
-class Warning (Exception):
- ## The constructor
- #
- # @param self The object pointer
- # @param Str The message to record
- # @param File The FDF name
- # @param Line The Line number that error occurs
- #
- def __init__(self, Str, File = None, Line = None):
- FileLineTuple = GetRealFileLine(File, Line)
- self.FileName = FileLineTuple[0]
- self.LineNumber = FileLineTuple[1]
- self.OriginalLineNumber = Line
- self.Message = Str
- self.ToolName = 'FdfParser'
-
- def __str__(self):
- return self.Message
-
- # helper functions to facilitate consistency in warnings
- # each function is for a different common warning
- @staticmethod
- def Expected(Str, File, Line):
- return Warning("expected {}".format(Str), File, Line)
- @staticmethod
- def ExpectedEquals(File, Line):
- return Warning.Expected("'='", File, Line)
- @staticmethod
- def ExpectedCurlyOpen(File, Line):
- return Warning.Expected("'{'", File, Line)
- @staticmethod
- def ExpectedCurlyClose(File, Line):
- return Warning.Expected("'}'", File, Line)
- @staticmethod
- def ExpectedBracketClose(File, Line):
- return Warning.Expected("']'", File, Line)
-
-## The Include file content class that used to record file data when parsing include file
-#
-# May raise Exception when opening file.
-#
-class IncludeFileProfile:
- ## The constructor
- #
- # @param self The object pointer
- # @param FileName The file that to be parsed
- #
- def __init__(self, FileName):
- self.FileName = FileName
- self.FileLinesList = []
- try:
- with open(FileName, "r") as fsock:
- self.FileLinesList = fsock.readlines()
- for index, line in enumerate(self.FileLinesList):
- if not line.endswith(TAB_LINE_BREAK):
- self.FileLinesList[index] += TAB_LINE_BREAK
- except:
- EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)
-
- self.InsertStartLineNumber = None
- self.InsertAdjust = 0
- self.IncludeFileList = []
- self.Level = 1 # first level include file
-
- def GetTotalLines(self):
- TotalLines = self.InsertAdjust + len(self.FileLinesList)
-
- for Profile in self.IncludeFileList:
- TotalLines += Profile.GetTotalLines()
-
- return TotalLines
-
- def IsLineInFile(self, Line):
- if Line >= self.InsertStartLineNumber and Line < self.InsertStartLineNumber + self.GetTotalLines():
- return True
-
- return False
-
- def GetLineInFile(self, Line):
- if not self.IsLineInFile (Line):
- return (self.FileName, -1)
-
- InsertedLines = self.InsertStartLineNumber
-
- for Profile in self.IncludeFileList:
- if Profile.IsLineInFile(Line):
- return Profile.GetLineInFile(Line)
- elif Line >= Profile.InsertStartLineNumber:
- InsertedLines += Profile.GetTotalLines()
-
- return (self.FileName, Line - InsertedLines + 1)
-
-## The FDF content class that used to record file data when parsing FDF
-#
-# May raise Exception when opening file.
-#
-class FileProfile:
- ## The constructor
- #
- # @param self The object pointer
- # @param FileName The file that to be parsed
- #
- def __init__(self, FileName):
- self.FileLinesList = []
- try:
- with open(FileName, "r") as fsock:
- self.FileLinesList = fsock.readlines()
-
- except:
- EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)
-
- self.FileName = FileName
- self.PcdDict = OrderedDict()
- self.PcdLocalDict = OrderedDict()
- self.InfList = []
- self.InfDict = {'ArchTBD':[]}
- # ECC will use this Dict and List information
- self.PcdFileLineDict = {}
- self.InfFileLineList = []
-
- self.FdDict = {}
- self.FdNameNotSet = False
- self.FvDict = {}
- self.CapsuleDict = {}
- self.RuleDict = {}
- self.OptRomDict = {}
- self.FmpPayloadDict = {}
-
-## The syntax parser for FDF
-#
-# PreprocessFile method should be called prior to ParseFile
-# CycleReferenceCheck method can detect cycles in FDF contents
-#
-# GetNext*** procedures mean these procedures will get next token first, then make judgement.
-# Get*** procedures mean these procedures will make judgement on current token only.
-#
-class FdfParser:
- ## The constructor
- #
- # @param self The object pointer
- # @param FileName The file that to be parsed
- #
- def __init__(self, FileName):
- self.Profile = FileProfile(FileName)
- self.FileName = FileName
- self.CurrentLineNumber = 1
- self.CurrentOffsetWithinLine = 0
- self.CurrentFdName = None
- self.CurrentFvName = None
- self._Token = ""
- self._SkippedChars = ""
- GlobalData.gFdfParser = self
-
- # Used to section info
- self._CurSection = []
- # Key: [section name, UI name, arch]
- # Value: {MACRO_NAME: MACRO_VALUE}
- self._MacroDict = tdict(True, 3)
- self._PcdDict = OrderedDict()
-
- self._WipeOffArea = []
- if GenFdsGlobalVariable.WorkSpaceDir == '':
- GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE")
-
- ## _SkipWhiteSpace() method
- #
- # Skip white spaces from current char.
- #
- # @param self The object pointer
- #
- def _SkipWhiteSpace(self):
- while not self._EndOfFile():
- if self._CurrentChar() in {TAB_PRINTCHAR_NUL, T_CHAR_CR, TAB_LINE_BREAK, TAB_SPACE_SPLIT, T_CHAR_TAB}:
- self._SkippedChars += str(self._CurrentChar())
- self._GetOneChar()
- else:
- return
- return
-
- ## _EndOfFile() method
- #
- # Judge current buffer pos is at file end
- #
- # @param self The object pointer
- # @retval True Current File buffer position is at file end
- # @retval False Current File buffer position is NOT at file end
- #
- def _EndOfFile(self):
- NumberOfLines = len(self.Profile.FileLinesList)
- SizeOfLastLine = len(self.Profile.FileLinesList[-1])
- if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:
- return True
- if self.CurrentLineNumber > NumberOfLines:
- return True
- return False
-
- ## _EndOfLine() method
- #
- # Judge current buffer pos is at line end
- #
- # @param self The object pointer
- # @retval True Current File buffer position is at line end
- # @retval False Current File buffer position is NOT at line end
- #
- def _EndOfLine(self):
- if self.CurrentLineNumber > len(self.Profile.FileLinesList):
- return True
- SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
- if self.CurrentOffsetWithinLine >= SizeOfCurrentLine:
- return True
- return False
-
- ## Rewind() method
- #
- # Reset file data buffer to the initial state
- #
- # @param self The object pointer
- # @param DestLine Optional new destination line number.
- # @param DestOffset Optional new destination offset.
- #
- def Rewind(self, DestLine = 1, DestOffset = 0):
- self.CurrentLineNumber = DestLine
- self.CurrentOffsetWithinLine = DestOffset
-
- ## _UndoOneChar() method
- #
- # Go back one char in the file buffer
- #
- # @param self The object pointer
- # @retval True Successfully go back one char
- # @retval False Not able to go back one char as file beginning reached
- #
- def _UndoOneChar(self):
- if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:
- return False
- elif self.CurrentOffsetWithinLine == 0:
- self.CurrentLineNumber -= 1
- self.CurrentOffsetWithinLine = len(self._CurrentLine()) - 1
- else:
- self.CurrentOffsetWithinLine -= 1
- return True
-
- ## _GetOneChar() method
- #
- # Move forward one char in the file buffer
- #
- # @param self The object pointer
- #
- def _GetOneChar(self):
- if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
- self.CurrentLineNumber += 1
- self.CurrentOffsetWithinLine = 0
- else:
- self.CurrentOffsetWithinLine += 1
-
- ## _CurrentChar() method
- #
- # Get the char pointed to by the file buffer pointer
- #
- # @param self The object pointer
- # @retval Char Current char
- #
- def _CurrentChar(self):
- return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]
-
- ## _NextChar() method
- #
- # Get the one char pass the char pointed to by the file buffer pointer
- #
- # @param self The object pointer
- # @retval Char Next char
- #
- def _NextChar(self):
- if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:
- return self.Profile.FileLinesList[self.CurrentLineNumber][0]
- return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]
-
- ## _SetCurrentCharValue() method
- #
- # Modify the value of current char
- #
- # @param self The object pointer
- # @param Value The new value of current char
- #
- def _SetCurrentCharValue(self, Value):
- self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value
-
- ## _CurrentLine() method
- #
- # Get the list that contains current line contents
- #
- # @param self The object pointer
- # @retval List current line contents
- #
- def _CurrentLine(self):
- return self.Profile.FileLinesList[self.CurrentLineNumber - 1]
-
- def _StringToList(self):
- self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]
- if not self.Profile.FileLinesList:
- EdkLogger.error('FdfParser', FILE_READ_FAILURE, 'The file is empty!', File=self.FileName)
- self.Profile.FileLinesList[-1].append(' ')
-
- def _ReplaceFragment(self, StartPos, EndPos, Value = ' '):
- if StartPos[0] == EndPos[0]:
- Offset = StartPos[1]
- while Offset <= EndPos[1]:
- self.Profile.FileLinesList[StartPos[0]][Offset] = Value
- Offset += 1
- return
-
- Offset = StartPos[1]
- while self.Profile.FileLinesList[StartPos[0]][Offset] not in CR_LB_SET:
- self.Profile.FileLinesList[StartPos[0]][Offset] = Value
- Offset += 1
-
- Line = StartPos[0]
- while Line < EndPos[0]:
- Offset = 0
- while self.Profile.FileLinesList[Line][Offset] not in CR_LB_SET:
- self.Profile.FileLinesList[Line][Offset] = Value
- Offset += 1
- Line += 1
-
- Offset = 0
- while Offset <= EndPos[1]:
- self.Profile.FileLinesList[EndPos[0]][Offset] = Value
- Offset += 1
-
- def _SetMacroValue(self, Macro, Value):
- if not self._CurSection:
- return
-
- MacroDict = {}
- if not self._MacroDict[self._CurSection[0], self._CurSection[1], self._CurSection[2]]:
- self._MacroDict[self._CurSection[0], self._CurSection[1], self._CurSection[2]] = MacroDict
- else:
- MacroDict = self._MacroDict[self._CurSection[0], self._CurSection[1], self._CurSection[2]]
- MacroDict[Macro] = Value
-
- def _GetMacroValue(self, Macro):
- # Highest priority
- if Macro in GlobalData.gCommandLineDefines:
- return GlobalData.gCommandLineDefines[Macro]
- if Macro in GlobalData.gGlobalDefines:
- return GlobalData.gGlobalDefines[Macro]
-
- if self._CurSection:
- MacroDict = self._MacroDict[
- self._CurSection[0],
- self._CurSection[1],
- self._CurSection[2]
- ]
- if MacroDict and Macro in MacroDict:
- return MacroDict[Macro]
-
- # Lowest priority
- if Macro in GlobalData.gPlatformDefines:
- return GlobalData.gPlatformDefines[Macro]
- return None
-
- def _SectionHeaderParser(self, Section):
- # [Defines]
- # [FD.UiName]: use dummy instead if UI name is optional
- # [FV.UiName]
- # [Capsule.UiName]
- # [Rule]: don't take rule section into account, macro is not allowed in this section
- # [OptionRom.DriverName]
- self._CurSection = []
- Section = Section.strip()[1:-1].upper().replace(' ', '').strip(TAB_SPLIT)
- ItemList = Section.split(TAB_SPLIT)
- Item = ItemList[0]
- if Item == '' or Item == 'RULE':
- return
-
- if Item == TAB_COMMON_DEFINES.upper():
- self._CurSection = [TAB_COMMON, TAB_COMMON, TAB_COMMON]
- elif len(ItemList) > 1:
- self._CurSection = [ItemList[0], ItemList[1], TAB_COMMON]
- elif len(ItemList) > 0:
- self._CurSection = [ItemList[0], 'DUMMY', TAB_COMMON]
-
- ## PreprocessFile() method
- #
- # Preprocess file contents, replace comments with spaces.
- # In the end, rewind the file buffer pointer to the beginning
- # BUGBUG: No !include statement processing contained in this procedure
- # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
- #
- # @param self The object pointer
- #
- def PreprocessFile(self):
- self.Rewind()
- InComment = False
- DoubleSlashComment = False
- HashComment = False
- # HashComment in quoted string " " is ignored.
- InString = False
-
- while not self._EndOfFile():
-
- if self._CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment:
- InString = not InString
- # meet new line, then no longer in a comment for // and '#'
- if self._CurrentChar() == TAB_LINE_BREAK:
- self.CurrentLineNumber += 1
- self.CurrentOffsetWithinLine = 0
- if InComment and DoubleSlashComment:
- InComment = False
- DoubleSlashComment = False
- if InComment and HashComment:
- InComment = False
- HashComment = False
- # check for */ comment end
- elif InComment and not DoubleSlashComment and not HashComment and self._CurrentChar() == TAB_STAR and self._NextChar() == TAB_BACK_SLASH:
- self._SetCurrentCharValue(TAB_SPACE_SPLIT)
- self._GetOneChar()
- self._SetCurrentCharValue(TAB_SPACE_SPLIT)
- self._GetOneChar()
- InComment = False
- # set comments to spaces
- elif InComment:
- self._SetCurrentCharValue(TAB_SPACE_SPLIT)
- self._GetOneChar()
- # check for // comment
- elif self._CurrentChar() == TAB_BACK_SLASH and self._NextChar() == TAB_BACK_SLASH and not self._EndOfLine():
- InComment = True
- DoubleSlashComment = True
- # check for '#' comment
- elif self._CurrentChar() == TAB_COMMENT_SPLIT and not self._EndOfLine() and not InString:
- InComment = True
- HashComment = True
- # check for /* comment start
- elif self._CurrentChar() == TAB_BACK_SLASH and self._NextChar() == TAB_STAR:
- self._SetCurrentCharValue(TAB_SPACE_SPLIT)
- self._GetOneChar()
- self._SetCurrentCharValue(TAB_SPACE_SPLIT)
- self._GetOneChar()
- InComment = True
- else:
- self._GetOneChar()
-
- # restore from ListOfList to ListOfString
- self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
- self.Rewind()
-
- ## PreprocessIncludeFile() method
- #
- # Preprocess file contents, replace !include statements with file contents.
- # In the end, rewind the file buffer pointer to the beginning
- #
- # @param self The object pointer
- #
- def PreprocessIncludeFile(self):
- # nested include support
- Processed = False
- MacroDict = {}
- while self._GetNextToken():
-
- if self._Token == TAB_DEFINE:
- if not self._GetNextToken():
- raise Warning.Expected("Macro name", self.FileName, self.CurrentLineNumber)
- Macro = self._Token
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- Value = self._GetExpression()
- MacroDict[Macro] = Value
-
- elif self._Token == TAB_INCLUDE:
- Processed = True
- IncludeLine = self.CurrentLineNumber
- IncludeOffset = self.CurrentOffsetWithinLine - len(TAB_INCLUDE)
- if not self._GetNextToken():
- raise Warning.Expected("include file name", self.FileName, self.CurrentLineNumber)
- IncFileName = self._Token
- PreIndex = 0
- StartPos = IncFileName.find('$(', PreIndex)
- EndPos = IncFileName.find(')', StartPos+2)
- while StartPos != -1 and EndPos != -1:
- Macro = IncFileName[StartPos+2: EndPos]
- MacroVal = self._GetMacroValue(Macro)
- if not MacroVal:
- if Macro in MacroDict:
- MacroVal = MacroDict[Macro]
- if MacroVal is not None:
- IncFileName = IncFileName.replace('$(' + Macro + ')', MacroVal, 1)
- if MacroVal.find('$(') != -1:
- PreIndex = StartPos
- else:
- PreIndex = StartPos + len(MacroVal)
- else:
- raise Warning("The Macro %s is not defined" %Macro, self.FileName, self.CurrentLineNumber)
- StartPos = IncFileName.find('$(', PreIndex)
- EndPos = IncFileName.find(')', StartPos+2)
-
- IncludedFile = NormPath(IncFileName)
- #
- # First search the include file under the same directory as FDF file
- #
- IncludedFile1 = PathClass(IncludedFile, os.path.dirname(self.FileName))
- ErrorCode = IncludedFile1.Validate()[0]
- if ErrorCode != 0:
- #
- # Then search the include file under the same directory as DSC file
- #
- PlatformDir = ''
- if GenFdsGlobalVariable.ActivePlatform:
- PlatformDir = GenFdsGlobalVariable.ActivePlatform.Dir
- elif GlobalData.gActivePlatform:
- PlatformDir = GlobalData.gActivePlatform.MetaFile.Dir
- IncludedFile1 = PathClass(IncludedFile, PlatformDir)
- ErrorCode = IncludedFile1.Validate()[0]
- if ErrorCode != 0:
- #
- # Also search file under the WORKSPACE directory
- #
- IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace)
- ErrorCode = IncludedFile1.Validate()[0]
- if ErrorCode != 0:
- raise Warning("The include file does not exist under below directories: \n%s\n%s\n%s\n"%(os.path.dirname(self.FileName), PlatformDir, GlobalData.gWorkspace),
- self.FileName, self.CurrentLineNumber)
-
- if not IsValidInclude (IncludedFile1.Path, self.CurrentLineNumber):
- raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1.Path), self.FileName, self.CurrentLineNumber)
-
- IncFileProfile = IncludeFileProfile(IncludedFile1.Path)
-
- CurrentLine = self.CurrentLineNumber
- CurrentOffset = self.CurrentOffsetWithinLine
- # list index of the insertion, note that line number is 'CurrentLine + 1'
- InsertAtLine = CurrentLine
- ParentProfile = GetParentAtLine (CurrentLine)
- if ParentProfile is not None:
- ParentProfile.IncludeFileList.insert(0, IncFileProfile)
- IncFileProfile.Level = ParentProfile.Level + 1
- IncFileProfile.InsertStartLineNumber = InsertAtLine + 1
- # deal with remaining portions after "!include filename", if exists.
- if self._GetNextToken():
- if self.CurrentLineNumber == CurrentLine:
- RemainingLine = self._CurrentLine()[CurrentOffset:]
- self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine)
- IncFileProfile.InsertAdjust += 1
- self.CurrentLineNumber += 1
- self.CurrentOffsetWithinLine = 0
-
- for Line in IncFileProfile.FileLinesList:
- self.Profile.FileLinesList.insert(InsertAtLine, Line)
- self.CurrentLineNumber += 1
- InsertAtLine += 1
-
- # reversely sorted to better determine error in file
- AllIncludeFileList.insert(0, IncFileProfile)
-
- # comment out the processed include file statement
- TempList = list(self.Profile.FileLinesList[IncludeLine - 1])
- TempList.insert(IncludeOffset, TAB_COMMENT_SPLIT)
- self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)
- if Processed: # Nested and back-to-back support
- self.Rewind(DestLine = IncFileProfile.InsertStartLineNumber - 1)
- Processed = False
- # Preprocess done.
- self.Rewind()
-
- @staticmethod
- def _GetIfListCurrentItemStat(IfList):
- if len(IfList) == 0:
- return True
-
- for Item in IfList:
- if Item[1] == False:
- return False
-
- return True
-
- ## PreprocessConditionalStatement() method
- #
- # Preprocess conditional statement.
- # In the end, rewind the file buffer pointer to the beginning
- #
- # @param self The object pointer
- #
- def PreprocessConditionalStatement(self):
- # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
- IfList = []
- RegionLayoutLine = 0
- ReplacedLine = -1
- while self._GetNextToken():
- # Determine section name and the location dependent macro
- if self._GetIfListCurrentItemStat(IfList):
- if self._Token.startswith(TAB_SECTION_START):
- Header = self._Token
- if not self._Token.endswith(TAB_SECTION_END):
- self._SkipToToken(TAB_SECTION_END)
- Header += self._SkippedChars
- if Header.find('$(') != -1:
- raise Warning("macro cannot be used in section header", self.FileName, self.CurrentLineNumber)
- self._SectionHeaderParser(Header)
- continue
- # Replace macros except in RULE section or out of section
- elif self._CurSection and ReplacedLine != self.CurrentLineNumber:
- ReplacedLine = self.CurrentLineNumber
- self._UndoToken()
- CurLine = self.Profile.FileLinesList[ReplacedLine - 1]
- PreIndex = 0
- StartPos = CurLine.find('$(', PreIndex)
- EndPos = CurLine.find(')', StartPos+2)
- while StartPos != -1 and EndPos != -1 and self._Token not in {TAB_IF_DEF, TAB_IF_N_DEF, TAB_IF, TAB_ELSE_IF}:
- MacroName = CurLine[StartPos+2: EndPos]
- MacroValue = self._GetMacroValue(MacroName)
- if MacroValue is not None:
- CurLine = CurLine.replace('$(' + MacroName + ')', MacroValue, 1)
- if MacroValue.find('$(') != -1:
- PreIndex = StartPos
- else:
- PreIndex = StartPos + len(MacroValue)
- else:
- PreIndex = EndPos + 1
- StartPos = CurLine.find('$(', PreIndex)
- EndPos = CurLine.find(')', StartPos+2)
- self.Profile.FileLinesList[ReplacedLine - 1] = CurLine
- continue
-
- if self._Token == TAB_DEFINE:
- if self._GetIfListCurrentItemStat(IfList):
- if not self._CurSection:
- raise Warning("macro cannot be defined in Rule section or out of section", self.FileName, self.CurrentLineNumber)
- DefineLine = self.CurrentLineNumber - 1
- DefineOffset = self.CurrentOffsetWithinLine - len(TAB_DEFINE)
- if not self._GetNextToken():
- raise Warning.Expected("Macro name", self.FileName, self.CurrentLineNumber)
- Macro = self._Token
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- Value = self._GetExpression()
- self._SetMacroValue(Macro, Value)
- self._WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
- elif self._Token == 'SET':
- if not self._GetIfListCurrentItemStat(IfList):
- continue
- SetLine = self.CurrentLineNumber - 1
- SetOffset = self.CurrentOffsetWithinLine - len('SET')
- PcdPair = self._GetNextPcdSettings()
- PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- Value = self._GetExpression()
- Value = self._EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)
-
- self._PcdDict[PcdName] = Value
-
- self.Profile.PcdDict[PcdPair] = Value
- self.SetPcdLocalation(PcdPair)
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
-
- self._WipeOffArea.append(((SetLine, SetOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
- elif self._Token in {TAB_IF_DEF, TAB_IF_N_DEF, TAB_IF}:
- IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self._Token))
- IfList.append([IfStartPos, None, None])
-
- CondLabel = self._Token
- Expression = self._GetExpression()
-
- if CondLabel == TAB_IF:
- ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
- else:
- ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in')
- if CondLabel == TAB_IF_N_DEF:
- ConditionSatisfied = not ConditionSatisfied
-
- BranchDetermined = ConditionSatisfied
- IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]
- if ConditionSatisfied:
- self._WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
- elif self._Token in {TAB_ELSE_IF, TAB_ELSE}:
- ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self._Token))
- if len(IfList) <= 0:
- raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)
-
- if IfList[-1][1]:
- IfList[-1] = [ElseStartPos, False, True]
- self._WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
- else:
- self._WipeOffArea.append((IfList[-1][0], ElseStartPos))
- IfList[-1] = [ElseStartPos, True, IfList[-1][2]]
- if self._Token == TAB_ELSE_IF:
- Expression = self._GetExpression()
- ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')
- IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]
-
- if IfList[-1][1]:
- if IfList[-1][2]:
- IfList[-1][1] = False
- else:
- IfList[-1][2] = True
- self._WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
- elif self._Token == '!endif':
- if len(IfList) <= 0:
- raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)
- if IfList[-1][1]:
- self._WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
- else:
- self._WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))
-
- IfList.pop()
- elif not IfList: # Don't use PCDs inside conditional directive
- if self.CurrentLineNumber <= RegionLayoutLine:
- # Don't try the same line twice
- continue
- SetPcd = ShortcutPcdPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
- if SetPcd:
- self._PcdDict[SetPcd.group('name')] = SetPcd.group('value')
- RegionLayoutLine = self.CurrentLineNumber
- continue
- RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])
- if not RegionSize:
- RegionLayoutLine = self.CurrentLineNumber
- continue
- RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber])
- if not RegionSizeGuid:
- RegionLayoutLine = self.CurrentLineNumber + 1
- continue
- self._PcdDict[RegionSizeGuid.group('base')] = RegionSize.group('base')
- self._PcdDict[RegionSizeGuid.group('size')] = RegionSize.group('size')
- RegionLayoutLine = self.CurrentLineNumber + 1
-
- if IfList:
- raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)
- self.Rewind()
-
- def _CollectMacroPcd(self):
- MacroDict = {}
-
- # PCD macro
- MacroDict.update(GlobalData.gPlatformPcds)
- MacroDict.update(self._PcdDict)
-
- # Lowest priority
- MacroDict.update(GlobalData.gPlatformDefines)
-
- if self._CurSection:
- # Defines macro
- ScopeMacro = self._MacroDict[TAB_COMMON, TAB_COMMON, TAB_COMMON]
- if ScopeMacro:
- MacroDict.update(ScopeMacro)
-
- # Section macro
- ScopeMacro = self._MacroDict[
- self._CurSection[0],
- self._CurSection[1],
- self._CurSection[2]
- ]
- if ScopeMacro:
- MacroDict.update(ScopeMacro)
-
- MacroDict.update(GlobalData.gGlobalDefines)
- MacroDict.update(GlobalData.gCommandLineDefines)
- for Item in GlobalData.BuildOptionPcd:
- if isinstance(Item, tuple):
- continue
- PcdName, TmpValue = Item.split(TAB_EQUAL_SPLIT)
- TmpValue = BuildOptionValue(TmpValue, {})
- MacroDict[PcdName.strip()] = TmpValue
- # Highest priority
-
- return MacroDict
-
- def _EvaluateConditional(self, Expression, Line, Op = None, Value = None):
- MacroPcdDict = self._CollectMacroPcd()
- if Op == 'eval':
- try:
- if Value:
- return ValueExpression(Expression, MacroPcdDict)(True)
- else:
- return ValueExpression(Expression, MacroPcdDict)()
- except WrnExpression as Excpt:
- #
- # Catch expression evaluation warning here. We need to report
- # the precise number of line and return the evaluation result
- #
- EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),
- File=self.FileName, ExtraData=self._CurrentLine(),
- Line=Line)
- return Excpt.result
- except Exception as Excpt:
- if hasattr(Excpt, 'Pcd'):
- if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
- Info = GlobalData.gPlatformOtherPcds[Excpt.Pcd]
- raise Warning("Cannot use this PCD (%s) in an expression as"
- " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
- " of the DSC file (%s), and it is currently defined in this section:"
- " %s, line #: %d." % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE'], Info[0], Info[1]),
- self.FileName, Line)
- else:
- raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE']),
- self.FileName, Line)
- else:
- raise Warning(str(Excpt), self.FileName, Line)
- else:
- if Expression.startswith('$(') and Expression[-1] == ')':
- Expression = Expression[2:-1]
- return Expression in MacroPcdDict
-
- ## _IsToken() method
- #
- # Check whether input string is found from current char position along
- # If found, the string value is put into self._Token
- #
- # @param self The object pointer
- # @param String The string to search
- # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
- # @retval True Successfully find string, file buffer pointer moved forward
- # @retval False Not able to find string, file buffer pointer not changed
- #
- def _IsToken(self, String, IgnoreCase = False):
- self._SkipWhiteSpace()
-
- # Only consider the same line, no multi-line token allowed
- StartPos = self.CurrentOffsetWithinLine
- index = -1
- if IgnoreCase:
- index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(String.upper())
- else:
- index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(String)
- if index == 0:
- self.CurrentOffsetWithinLine += len(String)
- self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]
- return True
- return False
-
- ## _IsKeyword() method
- #
- # Check whether input keyword is found from current char position along, whole word only!
- # If found, the string value is put into self._Token
- #
- # @param self The object pointer
- # @param Keyword The string to search
- # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
- # @retval True Successfully find string, file buffer pointer moved forward
- # @retval False Not able to find string, file buffer pointer not changed
- #
- def _IsKeyword(self, KeyWord, IgnoreCase = False):
- self._SkipWhiteSpace()
-
- # Only consider the same line, no multi-line token allowed
- StartPos = self.CurrentOffsetWithinLine
- index = -1
- if IgnoreCase:
- index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(KeyWord.upper())
- else:
- index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(KeyWord)
- if index == 0:
- followingChar = self._CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)]
- if not str(followingChar).isspace() and followingChar not in SEPARATORS:
- return False
- self.CurrentOffsetWithinLine += len(KeyWord)
- self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]
- return True
- return False
-
- def _GetExpression(self):
- Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1]
- Index = len(Line) - 1
- while Line[Index] in CR_LB_SET:
- Index -= 1
- ExpressionString = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:Index+1]
- self.CurrentOffsetWithinLine += len(ExpressionString)
- ExpressionString = ExpressionString.strip()
- return ExpressionString
-
- ## _GetNextWord() method
- #
- # Get next C name from file lines
- # If found, the string value is put into self._Token
- #
- # @param self The object pointer
- # @retval True Successfully find a C name string, file buffer pointer moved forward
- # @retval False Not able to find a C name string, file buffer pointer not changed
- #
- def _GetNextWord(self):
- self._SkipWhiteSpace()
- if self._EndOfFile():
- return False
-
- TempChar = self._CurrentChar()
- StartPos = self.CurrentOffsetWithinLine
- if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_':
- self._GetOneChar()
- while not self._EndOfLine():
- TempChar = self._CurrentChar()
- if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \
- or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-':
- self._GetOneChar()
-
- else:
- break
-
- self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]
- return True
-
- return False
-
- def _GetNextPcdWord(self):
- self._SkipWhiteSpace()
- if self._EndOfFile():
- return False
-
- TempChar = self._CurrentChar()
- StartPos = self.CurrentOffsetWithinLine
- if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_' or TempChar == TAB_SECTION_START or TempChar == TAB_SECTION_END:
- self._GetOneChar()
- while not self._EndOfLine():
- TempChar = self._CurrentChar()
- if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \
- or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-' or TempChar == TAB_SECTION_START or TempChar == TAB_SECTION_END:
- self._GetOneChar()
-
- else:
- break
-
- self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]
- return True
-
- return False
-
- ## _GetNextToken() method
- #
- # Get next token unit before a separator
- # If found, the string value is put into self._Token
- #
- # @param self The object pointer
- # @retval True Successfully find a token unit, file buffer pointer moved forward
- # @retval False Not able to find a token unit, file buffer pointer not changed
- #
- def _GetNextToken(self):
- # Skip leading spaces, if exist.
- self._SkipWhiteSpace()
- if self._EndOfFile():
- return False
- # Record the token start position, the position of the first non-space char.
- StartPos = self.CurrentOffsetWithinLine
- StartLine = self.CurrentLineNumber
- while StartLine == self.CurrentLineNumber:
- TempChar = self._CurrentChar()
- # Try to find the end char that is not a space and not in separator tuple.
- # That is, when we got a space or any char in the tuple, we got the end of token.
- if not str(TempChar).isspace() and TempChar not in SEPARATORS:
- self._GetOneChar()
- # if we happen to meet a separator as the first char, we must proceed to get it.
- # That is, we get a token that is a separator char. normally it is the boundary of other tokens.
- elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPARATORS:
- self._GetOneChar()
- break
- else:
- break
-# else:
-# return False
-
- EndPos = self.CurrentOffsetWithinLine
- if self.CurrentLineNumber != StartLine:
- EndPos = len(self.Profile.FileLinesList[StartLine-1])
- self._Token = self.Profile.FileLinesList[StartLine-1][StartPos: EndPos]
- if self._Token.lower() in {TAB_IF, TAB_END_IF, TAB_ELSE_IF, TAB_ELSE, TAB_IF_DEF, TAB_IF_N_DEF, TAB_ERROR, TAB_INCLUDE}:
- self._Token = self._Token.lower()
- if StartPos != self.CurrentOffsetWithinLine:
- return True
- else:
- return False
-
- ## _GetNextGuid() method
- #
- # Get next token unit before a separator
- # If found, the GUID string is put into self._Token
- #
- # @param self The object pointer
- # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
- # @retval False Not able to find a registry format GUID, file buffer pointer not changed
- #
- def _GetNextGuid(self):
- if not self._GetNextToken():
- return False
- if GlobalData.gGuidPattern.match(self._Token) is not None:
- return True
- elif self._Token in GlobalData.gGuidDict:
- return True
- else:
- self._UndoToken()
- return False
-
- @staticmethod
- def _Verify(Name, Value, Scope):
- # value verification only applies to numeric values.
- if Scope not in TAB_PCD_NUMERIC_TYPES:
- return
-
- ValueNumber = 0
- try:
- ValueNumber = int(Value, 0)
- except:
- EdkLogger.error("FdfParser", FORMAT_INVALID, "The value is not valid dec or hex number for %s." % Name)
- if ValueNumber < 0:
- EdkLogger.error("FdfParser", FORMAT_INVALID, "The value can't be set to negative value for %s." % Name)
- if ValueNumber > MAX_VAL_TYPE[Scope]:
- EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name)
- return True
-
- ## _UndoToken() method
- #
- # Go back one token unit in file buffer
- #
- # @param self The object pointer
- #
- def _UndoToken(self):
- self._UndoOneChar()
- while self._CurrentChar().isspace():
- if not self._UndoOneChar():
- self._GetOneChar()
- return
-
-
- StartPos = self.CurrentOffsetWithinLine
- CurrentLine = self.CurrentLineNumber
- while CurrentLine == self.CurrentLineNumber:
-
- TempChar = self._CurrentChar()
- # Try to find the end char that is not a space and not in separator tuple.
- # That is, when we got a space or any char in the tuple, we got the end of token.
- if not str(TempChar).isspace() and not TempChar in SEPARATORS:
- if not self._UndoOneChar():
- return
- # if we happen to meet a separator as the first char, we must proceed to get it.
- # That is, we get a token that is a separator char. normally it is the boundary of other tokens.
- elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPARATORS:
- return
- else:
- break
-
- self._GetOneChar()
-
- ## _GetNextHexNumber() method
- #
- # Get next HEX data before a separator
- # If found, the HEX data is put into self._Token
- #
- # @param self The object pointer
- # @retval True Successfully find a HEX data, file buffer pointer moved forward
- # @retval False Not able to find a HEX data, file buffer pointer not changed
- #
- def _GetNextHexNumber(self):
- if not self._GetNextToken():
- return False
- if GlobalData.gHexPatternAll.match(self._Token):
- return True
- else:
- self._UndoToken()
- return False
-
- ## _GetNextDecimalNumber() method
- #
- # Get next decimal data before a separator
- # If found, the decimal data is put into self._Token
- #
- # @param self The object pointer
- # @retval True Successfully find a decimal data, file buffer pointer moved forward
- # @retval False Not able to find a decimal data, file buffer pointer not changed
- #
- def _GetNextDecimalNumber(self):
- if not self._GetNextToken():
- return False
- if self._Token.isdigit():
- return True
- else:
- self._UndoToken()
- return False
-
- def _GetNextPcdSettings(self):
- if not self._GetNextWord():
- raise Warning.Expected("<PcdTokenSpaceCName>", self.FileName, self.CurrentLineNumber)
- pcdTokenSpaceCName = self._Token
-
- if not self._IsToken(TAB_SPLIT):
- raise Warning.Expected(".", self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextWord():
- raise Warning.Expected("<PcdCName>", self.FileName, self.CurrentLineNumber)
- pcdCName = self._Token
-
- Fields = []
- while self._IsToken(TAB_SPLIT):
- if not self._GetNextPcdWord():
- raise Warning.Expected("Pcd Fields", self.FileName, self.CurrentLineNumber)
- Fields.append(self._Token)
-
- return (pcdCName, pcdTokenSpaceCName,TAB_SPLIT.join(Fields))
-
- ## _GetStringData() method
- #
- # Get string contents quoted in ""
- # If found, the decimal data is put into self._Token
- #
- # @param self The object pointer
- # @retval True Successfully find a string data, file buffer pointer moved forward
- # @retval False Not able to find a string data, file buffer pointer not changed
- #
- def _GetStringData(self):
- QuoteToUse = None
- if self._Token.startswith(T_CHAR_DOUBLE_QUOTE) or self._Token.startswith("L\""):
- QuoteToUse = T_CHAR_DOUBLE_QUOTE
- elif self._Token.startswith(T_CHAR_SINGLE_QUOTE) or self._Token.startswith("L\'"):
- QuoteToUse = T_CHAR_SINGLE_QUOTE
- else:
- return False
-
- self._UndoToken()
- self._SkipToToken(QuoteToUse)
- currentLineNumber = self.CurrentLineNumber
-
- if not self._SkipToToken(QuoteToUse):
- raise Warning(QuoteToUse, self.FileName, self.CurrentLineNumber)
- if currentLineNumber != self.CurrentLineNumber:
- raise Warning(QuoteToUse, self.FileName, self.CurrentLineNumber)
- self._Token = self._SkippedChars.rstrip(QuoteToUse)
- return True
-
- ## _SkipToToken() method
- #
- # Search forward in file buffer for the string
- # The skipped chars are put into self._SkippedChars
- #
- # @param self The object pointer
- # @param String The string to search
- # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
- # @retval True Successfully find the string, file buffer pointer moved forward
- # @retval False Not able to find the string, file buffer pointer not changed
- #
- def _SkipToToken(self, String, IgnoreCase = False):
- StartPos = self.GetFileBufferPos()
-
- self._SkippedChars = ""
- while not self._EndOfFile():
- index = -1
- if IgnoreCase:
- index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(String.upper())
- else:
- index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(String)
- if index == 0:
- self.CurrentOffsetWithinLine += len(String)
- self._SkippedChars += String
- return True
- self._SkippedChars += str(self._CurrentChar())
- self._GetOneChar()
-
- self.SetFileBufferPos(StartPos)
- self._SkippedChars = ""
- return False
-
- ## GetFileBufferPos() method
- #
- # Return the tuple of current line and offset within the line
- #
- # @param self The object pointer
- # @retval Tuple Line number and offset pair
- #
- def GetFileBufferPos(self):
- return (self.CurrentLineNumber, self.CurrentOffsetWithinLine)
-
- ## SetFileBufferPos() method
- #
- # Restore the file buffer position
- #
- # @param self The object pointer
- # @param Pos The new file buffer position
- #
- def SetFileBufferPos(self, Pos):
- (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos
-
- ## Preprocess() method
- #
- # Preprocess comment, conditional directive, include directive, replace macro.
- # Exception will be raised if syntax error found
- #
- # @param self The object pointer
- #
- def Preprocess(self):
- self._StringToList()
- self.PreprocessFile()
- self.PreprocessIncludeFile()
- self._StringToList()
- self.PreprocessFile()
- self.PreprocessConditionalStatement()
- self._StringToList()
- for Pos in self._WipeOffArea:
- self._ReplaceFragment(Pos[0], Pos[1])
- self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]
-
- while self._GetDefines():
- pass
-
- ## ParseFile() method
- #
- # Parse the file profile buffer to extract fd, fv ... information
- # Exception will be raised if syntax error found
- #
- # @param self The object pointer
- #
- def ParseFile(self):
- try:
- self.Preprocess()
- self._GetError()
- #
- # Keep processing sections of the FDF until no new sections or a syntax error is found
- #
- while self._GetFd() or self._GetFv() or self._GetFmp() or self._GetCapsule() or self._GetRule() or self._GetOptionRom():
- pass
-
- except Warning as X:
- self._UndoToken()
- #'\n\tGot Token: \"%s\" from File %s\n' % (self._Token, FileLineTuple[0]) + \
- # At this point, the closest parent would be the included file itself
- Profile = GetParentAtLine(X.OriginalLineNumber)
- if Profile is not None:
- X.Message += ' near line %d, column %d: %s' \
- % (X.LineNumber, 0, Profile.FileLinesList[X.LineNumber-1])
- else:
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- X.Message += ' near line %d, column %d: %s' \
- % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:].rstrip(TAB_LINE_BREAK).rstrip(T_CHAR_CR))
- raise
-
- ## SectionParser() method
- #
- # Parse the file section info
- # Exception will be raised if syntax error found
- #
- # @param self The object pointer
- # @param section The section string
-
- def SectionParser(self, section):
- S = section.upper()
- if not S.startswith("[DEFINES") and not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \
- and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM.") and not S.startswith('[FMPPAYLOAD.'):
- raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self.FileName, self.CurrentLineNumber)
-
- ## _GetDefines() method
- #
- # Get Defines section contents and store its data into AllMacrosList
- #
- # @param self The object pointer
- # @retval True Successfully find a Defines
- # @retval False Not able to find a Defines
- #
- def _GetDefines(self):
- if not self._GetNextToken():
- return False
-
- S = self._Token.upper()
- if S.startswith(TAB_SECTION_START) and not S.startswith("[DEFINES"):
- self.SectionParser(S)
- self._UndoToken()
- return False
-
- self._UndoToken()
- if not self._IsToken("[DEFINES", True):
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
- # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
- raise Warning.Expected("[DEFINES", self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken(TAB_SECTION_END):
- raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)
-
- while self._GetNextWord():
- # handle the SET statement
- if self._Token == 'SET':
- self._UndoToken()
- self._GetSetStatement(None)
- continue
-
- Macro = self._Token
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextToken() or self._Token.startswith(TAB_SECTION_START):
- raise Warning.Expected("MACRO value", self.FileName, self.CurrentLineNumber)
- Value = self._Token
-
- return False
-
- ##_GetError() method
- def _GetError(self):
- #save the Current information
- CurrentLine = self.CurrentLineNumber
- CurrentOffset = self.CurrentOffsetWithinLine
- while self._GetNextToken():
- if self._Token == TAB_ERROR:
- EdkLogger.error('FdfParser', ERROR_STATEMENT, self._CurrentLine().replace(TAB_ERROR, '', 1), File=self.FileName, Line=self.CurrentLineNumber)
- self.CurrentLineNumber = CurrentLine
- self.CurrentOffsetWithinLine = CurrentOffset
-
- ## _GetFd() method
- #
- # Get FD section contents and store its data into FD dictionary of self.Profile
- #
- # @param self The object pointer
- # @retval True Successfully find a FD
- # @retval False Not able to find a FD
- #
- def _GetFd(self):
- if not self._GetNextToken():
- return False
-
- S = self._Token.upper()
- if S.startswith(TAB_SECTION_START) and not S.startswith("[FD."):
- if not S.startswith("[FV.") and not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \
- and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
- raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)
- self._UndoToken()
- return False
-
- self._UndoToken()
- if not self._IsToken("[FD.", True):
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
- # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
- raise Warning.Expected("[FD.]", self.FileName, self.CurrentLineNumber)
-
- FdName = self._GetUiName()
- if FdName == "":
- if len (self.Profile.FdDict) == 0:
- FdName = GenFdsGlobalVariable.PlatformName
- if FdName == "" and GlobalData.gActivePlatform:
- FdName = GlobalData.gActivePlatform.PlatformName
- self.Profile.FdNameNotSet = True
- else:
- raise Warning.Expected("FdName in [FD.] section", self.FileName, self.CurrentLineNumber)
- self.CurrentFdName = FdName.upper()
-
- if self.CurrentFdName in self.Profile.FdDict:
- raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken(TAB_SECTION_END):
- raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)
-
- FdObj = FD()
- FdObj.FdUiName = self.CurrentFdName
- self.Profile.FdDict[self.CurrentFdName] = FdObj
-
- if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet:
- raise Warning.Expected("all FDs have their name", self.FileName, self.CurrentLineNumber)
-
- Status = self._GetCreateFile(FdObj)
- if not Status:
- raise Warning("FD name error", self.FileName, self.CurrentLineNumber)
-
- while self._GetTokenStatements(FdObj):
- pass
- for Attr in ("BaseAddress", "Size", "ErasePolarity"):
- if getattr(FdObj, Attr) is None:
- self._GetNextToken()
- raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber)
-
- if not FdObj.BlockSizeList:
- FdObj.BlockSizeList.append((1, FdObj.Size, None))
-
- self._GetDefineStatements(FdObj)
-
- self._GetSetStatements(FdObj)
-
- if not self._GetRegionLayout(FdObj):
- raise Warning.Expected("region layout", self.FileName, self.CurrentLineNumber)
-
- while self._GetRegionLayout(FdObj):
- pass
- return True
-
- ## _GetUiName() method
- #
- # Return the UI name of a section
- #
- # @param self The object pointer
- # @retval FdName UI name
- #
- def _GetUiName(self):
- Name = ""
- if self._GetNextWord():
- Name = self._Token
-
- return Name
-
- ## _GetCreateFile() method
- #
- # Return the output file name of object
- #
- # @param self The object pointer
- # @param Obj object whose data will be stored in file
- # @retval FdName UI name
- #
- def _GetCreateFile(self, Obj):
- if self._IsKeyword("CREATE_FILE"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("file name", self.FileName, self.CurrentLineNumber)
-
- FileName = self._Token
- Obj.CreateFileName = FileName
-
- return True
-
- def SetPcdLocalation(self,pcdpair):
- self.Profile.PcdLocalDict[pcdpair] = (self.Profile.FileName,self.CurrentLineNumber)
-
- ## _GetTokenStatements() method
- #
- # Get token statements
- #
- # @param self The object pointer
- # @param Obj for whom token statement is got
- #
- def _GetTokenStatements(self, Obj):
- if self._IsKeyword("BaseAddress"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextHexNumber():
- raise Warning.Expected("Hex base address", self.FileName, self.CurrentLineNumber)
-
- Obj.BaseAddress = self._Token
-
- if self._IsToken(TAB_VALUE_SPLIT):
- pcdPair = self._GetNextPcdSettings()
- Obj.BaseAddressPcd = pcdPair
- self.Profile.PcdDict[pcdPair] = Obj.BaseAddress
- self.SetPcdLocalation(pcdPair)
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
- return True
-
- if self._IsKeyword("Size"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextHexNumber():
- raise Warning.Expected("Hex size", self.FileName, self.CurrentLineNumber)
-
- Size = self._Token
- if self._IsToken(TAB_VALUE_SPLIT):
- pcdPair = self._GetNextPcdSettings()
- Obj.SizePcd = pcdPair
- self.Profile.PcdDict[pcdPair] = Size
- self.SetPcdLocalation(pcdPair)
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
- Obj.Size = int(Size, 0)
- return True
-
- if self._IsKeyword("ErasePolarity"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("Erase Polarity", self.FileName, self.CurrentLineNumber)
-
- if not self._Token in {"1", "0"}:
- raise Warning.Expected("1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)
-
- Obj.ErasePolarity = self._Token
- return True
-
- return self._GetBlockStatements(Obj)
-
- ## _GetAddressStatements() method
- #
- # Get address statements
- #
- # @param self The object pointer
- # @param Obj for whom address statement is got
- # @retval True Successfully find
- # @retval False Not able to find
- #
- def _GetAddressStatements(self, Obj):
- if self._IsKeyword("BsBaseAddress"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextDecimalNumber() and not self._GetNextHexNumber():
- raise Warning.Expected("address", self.FileName, self.CurrentLineNumber)
-
- BsAddress = int(self._Token, 0)
- Obj.BsBaseAddress = BsAddress
-
- if self._IsKeyword("RtBaseAddress"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextDecimalNumber() and not self._GetNextHexNumber():
- raise Warning.Expected("address", self.FileName, self.CurrentLineNumber)
-
- RtAddress = int(self._Token, 0)
- Obj.RtBaseAddress = RtAddress
-
- ## _GetBlockStatements() method
- #
- # Get block statements
- #
- # @param self The object pointer
- # @param Obj for whom block statement is got
- #
- def _GetBlockStatements(self, Obj):
- IsBlock = False
- while self._GetBlockStatement(Obj):
- IsBlock = True
-
- Item = Obj.BlockSizeList[-1]
- if Item[0] is None or Item[1] is None:
- raise Warning.Expected("block statement", self.FileName, self.CurrentLineNumber)
- return IsBlock
-
- ## _GetBlockStatement() method
- #
- # Get block statement
- #
- # @param self The object pointer
- # @param Obj for whom block statement is got
- # @retval True Successfully find
- # @retval False Not able to find
- #
- def _GetBlockStatement(self, Obj):
- if not self._IsKeyword("BlockSize"):
- return False
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextHexNumber() and not self._GetNextDecimalNumber():
- raise Warning.Expected("Hex or Integer block size", self.FileName, self.CurrentLineNumber)
-
- BlockSize = self._Token
- BlockSizePcd = None
- if self._IsToken(TAB_VALUE_SPLIT):
- PcdPair = self._GetNextPcdSettings()
- BlockSizePcd = PcdPair
- self.Profile.PcdDict[PcdPair] = BlockSize
- self.SetPcdLocalation(PcdPair)
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
- BlockSize = int(BlockSize, 0)
-
- BlockNumber = None
- if self._IsKeyword("NumBlocks"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextDecimalNumber() and not self._GetNextHexNumber():
- raise Warning.Expected("block numbers", self.FileName, self.CurrentLineNumber)
-
- BlockNumber = int(self._Token, 0)
-
- Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))
- return True
-
- ## _GetDefineStatements() method
- #
- # Get define statements
- #
- # @param self The object pointer
- # @param Obj for whom define statement is got
- # @retval True Successfully find
- # @retval False Not able to find
- #
- def _GetDefineStatements(self, Obj):
- while self._GetDefineStatement(Obj):
- pass
-
- ## _GetDefineStatement() method
- #
- # Get define statement
- #
- # @param self The object pointer
- # @param Obj for whom define statement is got
- # @retval True Successfully find
- # @retval False Not able to find
- #
- def _GetDefineStatement(self, Obj):
- if self._IsKeyword(TAB_DEFINE):
- self._GetNextToken()
- Macro = self._Token
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)
-
- Value = self._Token
- Macro = '$(' + Macro + ')'
- Obj.DefineVarDict[Macro] = Value
- return True
-
- return False
-
- ## _GetSetStatements() method
- #
- # Get set statements
- #
- # @param self The object pointer
- # @param Obj for whom set statement is got
- # @retval True Successfully find
- # @retval False Not able to find
- #
- def _GetSetStatements(self, Obj):
- while self._GetSetStatement(Obj):
- pass
-
- ## _GetSetStatement() method
- #
- # Get set statement
- #
- # @param self The object pointer
- # @param Obj for whom set statement is got
- # @retval True Successfully find
- # @retval False Not able to find
- #
- def _GetSetStatement(self, Obj):
- if self._IsKeyword("SET"):
- PcdPair = self._GetNextPcdSettings()
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- Value = self._GetExpression()
- Value = self._EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)
-
- if Obj:
- Obj.SetVarDict[PcdPair] = Value
- self.Profile.PcdDict[PcdPair] = Value
- self.SetPcdLocalation(PcdPair)
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
- return True
-
- return False
-
- ## _CalcRegionExpr(self)
- #
- # Calculate expression for offset or size of a region
- #
- # @return: None if invalid expression
- # Calculated number if successfully
- #
- def _CalcRegionExpr(self):
- StartPos = self.GetFileBufferPos()
- Expr = ''
- PairCount = 0
- while not self._EndOfFile():
- CurCh = self._CurrentChar()
- if CurCh == '(':
- PairCount += 1
- elif CurCh == ')':
- PairCount -= 1
-
- if CurCh in '|\r\n' and PairCount == 0:
- break
- Expr += CurCh
- self._GetOneChar()
- try:
- return int(
- ValueExpression(Expr,
- self._CollectMacroPcd()
- )(True), 0)
- except Exception:
- self.SetFileBufferPos(StartPos)
- return None
-
- ## _GetRegionLayout() method
- #
- # Get region layout for FD
- #
- # @param self The object pointer
- # @param theFd for whom region is got
- # @retval True Successfully find
- # @retval False Not able to find
- #
- def _GetRegionLayout(self, theFd):
- Offset = self._CalcRegionExpr()
- if Offset is None:
- return False
-
- RegionObj = Region()
- RegionObj.Offset = Offset
- theFd.RegionList.append(RegionObj)
-
- if not self._IsToken(TAB_VALUE_SPLIT):
- raise Warning.Expected("'|'", self.FileName, self.CurrentLineNumber)
-
- Size = self._CalcRegionExpr()
- if Size is None:
- raise Warning.Expected("Region Size", self.FileName, self.CurrentLineNumber)
- RegionObj.Size = Size
-
- if not self._GetNextWord():
- return True
-
- if not self._Token in {"SET", BINARY_FILE_TYPE_FV, "FILE", "DATA", "CAPSULE", "INF"}:
- #
- # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
- # Or it might be next region's offset described by an expression which starts with a PCD.
- # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
- #
- self._UndoToken()
- IsRegionPcd = (RegionSizeGuidPattern.match(self._CurrentLine()[self.CurrentOffsetWithinLine:]) or
- RegionOffsetPcdPattern.match(self._CurrentLine()[self.CurrentOffsetWithinLine:]))
- if IsRegionPcd:
- RegionObj.PcdOffset = self._GetNextPcdSettings()
- self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + int(theFd.BaseAddress, 0))
- self.SetPcdLocalation(RegionObj.PcdOffset)
- self._PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple
- if self._IsToken(TAB_VALUE_SPLIT):
- RegionObj.PcdSize = self._GetNextPcdSettings()
- self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size
- self.SetPcdLocalation(RegionObj.PcdSize)
- self._PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple
-
- if not self._GetNextWord():
- return True
-
- if self._Token == "SET":
- self._UndoToken()
- self._GetSetStatements(RegionObj)
- if not self._GetNextWord():
- return True
-
- elif self._Token == BINARY_FILE_TYPE_FV:
- self._UndoToken()
- self._GetRegionFvType(RegionObj)
-
- elif self._Token == "CAPSULE":
- self._UndoToken()
- self._GetRegionCapType(RegionObj)
-
- elif self._Token == "FILE":
- self._UndoToken()
- self._GetRegionFileType(RegionObj)
-
- elif self._Token == "INF":
- self._UndoToken()
- RegionObj.RegionType = "INF"
- while self._IsKeyword("INF"):
- self._UndoToken()
- ffsInf = self._ParseInfStatement()
- if not ffsInf:
- break
- RegionObj.RegionDataList.append(ffsInf)
-
- elif self._Token == "DATA":
- self._UndoToken()
- self._GetRegionDataType(RegionObj)
- else:
- self._UndoToken()
- if self._GetRegionLayout(theFd):
- return True
- raise Warning("A valid region type was not found. "
- "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
- self.FileName, self.CurrentLineNumber)
-
- return True
-
- ## _GetRegionFvType() method
- #
- # Get region fv data for region
- #
- # @param self The object pointer
- # @param RegionObj for whom region data is got
- #
- def _GetRegionFvType(self, RegionObj):
- if not self._IsKeyword(BINARY_FILE_TYPE_FV):
- raise Warning.Expected("'FV'", self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)
-
- RegionObj.RegionType = BINARY_FILE_TYPE_FV
- RegionObj.RegionDataList.append((self._Token).upper())
-
- while self._IsKeyword(BINARY_FILE_TYPE_FV):
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)
-
- RegionObj.RegionDataList.append((self._Token).upper())
-
- ## _GetRegionCapType() method
- #
- # Get region capsule data for region
- #
- # @param self The object pointer
- # @param RegionObj for whom region data is got
- #
- def _GetRegionCapType(self, RegionObj):
- if not self._IsKeyword("CAPSULE"):
- raise Warning.Expected("'CAPSULE'", self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("CAPSULE name", self.FileName, self.CurrentLineNumber)
-
- RegionObj.RegionType = "CAPSULE"
- RegionObj.RegionDataList.append(self._Token)
-
- while self._IsKeyword("CAPSULE"):
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("CAPSULE name", self.FileName, self.CurrentLineNumber)
-
- RegionObj.RegionDataList.append(self._Token)
-
- ## _GetRegionFileType() method
- #
- # Get region file data for region
- #
- # @param self The object pointer
- # @param RegionObj for whom region data is got
- #
- def _GetRegionFileType(self, RegionObj):
- if not self._IsKeyword("FILE"):
- raise Warning.Expected("'FILE'", self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)
-
- RegionObj.RegionType = "FILE"
- RegionObj.RegionDataList.append(self._Token)
-
- while self._IsKeyword("FILE"):
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("FILE name", self.FileName, self.CurrentLineNumber)
-
- RegionObj.RegionDataList.append(self._Token)
-
- ## _GetRegionDataType() method
- #
- # Get region array data for region
- #
- # @param self The object pointer
- # @param RegionObj for whom region data is got
- #
- def _GetRegionDataType(self, RegionObj):
- if not self._IsKeyword("DATA"):
- raise Warning.Expected("Region Data type", self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken("{"):
- raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextHexNumber():
- raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber)
-
- if len(self._Token) > 18:
- raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
-
- # convert hex string value to byte hex string array
- AllString = self._Token
- AllStrLen = len (AllString)
- DataString = ""
- while AllStrLen > 4:
- DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + TAB_COMMA_SPLIT
- AllStrLen = AllStrLen - 2
- DataString = DataString + AllString[:AllStrLen] + TAB_COMMA_SPLIT
-
- # byte value array
- if len (self._Token) <= 4:
- while self._IsToken(TAB_COMMA_SPLIT):
- if not self._GetNextHexNumber():
- raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
- if len(self._Token) > 4:
- raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
- DataString += self._Token
- DataString += TAB_COMMA_SPLIT
-
- if not self._IsToken(T_CHAR_BRACE_R):
- raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
-
- DataString = DataString.rstrip(TAB_COMMA_SPLIT)
- RegionObj.RegionType = "DATA"
- RegionObj.RegionDataList.append(DataString)
-
- while self._IsKeyword("DATA"):
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken("{"):
- raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextHexNumber():
- raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber)
-
- if len(self._Token) > 18:
- raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
-
- # convert hex string value to byte hex string array
- AllString = self._Token
- AllStrLen = len (AllString)
- DataString = ""
- while AllStrLen > 4:
- DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + TAB_COMMA_SPLIT
- AllStrLen = AllStrLen - 2
- DataString = DataString + AllString[:AllStrLen] + TAB_COMMA_SPLIT
-
- # byte value array
- if len (self._Token) <= 4:
- while self._IsToken(TAB_COMMA_SPLIT):
- if not self._GetNextHexNumber():
- raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
- if len(self._Token) > 4:
- raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
- DataString += self._Token
- DataString += TAB_COMMA_SPLIT
-
- if not self._IsToken(T_CHAR_BRACE_R):
- raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
-
- DataString = DataString.rstrip(TAB_COMMA_SPLIT)
- RegionObj.RegionDataList.append(DataString)
-
- ## _GetFv() method
- #
- # Get FV section contents and store its data into FV dictionary of self.Profile
- #
- # @param self The object pointer
- # @retval True Successfully find a FV
- # @retval False Not able to find a FV
- #
- def _GetFv(self):
- if not self._GetNextToken():
- return False
-
- S = self._Token.upper()
- if S.startswith(TAB_SECTION_START) and not S.startswith("[FV."):
- self.SectionParser(S)
- self._UndoToken()
- return False
-
- self._UndoToken()
- if not self._IsToken("[FV.", True):
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
- # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
- raise Warning("Unknown Keyword '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
-
- FvName = self._GetUiName()
- self.CurrentFvName = FvName.upper()
-
- if not self._IsToken(TAB_SECTION_END):
- raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)
-
- FvObj = FV(Name=self.CurrentFvName)
- self.Profile.FvDict[self.CurrentFvName] = FvObj
-
- Status = self._GetCreateFile(FvObj)
- if not Status:
- raise Warning("FV name error", self.FileName, self.CurrentLineNumber)
-
- self._GetDefineStatements(FvObj)
-
- self._GetAddressStatements(FvObj)
-
- while True:
- self._GetSetStatements(FvObj)
-
- if not (self._GetBlockStatement(FvObj) or self._GetFvBaseAddress(FvObj) or
- self._GetFvForceRebase(FvObj) or self._GetFvAlignment(FvObj) or
- self._GetFvAttributes(FvObj) or self._GetFvNameGuid(FvObj) or
- self._GetFvExtEntryStatement(FvObj) or self._GetFvNameString(FvObj)):
- break
-
- if FvObj.FvNameString == 'TRUE' and not FvObj.FvNameGuid:
- raise Warning("FvNameString found but FvNameGuid was not found", self.FileName, self.CurrentLineNumber)
-
- self._GetAprioriSection(FvObj)
- self._GetAprioriSection(FvObj)
-
- while True:
- isInf = self._GetInfStatement(FvObj)
- isFile = self._GetFileStatement(FvObj)
- if not isInf and not isFile:
- break
-
- return True
-
- ## _GetFvAlignment() method
- #
- # Get alignment for FV
- #
- # @param self The object pointer
- # @param Obj for whom alignment is got
- # @retval True Successfully find a alignment statement
- # @retval False Not able to find a alignment statement
- #
- def _GetFvAlignment(self, Obj):
- if not self._IsKeyword("FvAlignment"):
- return False
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("alignment value", self.FileName, self.CurrentLineNumber)
-
- if self._Token.upper() not in {"1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
- "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
- "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
- "1G", "2G"}:
- raise Warning("Unknown alignment value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
- Obj.FvAlignment = self._Token
- return True
-
- ## _GetFvBaseAddress() method
- #
- # Get BaseAddress for FV
- #
- # @param self The object pointer
- # @param Obj for whom FvBaseAddress is got
- # @retval True Successfully find a FvBaseAddress statement
- # @retval False Not able to find a FvBaseAddress statement
- #
- def _GetFvBaseAddress(self, Obj):
- if not self._IsKeyword("FvBaseAddress"):
- return False
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("FV base address value", self.FileName, self.CurrentLineNumber)
-
- if not BaseAddrValuePattern.match(self._Token.upper()):
- raise Warning("Unknown FV base address value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
- Obj.FvBaseAddress = self._Token
- return True
-
- ## _GetFvForceRebase() method
- #
- # Get FvForceRebase for FV
- #
- # @param self The object pointer
- # @param Obj for whom FvForceRebase is got
- # @retval True Successfully find a FvForceRebase statement
- # @retval False Not able to find a FvForceRebase statement
- #
- def _GetFvForceRebase(self, Obj):
- if not self._IsKeyword("FvForceRebase"):
- return False
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("FvForceRebase value", self.FileName, self.CurrentLineNumber)
-
- if self._Token.upper() not in {"TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"}:
- raise Warning("Unknown FvForceRebase value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
-
- if self._Token.upper() in {"TRUE", "1", "0X1", "0X01"}:
- Obj.FvForceRebase = True
- elif self._Token.upper() in {"FALSE", "0", "0X0", "0X00"}:
- Obj.FvForceRebase = False
- else:
- Obj.FvForceRebase = None
-
- return True
-
-
- ## _GetFvAttributes() method
- #
- # Get attributes for FV
- #
- # @param self The object pointer
- # @param Obj for whom attribute is got
- # @retval None
- #
- def _GetFvAttributes(self, FvObj):
- IsWordToken = False
- while self._GetNextWord():
- IsWordToken = True
- name = self._Token
- if name not in {"ERASE_POLARITY", "MEMORY_MAPPED", \
- "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
- "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
- "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
- "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
- "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"}:
- self._UndoToken()
- return False
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken() or self._Token.upper() not in {"TRUE", "FALSE", "1", "0"}:
- raise Warning.Expected("TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
-
- FvObj.FvAttributeDict[name] = self._Token
-
- return IsWordToken
-
- ## _GetFvNameGuid() method
- #
- # Get FV GUID for FV
- #
- # @param self The object pointer
- # @param Obj for whom GUID is got
- # @retval None
- #
- def _GetFvNameGuid(self, FvObj):
- if not self._IsKeyword("FvNameGuid"):
- return False
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextGuid():
- raise Warning.Expected("GUID value", self.FileName, self.CurrentLineNumber)
- if self._Token in GlobalData.gGuidDict:
- self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper()
-
- FvObj.FvNameGuid = self._Token
-
- return True
-
- def _GetFvNameString(self, FvObj):
- if not self._IsKeyword("FvNameString"):
- return False
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken() or self._Token.upper() not in {'TRUE', 'FALSE'}:
- raise Warning.Expected("TRUE or FALSE for FvNameString", self.FileName, self.CurrentLineNumber)
-
- FvObj.FvNameString = self._Token
-
- return True
-
- def _GetFvExtEntryStatement(self, FvObj):
- if not (self._IsKeyword("FV_EXT_ENTRY") or self._IsKeyword("FV_EXT_ENTRY_TYPE")):
- return False
-
- if not self._IsKeyword ("TYPE"):
- raise Warning.Expected("'TYPE'", self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextHexNumber() and not self._GetNextDecimalNumber():
- raise Warning.Expected("Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber)
-
- FvObj.FvExtEntryTypeValue.append(self._Token)
-
- if not self._IsToken("{"):
- raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
-
- if not self._IsKeyword("FILE") and not self._IsKeyword("DATA"):
- raise Warning.Expected("'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber)
-
- FvObj.FvExtEntryType.append(self._Token)
-
- if self._Token == 'DATA':
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken("{"):
- raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextHexNumber():
- raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber)
-
- if len(self._Token) > 4:
- raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
-
- DataString = self._Token
- DataString += TAB_COMMA_SPLIT
-
- while self._IsToken(TAB_COMMA_SPLIT):
- if not self._GetNextHexNumber():
- raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
- if len(self._Token) > 4:
- raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
- DataString += self._Token
- DataString += TAB_COMMA_SPLIT
-
- if not self._IsToken(T_CHAR_BRACE_R):
- raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken(T_CHAR_BRACE_R):
- raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
-
- DataString = DataString.rstrip(TAB_COMMA_SPLIT)
- FvObj.FvExtEntryData.append(DataString)
-
- if self._Token == 'FILE':
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber)
-
- FvObj.FvExtEntryData.append(self._Token)
-
- if not self._IsToken(T_CHAR_BRACE_R):
- raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
-
- return True
-
- ## _GetAprioriSection() method
- #
- # Get token statements
- #
- # @param self The object pointer
- # @param FvObj for whom apriori is got
- # @retval True Successfully find apriori statement
- # @retval False Not able to find apriori statement
- #
- def _GetAprioriSection(self, FvObj):
- if not self._IsKeyword("APRIORI"):
- return False
-
- if not self._IsKeyword("PEI") and not self._IsKeyword("DXE"):
- raise Warning.Expected("Apriori file type", self.FileName, self.CurrentLineNumber)
- AprType = self._Token
-
- if not self._IsToken("{"):
- raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
-
- AprSectionObj = AprioriSection()
- AprSectionObj.AprioriType = AprType
-
- self._GetDefineStatements(AprSectionObj)
-
- while True:
- IsInf = self._GetInfStatement(AprSectionObj)
- IsFile = self._GetFileStatement(AprSectionObj)
- if not IsInf and not IsFile:
- break
-
- if not self._IsToken(T_CHAR_BRACE_R):
- raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
-
- FvObj.AprioriSectionList.append(AprSectionObj)
- return True
-
- def _ParseInfStatement(self):
- if not self._IsKeyword("INF"):
- return None
-
- ffsInf = FfsInfStatement()
- self._GetInfOptions(ffsInf)
-
- if not self._GetNextToken():
- raise Warning.Expected("INF file path", self.FileName, self.CurrentLineNumber)
- ffsInf.InfFileName = self._Token
- if not ffsInf.InfFileName.endswith('.inf'):
- raise Warning.Expected(".inf file path", self.FileName, self.CurrentLineNumber)
-
- ffsInf.CurrentLineNum = self.CurrentLineNumber
- ffsInf.CurrentLineContent = self._CurrentLine()
-
- #Replace $(SAPCE) with real space
- ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')
-
- if ffsInf.InfFileName.replace(TAB_WORKSPACE, '').find('$') == -1:
- #do case sensitive check for file path
- ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
- if ErrorCode != 0:
- EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
-
- NewFileName = ffsInf.InfFileName
- if ffsInf.OverrideGuid:
- NewFileName = ProcessDuplicatedInf(PathClass(ffsInf.InfFileName,GenFdsGlobalVariable.WorkSpaceDir), ffsInf.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir).Path
-
- if not NewFileName in self.Profile.InfList:
- self.Profile.InfList.append(NewFileName)
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- self.Profile.InfFileLineList.append(FileLineTuple)
- if ffsInf.UseArch:
- if ffsInf.UseArch not in self.Profile.InfDict:
- self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]
- else:
- self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)
- else:
- self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)
-
- if self._IsToken(TAB_VALUE_SPLIT):
- if self._IsKeyword('RELOCS_STRIPPED'):
- ffsInf.KeepReloc = False
- elif self._IsKeyword('RELOCS_RETAINED'):
- ffsInf.KeepReloc = True
- else:
- raise Warning("Unknown reloc strip flag '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
- return ffsInf
-
- ## _GetInfStatement() method
- #
- # Get INF statements
- #
- # @param self The object pointer
- # @param Obj for whom inf statement is got
- # @retval True Successfully find inf statement
- # @retval False Not able to find inf statement
- #
- def _GetInfStatement(self, Obj, ForCapsule=False):
- ffsInf = self._ParseInfStatement()
- if not ffsInf:
- return False
-
- if ForCapsule:
- myCapsuleFfs = CapsuleFfs()
- myCapsuleFfs.Ffs = ffsInf
- Obj.CapsuleDataList.append(myCapsuleFfs)
- else:
- Obj.FfsList.append(ffsInf)
- return True
-
- ## _GetInfOptions() method
- #
- # Get options for INF
- #
- # @param self The object pointer
- # @param FfsInfObj for whom option is got
- #
- def _GetInfOptions(self, FfsInfObj):
- if self._IsKeyword("FILE_GUID"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextGuid():
- raise Warning.Expected("GUID value", self.FileName, self.CurrentLineNumber)
- if self._Token in GlobalData.gGuidDict:
- self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper()
- FfsInfObj.OverrideGuid = self._Token
-
- if self._IsKeyword("RuleOverride"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextToken():
- raise Warning.Expected("Rule name", self.FileName, self.CurrentLineNumber)
- FfsInfObj.Rule = self._Token
-
- if self._IsKeyword("VERSION"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextToken():
- raise Warning.Expected("Version", self.FileName, self.CurrentLineNumber)
-
- if self._GetStringData():
- FfsInfObj.Version = self._Token
-
- if self._IsKeyword(BINARY_FILE_TYPE_UI):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextToken():
- raise Warning.Expected("UI name", self.FileName, self.CurrentLineNumber)
-
- if self._GetStringData():
- FfsInfObj.Ui = self._Token
-
- if self._IsKeyword("USE"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextToken():
- raise Warning.Expected("ARCH name", self.FileName, self.CurrentLineNumber)
- FfsInfObj.UseArch = self._Token
-
-
- if self._GetNextToken():
- p = compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
- if p.match(self._Token) and p.match(self._Token).span()[1] == len(self._Token):
- FfsInfObj.KeyStringList.append(self._Token)
- if not self._IsToken(TAB_COMMA_SPLIT):
- return
- else:
- self._UndoToken()
- return
-
- while self._GetNextToken():
- if not p.match(self._Token):
- raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
- FfsInfObj.KeyStringList.append(self._Token)
-
- if not self._IsToken(TAB_COMMA_SPLIT):
- break
-
- ## _GetFileStatement() method
- #
- # Get FILE statements
- #
- # @param self The object pointer
- # @param Obj for whom FILE statement is got
- # @retval True Successfully find FILE statement
- # @retval False Not able to find FILE statement
- #
- def _GetFileStatement(self, Obj, ForCapsule = False):
- if not self._IsKeyword("FILE"):
- return False
-
- if not self._GetNextWord():
- raise Warning.Expected("FFS type", self.FileName, self.CurrentLineNumber)
-
- if ForCapsule and self._Token == 'DATA':
- self._UndoToken()
- self._UndoToken()
- return False
-
- FfsFileObj = FileStatement()
- FfsFileObj.FvFileType = self._Token
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextGuid():
- if not self._GetNextWord():
- raise Warning.Expected("File GUID", self.FileName, self.CurrentLineNumber)
- if self._Token == 'PCD':
- if not self._IsToken("("):
- raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)
- PcdPair = self._GetNextPcdSettings()
- if not self._IsToken(")"):
- raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)
- self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'
-
- if self._Token in GlobalData.gGuidDict:
- self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper()
- FfsFileObj.NameGuid = self._Token
-
- self._GetFilePart(FfsFileObj)
-
- if ForCapsule:
- capsuleFfs = CapsuleFfs()
- capsuleFfs.Ffs = FfsFileObj
- Obj.CapsuleDataList.append(capsuleFfs)
- else:
- Obj.FfsList.append(FfsFileObj)
-
- return True
-
- ## _FileCouldHaveRelocFlag() method
- #
- # Check whether reloc strip flag can be set for a file type.
- #
- # @param FileType The file type to check with
- # @retval True This type could have relocation strip flag
- # @retval False No way to have it
- #
- @staticmethod
- def _FileCouldHaveRelocFlag (FileType):
- if FileType in {SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE, 'PEI_DXE_COMBO'}:
- return True
- else:
- return False
-
- ## _SectionCouldHaveRelocFlag() method
- #
- # Check whether reloc strip flag can be set for a section type.
- #
- # @param SectionType The section type to check with
- # @retval True This type could have relocation strip flag
- # @retval False No way to have it
- #
- @staticmethod
- def _SectionCouldHaveRelocFlag (SectionType):
- if SectionType in {BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32}:
- return True
- else:
- return False
-
- ## _GetFilePart() method
- #
- # Get components for FILE statement
- #
- # @param self The object pointer
- # @param FfsFileObj for whom component is got
- #
- def _GetFilePart(self, FfsFileObj):
- self._GetFileOpts(FfsFileObj)
-
- if not self._IsToken("{"):
- if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):
- if self._FileCouldHaveRelocFlag(FfsFileObj.FvFileType):
- if self._Token == 'RELOCS_STRIPPED':
- FfsFileObj.KeepReloc = False
- else:
- FfsFileObj.KeepReloc = True
- else:
- raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken("{"):
- raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("File name or section data", self.FileName, self.CurrentLineNumber)
-
- if self._Token == BINARY_FILE_TYPE_FV:
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextToken():
- raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)
- FfsFileObj.FvName = self._Token
-
- elif self._Token == "FD":
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextToken():
- raise Warning.Expected("FD name", self.FileName, self.CurrentLineNumber)
- FfsFileObj.FdName = self._Token
-
- elif self._Token in {TAB_DEFINE, "APRIORI", "SECTION"}:
- self._UndoToken()
- self._GetSectionData(FfsFileObj)
-
- elif hasattr(FfsFileObj, 'FvFileType') and FfsFileObj.FvFileType == 'RAW':
- self._UndoToken()
- self._GetRAWData(FfsFileObj)
-
- else:
- FfsFileObj.CurrentLineNum = self.CurrentLineNumber
- FfsFileObj.CurrentLineContent = self._CurrentLine()
- FfsFileObj.FileName = self._Token.replace('$(SPACE)', ' ')
- self._VerifyFile(FfsFileObj.FileName)
-
- if not self._IsToken(T_CHAR_BRACE_R):
- raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
-
- ## _GetRAWData() method
- #
- # Get RAW data for FILE statement
- #
- # @param self The object pointer
- # @param FfsFileObj for whom section is got
- #
- def _GetRAWData(self, FfsFileObj):
- FfsFileObj.FileName = []
- FfsFileObj.SubAlignment = []
- while True:
- AlignValue = None
- if self._GetAlignment():
- if self._Token not in ALIGNMENTS:
- raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
- #For FFS, Auto is default option same to ""
- if not self._Token == "Auto":
- AlignValue = self._Token
- if not self._GetNextToken():
- raise Warning.Expected("Filename value", self.FileName, self.CurrentLineNumber)
-
- FileName = self._Token.replace('$(SPACE)', ' ')
- if FileName == T_CHAR_BRACE_R:
- self._UndoToken()
- raise Warning.Expected("Filename value", self.FileName, self.CurrentLineNumber)
-
- self._VerifyFile(FileName)
- File = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir)
- FfsFileObj.FileName.append(File.Path)
- FfsFileObj.SubAlignment.append(AlignValue)
-
- if self._IsToken(T_CHAR_BRACE_R):
- self._UndoToken()
- break
-
- if len(FfsFileObj.SubAlignment) == 1:
- FfsFileObj.SubAlignment = FfsFileObj.SubAlignment[0]
- if len(FfsFileObj.FileName) == 1:
- FfsFileObj.FileName = FfsFileObj.FileName[0]
-
- ## _GetFileOpts() method
- #
- # Get options for FILE statement
- #
- # @param self The object pointer
- # @param FfsFileObj for whom options is got
- #
- def _GetFileOpts(self, FfsFileObj):
- if self._GetNextToken():
- if TokenFindPattern.match(self._Token):
- FfsFileObj.KeyStringList.append(self._Token)
- if self._IsToken(TAB_COMMA_SPLIT):
- while self._GetNextToken():
- if not TokenFindPattern.match(self._Token):
- raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
- FfsFileObj.KeyStringList.append(self._Token)
-
- if not self._IsToken(TAB_COMMA_SPLIT):
- break
-
- else:
- self._UndoToken()
-
- if self._IsKeyword("FIXED", True):
- FfsFileObj.Fixed = True
-
- if self._IsKeyword("CHECKSUM", True):
- FfsFileObj.CheckSum = True
-
- if self._GetAlignment():
- if self._Token not in ALIGNMENTS:
- raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
- #For FFS, Auto is default option same to ""
- if not self._Token == "Auto":
- FfsFileObj.Alignment = self._Token
-
- ## _GetAlignment() method
- #
- # Return the alignment value
- #
- # @param self The object pointer
- # @retval True Successfully find alignment
- # @retval False Not able to find alignment
- #
- def _GetAlignment(self):
- if self._IsKeyword("Align", True):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("alignment value", self.FileName, self.CurrentLineNumber)
- return True
-
- return False
-
- ## _GetSectionData() method
- #
- # Get section data for FILE statement
- #
- # @param self The object pointer
- # @param FfsFileObj for whom section is got
- #
- def _GetSectionData(self, FfsFileObj):
- self._GetDefineStatements(FfsFileObj)
-
- while True:
- IsLeafSection = self._GetLeafSection(FfsFileObj)
- IsEncapSection = self._GetEncapsulationSec(FfsFileObj)
- if not IsLeafSection and not IsEncapSection:
- break
-
- ## _GetLeafSection() method
- #
- # Get leaf section for Obj
- #
- # @param self The object pointer
- # @param Obj for whom leaf section is got
- # @retval True Successfully find section statement
- # @retval False Not able to find section statement
- #
- def _GetLeafSection(self, Obj):
- OldPos = self.GetFileBufferPos()
-
- if not self._IsKeyword("SECTION"):
- if len(Obj.SectionList) == 0:
- raise Warning.Expected("SECTION", self.FileName, self.CurrentLineNumber)
- else:
- return False
-
- AlignValue = None
- if self._GetAlignment():
- if self._Token not in ALIGNMENTS:
- raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
- AlignValue = self._Token
-
- BuildNum = None
- if self._IsKeyword("BUILD_NUM"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("Build number value", self.FileName, self.CurrentLineNumber)
-
- BuildNum = self._Token
-
- if self._IsKeyword("VERSION"):
- if AlignValue == 'Auto':
- raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextToken():
- raise Warning.Expected("version", self.FileName, self.CurrentLineNumber)
- VerSectionObj = VerSection()
- VerSectionObj.Alignment = AlignValue
- VerSectionObj.BuildNum = BuildNum
- if self._GetStringData():
- VerSectionObj.StringData = self._Token
- else:
- VerSectionObj.FileName = self._Token
- Obj.SectionList.append(VerSectionObj)
-
- elif self._IsKeyword(BINARY_FILE_TYPE_UI):
- if AlignValue == 'Auto':
- raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextToken():
- raise Warning.Expected("UI", self.FileName, self.CurrentLineNumber)
- UiSectionObj = UiSection()
- UiSectionObj.Alignment = AlignValue
- if self._GetStringData():
- UiSectionObj.StringData = self._Token
- else:
- UiSectionObj.FileName = self._Token
- Obj.SectionList.append(UiSectionObj)
-
- elif self._IsKeyword("FV_IMAGE"):
- if AlignValue == 'Auto':
- raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextToken():
- raise Warning.Expected("FV name or FV file path", self.FileName, self.CurrentLineNumber)
-
- FvName = self._Token
- FvObj = None
-
- if self._IsToken("{"):
- FvObj = FV()
- FvObj.UiFvName = FvName.upper()
- self._GetDefineStatements(FvObj)
-
- self._GetBlockStatement(FvObj)
- self._GetSetStatements(FvObj)
- self._GetFvAlignment(FvObj)
- self._GetFvAttributes(FvObj)
-
- while True:
- IsInf = self._GetInfStatement(FvObj)
- IsFile = self._GetFileStatement(FvObj)
- if not IsInf and not IsFile:
- break
-
- if not self._IsToken(T_CHAR_BRACE_R):
- raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
-
- FvImageSectionObj = FvImageSection()
- FvImageSectionObj.Alignment = AlignValue
- if FvObj is not None:
- FvImageSectionObj.Fv = FvObj
- FvImageSectionObj.FvName = None
- else:
- FvImageSectionObj.FvName = FvName.upper()
- FvImageSectionObj.FvFileName = FvName
-
- Obj.SectionList.append(FvImageSectionObj)
-
- elif self._IsKeyword("PEI_DEPEX_EXP") or self._IsKeyword("DXE_DEPEX_EXP") or self._IsKeyword("SMM_DEPEX_EXP"):
- if AlignValue == 'Auto':
- raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
- DepexSectionObj = DepexSection()
- DepexSectionObj.Alignment = AlignValue
- DepexSectionObj.DepexType = self._Token
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._IsToken("{"):
- raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
- if not self._SkipToToken(T_CHAR_BRACE_R):
- raise Warning.Expected("Depex expression ending '}'", self.FileName, self.CurrentLineNumber)
-
- DepexSectionObj.Expression = self._SkippedChars.rstrip(T_CHAR_BRACE_R)
- Obj.SectionList.append(DepexSectionObj)
-
- elif self._IsKeyword("SUBTYPE_GUID"):
- if AlignValue == 'Auto':
- raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
- SubTypeGuidValue = None
- if not self._GetNextGuid():
- raise Warning.Expected("GUID", self.FileName, self.CurrentLineNumber)
- else:
- SubTypeGuidValue = self._Token
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextToken():
- raise Warning.Expected("section file path", self.FileName, self.CurrentLineNumber)
- FileName = self._Token
-
- SubTypeGuidSectionObj = SubTypeGuidSection()
- SubTypeGuidSectionObj.Alignment = AlignValue
- SubTypeGuidSectionObj.SubTypeGuid = SubTypeGuidValue
- SubTypeGuidSectionObj.SectFileName = FileName
- Obj.SectionList.append(SubTypeGuidSectionObj)
-
- else:
- if not self._GetNextWord():
- raise Warning.Expected("section type", self.FileName, self.CurrentLineNumber)
-
- # Encapsulation section appear, UndoToken and return
- if self._Token == "COMPRESS" or self._Token == "GUIDED":
- self.SetFileBufferPos(OldPos)
- return False
-
- if self._Token not in {"COMPAT16", BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\
- BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX}:
- raise Warning("Unknown section type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
- if AlignValue == 'Auto'and (not self._Token == BINARY_FILE_TYPE_PE32) and (not self._Token == BINARY_FILE_TYPE_TE):
- raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
-
- # DataSection
- DataSectionObj = DataSection()
- DataSectionObj.Alignment = AlignValue
- DataSectionObj.SecType = self._Token
-
- if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):
- if self._FileCouldHaveRelocFlag(Obj.FvFileType) and self._SectionCouldHaveRelocFlag(DataSectionObj.SecType):
- if self._Token == 'RELOCS_STRIPPED':
- DataSectionObj.KeepReloc = False
- else:
- DataSectionObj.KeepReloc = True
- else:
- raise Warning("File type %s, section type %s, could not have reloc strip flag%d" % (Obj.FvFileType, DataSectionObj.SecType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
-
- if self._IsToken(TAB_EQUAL_SPLIT):
- if not self._GetNextToken():
- raise Warning.Expected("section file path", self.FileName, self.CurrentLineNumber)
- DataSectionObj.SectFileName = self._Token
- self._VerifyFile(DataSectionObj.SectFileName)
- else:
- if not self._GetCglSection(DataSectionObj):
- return False
-
- Obj.SectionList.append(DataSectionObj)
-
- return True
-
- ## _VerifyFile
- #
- # Check if file exists or not:
- # If current phase if GenFds, the file must exist;
- # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
- # @param FileName: File path to be verified.
- #
- def _VerifyFile(self, FileName):
- if FileName.replace(TAB_WORKSPACE, '').find('$') != -1:
- return
- if not GlobalData.gAutoGenPhase or not self._GetMacroValue(TAB_DSC_DEFINES_OUTPUT_DIRECTORY) in FileName:
- ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
- if ErrorCode != 0:
- EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
-
- ## _GetCglSection() method
- #
- # Get compressed or GUIDed section for Obj
- #
- # @param self The object pointer
- # @param Obj for whom leaf section is got
- # @param AlignValue alignment value for complex section
- # @retval True Successfully find section statement
- # @retval False Not able to find section statement
- #
- def _GetCglSection(self, Obj, AlignValue = None):
-
- if self._IsKeyword("COMPRESS"):
- type = "PI_STD"
- if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"):
- type = self._Token
-
- if not self._IsToken("{"):
- raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
-
- CompressSectionObj = CompressSection()
- CompressSectionObj.Alignment = AlignValue
- CompressSectionObj.CompType = type
- # Recursive sections...
- while True:
- IsLeafSection = self._GetLeafSection(CompressSectionObj)
- IsEncapSection = self._GetEncapsulationSec(CompressSectionObj)
- if not IsLeafSection and not IsEncapSection:
- break
-
-
- if not self._IsToken(T_CHAR_BRACE_R):
- raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
- Obj.SectionList.append(CompressSectionObj)
- return True
-
- elif self._IsKeyword("GUIDED"):
- GuidValue = None
- if self._GetNextGuid():
- if self._Token in GlobalData.gGuidDict:
- self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper()
- GuidValue = self._Token
-
- AttribDict = self._GetGuidAttrib()
- if not self._IsToken("{"):
- raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
- GuidSectionObj = GuidSection()
- GuidSectionObj.Alignment = AlignValue
- GuidSectionObj.NameGuid = GuidValue
- GuidSectionObj.SectionType = "GUIDED"
- GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
- GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
- GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]
- # Recursive sections...
- while True:
- IsLeafSection = self._GetLeafSection(GuidSectionObj)
- IsEncapSection = self._GetEncapsulationSec(GuidSectionObj)
- if not IsLeafSection and not IsEncapSection:
- break
-
- if not self._IsToken(T_CHAR_BRACE_R):
- raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
- Obj.SectionList.append(GuidSectionObj)
-
- return True
-
- return False
-
- ## _GetGuidAttri() method
- #
- # Get attributes for GUID section
- #
- # @param self The object pointer
- # @retval AttribDict Dictionary of key-value pair of section attributes
- #
- def _GetGuidAttrib(self):
- AttribDict = {}
- AttribDict["PROCESSING_REQUIRED"] = "NONE"
- AttribDict["AUTH_STATUS_VALID"] = "NONE"
- AttribDict["EXTRA_HEADER_SIZE"] = -1
- while self._IsKeyword("PROCESSING_REQUIRED") or self._IsKeyword("AUTH_STATUS_VALID") \
- or self._IsKeyword("EXTRA_HEADER_SIZE"):
- AttribKey = self._Token
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber)
- elif AttribKey == "EXTRA_HEADER_SIZE":
- Base = 10
- if self._Token[0:2].upper() == "0X":
- Base = 16
- try:
- AttribDict[AttribKey] = int(self._Token, Base)
- continue
- except ValueError:
- raise Warning.Expected("Number", self.FileName, self.CurrentLineNumber)
- elif self._Token.upper() not in {"TRUE", "FALSE", "1", "0"}:
- raise Warning.Expected("TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
- AttribDict[AttribKey] = self._Token
-
- return AttribDict
-
- ## _GetEncapsulationSec() method
- #
- # Get encapsulation section for FILE
- #
- # @param self The object pointer
- # @param FfsFile for whom section is got
- # @retval True Successfully find section statement
- # @retval False Not able to find section statement
- #
- def _GetEncapsulationSec(self, FfsFileObj):
- OldPos = self.GetFileBufferPos()
- if not self._IsKeyword("SECTION"):
- if len(FfsFileObj.SectionList) == 0:
- raise Warning.Expected("SECTION", self.FileName, self.CurrentLineNumber)
- else:
- return False
-
- AlignValue = None
- if self._GetAlignment():
- if self._Token not in ALIGNMENT_NOAUTO:
- raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
- AlignValue = self._Token
-
- if not self._GetCglSection(FfsFileObj, AlignValue):
- self.SetFileBufferPos(OldPos)
- return False
- else:
- return True
-
- def _GetFmp(self):
- if not self._GetNextToken():
- return False
- S = self._Token.upper()
- if S.startswith(TAB_SECTION_START) and not S.startswith("[FMPPAYLOAD."):
- self.SectionParser(S)
- self._UndoToken()
- return False
-
- self._UndoToken()
- self._SkipToToken("[FMPPAYLOAD.", True)
- FmpUiName = self._GetUiName().upper()
- if FmpUiName in self.Profile.FmpPayloadDict:
- raise Warning("Duplicated FMP UI name found: %s" % FmpUiName, self.FileName, self.CurrentLineNumber)
-
- FmpData = CapsulePayload()
- FmpData.UiName = FmpUiName
-
- if not self._IsToken(TAB_SECTION_END):
- raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber)
- FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']
- while self._Token in FmpKeyList:
- Name = self._Token
- FmpKeyList.remove(Name)
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if Name == 'IMAGE_TYPE_ID':
- if not self._GetNextGuid():
- raise Warning.Expected("GUID value for IMAGE_TYPE_ID.", self.FileName, self.CurrentLineNumber)
- FmpData.ImageTypeId = self._Token
- elif Name == 'CERTIFICATE_GUID':
- if not self._GetNextGuid():
- raise Warning.Expected("GUID value for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)
- FmpData.Certificate_Guid = self._Token
- if UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_RSA2048_SHA256_GUID and UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_PKCS7_GUID:
- raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)
- else:
- if not self._GetNextToken():
- raise Warning.Expected("value of %s" % Name, self.FileName, self.CurrentLineNumber)
- Value = self._Token
- if Name == 'IMAGE_HEADER_INIT_VERSION':
- if FdfParser._Verify(Name, Value, 'UINT8'):
- FmpData.Version = Value
- elif Name == 'IMAGE_INDEX':
- if FdfParser._Verify(Name, Value, 'UINT8'):
- FmpData.ImageIndex = Value
- elif Name == 'HARDWARE_INSTANCE':
- if FdfParser._Verify(Name, Value, 'UINT8'):
- FmpData.HardwareInstance = Value
- elif Name == 'MONOTONIC_COUNT':
- if FdfParser._Verify(Name, Value, 'UINT64'):
- FmpData.MonotonicCount = Value
- if FmpData.MonotonicCount.upper().startswith('0X'):
- FmpData.MonotonicCount = int(FmpData.MonotonicCount, 16)
- else:
- FmpData.MonotonicCount = int(FmpData.MonotonicCount)
- if not self._GetNextToken():
- break
- else:
- self._UndoToken()
-
- if (FmpData.MonotonicCount and not FmpData.Certificate_Guid) or (not FmpData.MonotonicCount and FmpData.Certificate_Guid):
- EdkLogger.error("FdfParser", FORMAT_INVALID, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")
-
- # Only the IMAGE_TYPE_ID is required item
- if FmpKeyList and 'IMAGE_TYPE_ID' in FmpKeyList:
- raise Warning("'IMAGE_TYPE_ID' in FMP payload section.", self.FileName, self.CurrentLineNumber)
- # get the Image file and Vendor code file
- self._GetFMPCapsuleData(FmpData)
- if not FmpData.ImageFile:
- raise Warning("Missing image file in FMP payload section.", self.FileName, self.CurrentLineNumber)
- # check whether more than one Vendor code file
- if len(FmpData.VendorCodeFile) > 1:
- raise Warning("Vendor code file max of 1 per FMP payload section.", self.FileName, self.CurrentLineNumber)
- self.Profile.FmpPayloadDict[FmpUiName] = FmpData
- return True
-
- ## _GetCapsule() method
- #
- # Get capsule section contents and store its data into capsule list of self.Profile
- #
- # @param self The object pointer
- # @retval True Successfully find a capsule
- # @retval False Not able to find a capsule
- #
- def _GetCapsule(self):
- if not self._GetNextToken():
- return False
-
- S = self._Token.upper()
- if S.startswith(TAB_SECTION_START) and not S.startswith("[CAPSULE."):
- self.SectionParser(S)
- self._UndoToken()
- return False
-
- self._UndoToken()
- if not self._IsToken("[CAPSULE.", True):
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
- # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
- raise Warning.Expected("[Capsule.]", self.FileName, self.CurrentLineNumber)
-
- CapsuleObj = Capsule()
-
- CapsuleName = self._GetUiName()
- if not CapsuleName:
- raise Warning.Expected("capsule name", self.FileName, self.CurrentLineNumber)
-
- CapsuleObj.UiCapsuleName = CapsuleName.upper()
-
- if not self._IsToken(TAB_SECTION_END):
- raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)
-
- if self._IsKeyword("CREATE_FILE"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("file name", self.FileName, self.CurrentLineNumber)
-
- CapsuleObj.CreateFile = self._Token
-
- self._GetCapsuleStatements(CapsuleObj)
- self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj
- return True
-
- ## _GetCapsuleStatements() method
- #
- # Get statements for capsule
- #
- # @param self The object pointer
- # @param Obj for whom statements are got
- #
- def _GetCapsuleStatements(self, Obj):
- self._GetCapsuleTokens(Obj)
- self._GetDefineStatements(Obj)
- self._GetSetStatements(Obj)
- self._GetCapsuleData(Obj)
-
- ## _GetCapsuleTokens() method
- #
- # Get token statements for capsule
- #
- # @param self The object pointer
- # @param Obj for whom token statements are got
- #
- def _GetCapsuleTokens(self, Obj):
- if not self._GetNextToken():
- return False
- while self._Token in {"CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"}:
- Name = self._Token.strip()
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextToken():
- raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)
- if Name == 'CAPSULE_FLAGS':
- if not self._Token in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
- raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
- Value = self._Token.strip()
- while self._IsToken(TAB_COMMA_SPLIT):
- Value += TAB_COMMA_SPLIT
- if not self._GetNextToken():
- raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)
- if not self._Token in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
- raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
- Value += self._Token.strip()
- elif Name == 'OEM_CAPSULE_FLAGS':
- Value = self._Token.strip()
- if not Value.upper().startswith('0X'):
- raise Warning.Expected("hex value starting with 0x", self.FileName, self.CurrentLineNumber)
- try:
- Value = int(Value, 0)
- except ValueError:
- raise Warning.Expected("hex string failed to convert to value", self.FileName, self.CurrentLineNumber)
- if not 0x0000 <= Value <= 0xFFFF:
- raise Warning.Expected("hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
- Value = self._Token.strip()
- else:
- Value = self._Token.strip()
- Obj.TokensDict[Name] = Value
- if not self._GetNextToken():
- return False
- self._UndoToken()
-
- ## _GetCapsuleData() method
- #
- # Get capsule data for capsule
- #
- # @param self The object pointer
- # @param Obj for whom capsule data are got
- #
- def _GetCapsuleData(self, Obj):
- while True:
- IsInf = self._GetInfStatement(Obj, True)
- IsFile = self._GetFileStatement(Obj, True)
- IsFv = self._GetFvStatement(Obj)
- IsFd = self._GetFdStatement(Obj)
- IsAnyFile = self._GetAnyFileStatement(Obj)
- IsAfile = self._GetAfileStatement(Obj)
- IsFmp = self._GetFmpStatement(Obj)
- if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp):
- break
-
- ## _GetFMPCapsuleData() method
- #
- # Get capsule data for FMP capsule
- #
- # @param self The object pointer
- # @param Obj for whom capsule data are got
- #
- def _GetFMPCapsuleData(self, Obj):
- while True:
- IsFv = self._GetFvStatement(Obj, True)
- IsFd = self._GetFdStatement(Obj, True)
- IsAnyFile = self._GetAnyFileStatement(Obj, True)
- if not (IsFv or IsFd or IsAnyFile):
- break
-
- ## _GetFvStatement() method
- #
- # Get FV for capsule
- #
- # @param self The object pointer
- # @param CapsuleObj for whom FV is got
- # @retval True Successfully find a FV statement
- # @retval False Not able to find a FV statement
- #
- def _GetFvStatement(self, CapsuleObj, FMPCapsule = False):
- if not self._IsKeyword(BINARY_FILE_TYPE_FV):
- return False
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)
-
- if self._Token.upper() not in self.Profile.FvDict:
- raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)
-
- myCapsuleFv = CapsuleFv()
- myCapsuleFv.FvName = self._Token
- if FMPCapsule:
- if not CapsuleObj.ImageFile:
- CapsuleObj.ImageFile.append(myCapsuleFv)
- else:
- CapsuleObj.VendorCodeFile.append(myCapsuleFv)
- else:
- CapsuleObj.CapsuleDataList.append(myCapsuleFv)
- return True
-
- ## _GetFdStatement() method
- #
- # Get FD for capsule
- #
- # @param self The object pointer
- # @param CapsuleObj for whom FD is got
- # @retval True Successfully find a FD statement
- # @retval False Not able to find a FD statement
- #
- def _GetFdStatement(self, CapsuleObj, FMPCapsule = False):
- if not self._IsKeyword("FD"):
- return False
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("FD name", self.FileName, self.CurrentLineNumber)
-
- if self._Token.upper() not in self.Profile.FdDict:
- raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)
-
- myCapsuleFd = CapsuleFd()
- myCapsuleFd.FdName = self._Token
- if FMPCapsule:
- if not CapsuleObj.ImageFile:
- CapsuleObj.ImageFile.append(myCapsuleFd)
- else:
- CapsuleObj.VendorCodeFile.append(myCapsuleFd)
- else:
- CapsuleObj.CapsuleDataList.append(myCapsuleFd)
- return True
-
- def _GetFmpStatement(self, CapsuleObj):
- if not self._IsKeyword("FMP_PAYLOAD"):
- if not self._IsKeyword("FMP"):
- return False
-
- if not self._IsKeyword("PAYLOAD"):
- self._UndoToken()
- return False
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("payload name after FMP_PAYLOAD =", self.FileName, self.CurrentLineNumber)
- Payload = self._Token.upper()
- if Payload not in self.Profile.FmpPayloadDict:
- raise Warning("This FMP Payload does not exist: %s" % self._Token, self.FileName, self.CurrentLineNumber)
- CapsuleObj.FmpPayloadList.append(self.Profile.FmpPayloadDict[Payload])
- return True
-
- def _ParseRawFileStatement(self):
- if not self._IsKeyword("FILE"):
- return None
-
- if not self._IsKeyword("DATA"):
- self._UndoToken()
- return None
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)
-
- AnyFileName = self._Token
- self._VerifyFile(AnyFileName)
-
- if not os.path.isabs(AnyFileName):
- AnyFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, AnyFileName)
-
- return AnyFileName
-
- ## _GetAnyFileStatement() method
- #
- # Get AnyFile for capsule
- #
- # @param self The object pointer
- # @param CapsuleObj for whom AnyFile is got
- # @retval True Successfully find a Anyfile statement
- # @retval False Not able to find a AnyFile statement
- #
- def _GetAnyFileStatement(self, CapsuleObj, FMPCapsule = False):
- AnyFileName = self._ParseRawFileStatement()
- if not AnyFileName:
- return False
-
- myCapsuleAnyFile = CapsuleAnyFile()
- myCapsuleAnyFile.FileName = AnyFileName
- if FMPCapsule:
- if not CapsuleObj.ImageFile:
- CapsuleObj.ImageFile.append(myCapsuleAnyFile)
- else:
- CapsuleObj.VendorCodeFile.append(myCapsuleAnyFile)
- else:
- CapsuleObj.CapsuleDataList.append(myCapsuleAnyFile)
- return True
-
- ## _GetAfileStatement() method
- #
- # Get Afile for capsule
- #
- # @param self The object pointer
- # @param CapsuleObj for whom Afile is got
- # @retval True Successfully find a Afile statement
- # @retval False Not able to find a Afile statement
- #
- def _GetAfileStatement(self, CapsuleObj):
- if not self._IsKeyword("APPEND"):
- return False
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("Afile name", self.FileName, self.CurrentLineNumber)
-
- AfileName = self._Token
- AfileBaseName = os.path.basename(AfileName)
-
- if os.path.splitext(AfileBaseName)[1] not in {".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"}:
- raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \
- self.FileName, self.CurrentLineNumber)
-
- if not os.path.isabs(AfileName):
- AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName)
- self._VerifyFile(AfileName)
- else:
- if not os.path.exists(AfileName):
- raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber)
- else:
- pass
-
- myCapsuleAfile = CapsuleAfile()
- myCapsuleAfile.FileName = AfileName
- CapsuleObj.CapsuleDataList.append(myCapsuleAfile)
- return True
-
- ## _GetRule() method
- #
- # Get Rule section contents and store its data into rule list of self.Profile
- #
- # @param self The object pointer
- # @retval True Successfully find a Rule
- # @retval False Not able to find a Rule
- #
- def _GetRule(self):
- if not self._GetNextToken():
- return False
-
- S = self._Token.upper()
- if S.startswith(TAB_SECTION_START) and not S.startswith("[RULE."):
- self.SectionParser(S)
- self._UndoToken()
- return False
- self._UndoToken()
- if not self._IsToken("[Rule.", True):
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
- # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
- raise Warning.Expected("[Rule.]", self.FileName, self.CurrentLineNumber)
-
- if not self._SkipToToken(TAB_SPLIT):
- raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber)
-
- Arch = self._SkippedChars.rstrip(TAB_SPLIT)
-
- ModuleType = self._GetModuleType()
-
- TemplateName = ""
- if self._IsToken(TAB_SPLIT):
- if not self._GetNextWord():
- raise Warning.Expected("template name", self.FileName, self.CurrentLineNumber)
- TemplateName = self._Token
-
- if not self._IsToken(TAB_SECTION_END):
- raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)
-
- RuleObj = self._GetRuleFileStatements()
- RuleObj.Arch = Arch.upper()
- RuleObj.ModuleType = ModuleType
- RuleObj.TemplateName = TemplateName
- if TemplateName == '':
- self.Profile.RuleDict['RULE' + \
- TAB_SPLIT + \
- Arch.upper() + \
- TAB_SPLIT + \
- ModuleType.upper() ] = RuleObj
- else:
- self.Profile.RuleDict['RULE' + \
- TAB_SPLIT + \
- Arch.upper() + \
- TAB_SPLIT + \
- ModuleType.upper() + \
- TAB_SPLIT + \
- TemplateName.upper() ] = RuleObj
- return True
-
- ## _GetModuleType() method
- #
- # Return the module type
- #
- # @param self The object pointer
- # @retval string module type
- #
- def _GetModuleType(self):
- if not self._GetNextWord():
- raise Warning.Expected("Module type", self.FileName, self.CurrentLineNumber)
- if self._Token.upper() not in {
- SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM,
- SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER,
- SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_DXE_SMM_DRIVER,
- SUP_MODULE_DXE_RUNTIME_DRIVER, SUP_MODULE_UEFI_DRIVER,
- SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_USER_DEFINED, SUP_MODULE_HOST_APPLICATION,
- TAB_DEFAULT, SUP_MODULE_BASE,
- EDK_COMPONENT_TYPE_SECURITY_CORE,
- EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER,
- EDK_COMPONENT_TYPE_PIC_PEIM,
- EDK_COMPONENT_TYPE_RELOCATABLE_PEIM, "PE32_PEIM",
- EDK_COMPONENT_TYPE_BS_DRIVER, EDK_COMPONENT_TYPE_RT_DRIVER,
- EDK_COMPONENT_TYPE_SAL_RT_DRIVER,
- EDK_COMPONENT_TYPE_APPLICATION, "ACPITABLE",
- SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE,
- SUP_MODULE_MM_CORE_STANDALONE}:
- raise Warning("Unknown Module type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
- return self._Token
-
- ## _GetFileExtension() method
- #
- # Return the file extension
- #
- # @param self The object pointer
- # @retval string file name extension
- #
- def _GetFileExtension(self):
- if not self._IsToken(TAB_SPLIT):
- raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber)
-
- Ext = ""
- if self._GetNextToken():
- if FileExtensionPattern.match(self._Token):
- Ext = self._Token
- return TAB_SPLIT + Ext
- else:
- raise Warning("Unknown file extension '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
-
- else:
- raise Warning.Expected("file extension", self.FileName, self.CurrentLineNumber)
-
- ## _GetRuleFileStatement() method
- #
- # Get rule contents
- #
- # @param self The object pointer
- # @retval Rule Rule object
- #
- def _GetRuleFileStatements(self):
- if not self._IsKeyword("FILE"):
- raise Warning.Expected("FILE", self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextWord():
- raise Warning.Expected("FFS type", self.FileName, self.CurrentLineNumber)
-
- Type = self._Token.strip().upper()
- if Type not in {"RAW", "FREEFORM", SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM,
- "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE, EDK_COMPONENT_TYPE_APPLICATION,
- "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE,
- SUP_MODULE_MM_CORE_STANDALONE}:
- raise Warning("Unknown FV type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._IsKeyword("$(NAMED_GUID)"):
- if not self._GetNextWord():
- NamedGuid = self._CurrentLine()[self.CurrentOffsetWithinLine:].split()[0].strip()
- if GlobalData.gGuidPatternEnd.match(NamedGuid):
- self.CurrentOffsetWithinLine += len(NamedGuid)
- self._Token = NamedGuid
- else:
- raise Warning.Expected("$(NAMED_GUID)", self.FileName, self.CurrentLineNumber)
- if self._Token == 'PCD':
- if not self._IsToken("("):
- raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)
- PcdPair = self._GetNextPcdSettings()
- if not self._IsToken(")"):
- raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)
- self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'
-
- NameGuid = self._Token
-
- KeepReloc = None
- if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):
- if self._FileCouldHaveRelocFlag(Type):
- if self._Token == 'RELOCS_STRIPPED':
- KeepReloc = False
- else:
- KeepReloc = True
- else:
- raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
-
- KeyStringList = []
- if self._GetNextToken():
- if TokenFindPattern.match(self._Token):
- KeyStringList.append(self._Token)
- if self._IsToken(TAB_COMMA_SPLIT):
- while self._GetNextToken():
- if not TokenFindPattern.match(self._Token):
- raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
- KeyStringList.append(self._Token)
-
- if not self._IsToken(TAB_COMMA_SPLIT):
- break
-
- else:
- self._UndoToken()
-
-
- Fixed = False
- if self._IsKeyword("Fixed", True):
- Fixed = True
-
- CheckSum = False
- if self._IsKeyword("CheckSum", True):
- CheckSum = True
-
- AlignValue = ""
- if self._GetAlignment():
- if self._Token not in ALIGNMENTS:
- raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
- #For FFS, Auto is default option same to ""
- if not self._Token == "Auto":
- AlignValue = self._Token
-
- if self._IsToken("{"):
- # Complex file rule expected
- NewRule = RuleComplexFile()
- NewRule.FvFileType = Type
- NewRule.NameGuid = NameGuid
- NewRule.Alignment = AlignValue
- NewRule.CheckSum = CheckSum
- NewRule.Fixed = Fixed
- NewRule.KeyStringList = KeyStringList
- if KeepReloc is not None:
- NewRule.KeepReloc = KeepReloc
-
- while True:
- IsEncapsulate = self._GetRuleEncapsulationSection(NewRule)
- IsLeaf = self._GetEfiSection(NewRule)
- if not IsEncapsulate and not IsLeaf:
- break
-
- if not self._IsToken(T_CHAR_BRACE_R):
- raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
-
- return NewRule
-
- else:
- # Simple file rule expected
- if not self._GetNextWord():
- raise Warning.Expected("leaf section type", self.FileName, self.CurrentLineNumber)
-
- SectionName = self._Token
-
- if SectionName not in {
- "COMPAT16", BINARY_FILE_TYPE_PE32,
- BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE",
- "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,
- BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",
- BINARY_FILE_TYPE_SMM_DEPEX}:
- raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)
-
-
- if self._IsKeyword("Fixed", True):
- Fixed = True
-
- if self._IsKeyword("CheckSum", True):
- CheckSum = True
-
- SectAlignment = ""
- if self._GetAlignment():
- if self._Token not in ALIGNMENTS:
- raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
- if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE):
- raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
- SectAlignment = self._Token
-
- Ext = None
- if self._IsToken(TAB_VALUE_SPLIT):
- Ext = self._GetFileExtension()
- elif not self._GetNextToken():
- raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)
-
- NewRule = RuleSimpleFile()
- NewRule.SectionType = SectionName
- NewRule.FvFileType = Type
- NewRule.NameGuid = NameGuid
- NewRule.Alignment = AlignValue
- NewRule.SectAlignment = SectAlignment
- NewRule.CheckSum = CheckSum
- NewRule.Fixed = Fixed
- NewRule.KeyStringList = KeyStringList
- if KeepReloc is not None:
- NewRule.KeepReloc = KeepReloc
- NewRule.FileExtension = Ext
- NewRule.FileName = self._Token
- return NewRule
-
- ## _GetEfiSection() method
- #
- # Get section list for Rule
- #
- # @param self The object pointer
- # @param Obj for whom section is got
- # @retval True Successfully find section statement
- # @retval False Not able to find section statement
- #
- def _GetEfiSection(self, Obj):
- OldPos = self.GetFileBufferPos()
- EfiSectionObj = EfiSection()
- if not self._GetNextWord():
- CurrentLine = self._CurrentLine()[self.CurrentOffsetWithinLine:].split()[0].strip()
- if self._Token == '{' and Obj.FvFileType == "RAW" and TAB_SPLIT in CurrentLine:
- if self._IsToken(TAB_VALUE_SPLIT):
- EfiSectionObj.FileExtension = self._GetFileExtension()
- elif self._GetNextToken():
- EfiSectionObj.FileName = self._Token
- EfiSectionObj.SectionType = BINARY_FILE_TYPE_RAW
- Obj.SectionList.append(EfiSectionObj)
- return True
- else:
- return False
- SectionName = self._Token
-
- if SectionName not in {
- "COMPAT16", BINARY_FILE_TYPE_PE32,
- BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE",
- "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,
- BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",
- BINARY_FILE_TYPE_SMM_DEPEX, BINARY_FILE_TYPE_GUID}:
- self._UndoToken()
- return False
-
- if SectionName == "FV_IMAGE":
- FvImageSectionObj = FvImageSection()
- if self._IsKeyword("FV_IMAGE"):
- pass
- if self._IsToken("{"):
- FvObj = FV()
- self._GetDefineStatements(FvObj)
- self._GetBlockStatement(FvObj)
- self._GetSetStatements(FvObj)
- self._GetFvAlignment(FvObj)
- self._GetFvAttributes(FvObj)
- self._GetAprioriSection(FvObj)
- self._GetAprioriSection(FvObj)
-
- while True:
- IsInf = self._GetInfStatement(FvObj)
- IsFile = self._GetFileStatement(FvObj)
- if not IsInf and not IsFile:
- break
-
- if not self._IsToken(T_CHAR_BRACE_R):
- raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
- FvImageSectionObj.Fv = FvObj
- FvImageSectionObj.FvName = None
-
- else:
- if not self._IsKeyword(BINARY_FILE_TYPE_FV):
- raise Warning.Expected("'FV'", self.FileName, self.CurrentLineNumber)
- FvImageSectionObj.FvFileType = self._Token
-
- if self._GetAlignment():
- if self._Token not in ALIGNMENT_NOAUTO:
- raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
- FvImageSectionObj.Alignment = self._Token
-
- if self._IsToken(TAB_VALUE_SPLIT):
- FvImageSectionObj.FvFileExtension = self._GetFileExtension()
- elif self._GetNextToken():
- if self._Token not in {
- T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32,
- BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE,
- "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,
- BINARY_FILE_TYPE_UI, "VERSION",
- BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,
- BINARY_FILE_TYPE_SMM_DEPEX}:
- FvImageSectionObj.FvFileName = self._Token
- else:
- self._UndoToken()
- else:
- raise Warning.Expected("FV file name", self.FileName, self.CurrentLineNumber)
-
- Obj.SectionList.append(FvImageSectionObj)
- return True
-
- EfiSectionObj.SectionType = SectionName
-
- if not self._GetNextToken():
- raise Warning.Expected("file type", self.FileName, self.CurrentLineNumber)
-
- if self._Token == "STRING":
- if not self._RuleSectionCouldHaveString(EfiSectionObj.SectionType):
- raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
-
- if not self._GetNextToken():
- raise Warning.Expected("Quoted String", self.FileName, self.CurrentLineNumber)
-
- if self._GetStringData():
- EfiSectionObj.StringData = self._Token
-
- if self._IsKeyword("BUILD_NUM"):
- if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
- raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextToken():
- raise Warning.Expected("Build number", self.FileName, self.CurrentLineNumber)
- EfiSectionObj.BuildNum = self._Token
-
- else:
- EfiSectionObj.FileType = self._Token
- self._CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)
-
- if self._IsKeyword("Optional"):
- if not self._RuleSectionCouldBeOptional(EfiSectionObj.SectionType):
- raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
- EfiSectionObj.Optional = True
-
- if self._IsKeyword("BUILD_NUM"):
- if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
- raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
-
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextToken():
- raise Warning.Expected("Build number", self.FileName, self.CurrentLineNumber)
- EfiSectionObj.BuildNum = self._Token
-
- if self._GetAlignment():
- if self._Token not in ALIGNMENTS:
- raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
- if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE):
- raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
- EfiSectionObj.Alignment = self._Token
-
- if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):
- if self._SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):
- if self._Token == 'RELOCS_STRIPPED':
- EfiSectionObj.KeepReloc = False
- else:
- EfiSectionObj.KeepReloc = True
- if Obj.KeepReloc is not None and Obj.KeepReloc != EfiSectionObj.KeepReloc:
- raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
- else:
- raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
-
-
- if self._IsToken(TAB_VALUE_SPLIT):
- EfiSectionObj.FileExtension = self._GetFileExtension()
- elif self._GetNextToken():
- if self._Token not in {
- T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32,
- BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE,
- "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,
- BINARY_FILE_TYPE_UI, "VERSION",
- BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,
- BINARY_FILE_TYPE_SMM_DEPEX}:
-
- if self._Token.startswith('PCD'):
- self._UndoToken()
- self._GetNextWord()
-
- if self._Token == 'PCD':
- if not self._IsToken("("):
- raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)
- PcdPair = self._GetNextPcdSettings()
- if not self._IsToken(")"):
- raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)
- self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'
-
- EfiSectionObj.FileName = self._Token
-
- else:
- self._UndoToken()
- else:
- raise Warning.Expected("section file name", self.FileName, self.CurrentLineNumber)
-
- Obj.SectionList.append(EfiSectionObj)
- return True
-
- ## _RuleSectionCouldBeOptional() method
- #
- # Get whether a section could be optional
- #
- # @param SectionType The section type to check
- # @retval True section could be optional
- # @retval False section never optional
- #
- @staticmethod
- def _RuleSectionCouldBeOptional(SectionType):
- if SectionType in {BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "RAW", BINARY_FILE_TYPE_SMM_DEPEX}:
- return True
- else:
- return False
-
- ## _RuleSectionCouldHaveBuildNum() method
- #
- # Get whether a section could have build number information
- #
- # @param SectionType The section type to check
- # @retval True section could have build number information
- # @retval False section never have build number information
- #
- @staticmethod
- def _RuleSectionCouldHaveBuildNum(SectionType):
- if SectionType == "VERSION":
- return True
- else:
- return False
-
- ## _RuleSectionCouldHaveString() method
- #
- # Get whether a section could have string
- #
- # @param SectionType The section type to check
- # @retval True section could have string
- # @retval False section never have string
- #
- @staticmethod
- def _RuleSectionCouldHaveString(SectionType):
- if SectionType in {BINARY_FILE_TYPE_UI, "VERSION"}:
- return True
- else:
- return False
-
- ## _CheckRuleSectionFileType() method
- #
- # Get whether a section matches a file type
- #
- # @param self The object pointer
- # @param SectionType The section type to check
- # @param FileType The file type to check
- #
- def _CheckRuleSectionFileType(self, SectionType, FileType):
- WarningString = "Incorrect section file type '%s'"
- if SectionType == "COMPAT16":
- if FileType not in {"COMPAT16", "SEC_COMPAT16"}:
- raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
- elif SectionType == BINARY_FILE_TYPE_PE32:
- if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_PE32"}:
- raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
- elif SectionType == BINARY_FILE_TYPE_PIC:
- if FileType not in {BINARY_FILE_TYPE_PIC, "SEC_PIC"}:
- raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
- elif SectionType == BINARY_FILE_TYPE_TE:
- if FileType not in {BINARY_FILE_TYPE_TE, "SEC_TE"}:
- raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
- elif SectionType == "RAW":
- if FileType not in {BINARY_FILE_TYPE_BIN, "SEC_BIN", "RAW", "ASL", "ACPI"}:
- raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
- elif SectionType == BINARY_FILE_TYPE_DXE_DEPEX or SectionType == BINARY_FILE_TYPE_SMM_DEPEX:
- if FileType not in {BINARY_FILE_TYPE_DXE_DEPEX, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX}:
- raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
- elif SectionType == BINARY_FILE_TYPE_UI:
- if FileType not in {BINARY_FILE_TYPE_UI, "SEC_UI"}:
- raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
- elif SectionType == "VERSION":
- if FileType not in {"VERSION", "SEC_VERSION"}:
- raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
- elif SectionType == BINARY_FILE_TYPE_PEI_DEPEX:
- if FileType not in {BINARY_FILE_TYPE_PEI_DEPEX, "SEC_PEI_DEPEX"}:
- raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
- elif SectionType == BINARY_FILE_TYPE_GUID:
- if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_GUID"}:
- raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)
-
- ## _GetRuleEncapsulationSection() method
- #
- # Get encapsulation section for Rule
- #
- # @param self The object pointer
- # @param theRule for whom section is got
- # @retval True Successfully find section statement
- # @retval False Not able to find section statement
- #
- def _GetRuleEncapsulationSection(self, theRule):
- if self._IsKeyword("COMPRESS"):
- Type = "PI_STD"
- if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"):
- Type = self._Token
-
- if not self._IsToken("{"):
- raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
-
- CompressSectionObj = CompressSection()
-
- CompressSectionObj.CompType = Type
- # Recursive sections...
- while True:
- IsEncapsulate = self._GetRuleEncapsulationSection(CompressSectionObj)
- IsLeaf = self._GetEfiSection(CompressSectionObj)
- if not IsEncapsulate and not IsLeaf:
- break
-
- if not self._IsToken(T_CHAR_BRACE_R):
- raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
- theRule.SectionList.append(CompressSectionObj)
-
- return True
-
- elif self._IsKeyword("GUIDED"):
- GuidValue = None
- if self._GetNextGuid():
- if self._Token in GlobalData.gGuidDict:
- self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper()
- GuidValue = self._Token
-
- if self._IsKeyword("$(NAMED_GUID)"):
- GuidValue = self._Token
-
- AttribDict = self._GetGuidAttrib()
-
- if not self._IsToken("{"):
- raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)
- GuidSectionObj = GuidSection()
- GuidSectionObj.NameGuid = GuidValue
- GuidSectionObj.SectionType = "GUIDED"
- GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
- GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
- GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]
-
- # Efi sections...
- while True:
- IsEncapsulate = self._GetRuleEncapsulationSection(GuidSectionObj)
- IsLeaf = self._GetEfiSection(GuidSectionObj)
- if not IsEncapsulate and not IsLeaf:
- break
-
- if not self._IsToken(T_CHAR_BRACE_R):
- raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)
- theRule.SectionList.append(GuidSectionObj)
-
- return True
-
- return False
-
- ## _GetOptionRom() method
- #
- # Get OptionROM section contents and store its data into OptionROM list of self.Profile
- #
- # @param self The object pointer
- # @retval True Successfully find a OptionROM
- # @retval False Not able to find a OptionROM
- #
- def _GetOptionRom(self):
- if not self._GetNextToken():
- return False
-
- S = self._Token.upper()
- if S.startswith(TAB_SECTION_START) and not S.startswith("[OPTIONROM."):
- self.SectionParser(S)
- self._UndoToken()
- return False
-
- self._UndoToken()
- if not self._IsToken("[OptionRom.", True):
- raise Warning("Unknown Keyword '%s'" % self._Token, self.FileName, self.CurrentLineNumber)
-
- OptRomName = self._GetUiName()
-
- if not self._IsToken(TAB_SECTION_END):
- raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)
-
- OptRomObj = OPTIONROM(OptRomName)
- self.Profile.OptRomDict[OptRomName] = OptRomObj
-
- while True:
- isInf = self._GetOptRomInfStatement(OptRomObj)
- isFile = self._GetOptRomFileStatement(OptRomObj)
- if not isInf and not isFile:
- break
-
- return True
-
- ## _GetOptRomInfStatement() method
- #
- # Get INF statements
- #
- # @param self The object pointer
- # @param Obj for whom inf statement is got
- # @retval True Successfully find inf statement
- # @retval False Not able to find inf statement
- #
- def _GetOptRomInfStatement(self, Obj):
- if not self._IsKeyword("INF"):
- return False
-
- ffsInf = OptRomInfStatement()
- self._GetInfOptions(ffsInf)
-
- if not self._GetNextToken():
- raise Warning.Expected("INF file path", self.FileName, self.CurrentLineNumber)
- ffsInf.InfFileName = self._Token
- if ffsInf.InfFileName.replace(TAB_WORKSPACE, '').find('$') == -1:
- #check for file path
- ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
- if ErrorCode != 0:
- EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
-
- NewFileName = ffsInf.InfFileName
- if ffsInf.OverrideGuid:
- NewFileName = ProcessDuplicatedInf(PathClass(ffsInf.InfFileName,GenFdsGlobalVariable.WorkSpaceDir), ffsInf.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir).Path
-
- if not NewFileName in self.Profile.InfList:
- self.Profile.InfList.append(NewFileName)
- FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
- self.Profile.InfFileLineList.append(FileLineTuple)
- if ffsInf.UseArch:
- if ffsInf.UseArch not in self.Profile.InfDict:
- self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]
- else:
- self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)
- else:
- self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)
-
-
- self._GetOptRomOverrides (ffsInf)
-
- Obj.FfsList.append(ffsInf)
- return True
-
- ## _GetOptRomOverrides() method
- #
- # Get overrides for OptROM INF & FILE
- #
- # @param self The object pointer
- # @param FfsInfObj for whom overrides is got
- #
- def _GetOptRomOverrides(self, Obj):
- if self._IsToken('{'):
- Overrides = OverrideAttribs()
- while True:
- if self._IsKeyword("PCI_VENDOR_ID"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextHexNumber():
- raise Warning.Expected("Hex vendor id", self.FileName, self.CurrentLineNumber)
- Overrides.PciVendorId = self._Token
- continue
-
- if self._IsKeyword("PCI_CLASS_CODE"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextHexNumber():
- raise Warning.Expected("Hex class code", self.FileName, self.CurrentLineNumber)
- Overrides.PciClassCode = self._Token
- continue
-
- if self._IsKeyword("PCI_DEVICE_ID"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- # Get a list of PCI IDs
- Overrides.PciDeviceId = ""
- while (self._GetNextHexNumber()):
- Overrides.PciDeviceId = "{} {}".format(Overrides.PciDeviceId, self._Token)
- if not Overrides.PciDeviceId:
- raise Warning.Expected("one or more Hex device ids", self.FileName, self.CurrentLineNumber)
- continue
-
- if self._IsKeyword("PCI_REVISION"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextHexNumber():
- raise Warning.Expected("Hex revision", self.FileName, self.CurrentLineNumber)
- Overrides.PciRevision = self._Token
- continue
-
- if self._IsKeyword("PCI_COMPRESS"):
- if not self._IsToken(TAB_EQUAL_SPLIT):
- raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)
- if not self._GetNextToken():
- raise Warning.Expected("TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)
- Overrides.NeedCompress = self._Token.upper() == 'TRUE'
- continue
-
- if self._IsToken(T_CHAR_BRACE_R):
- break
- else:
- EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)
-
- Obj.OverrideAttribs = Overrides
-
- ## _GetOptRomFileStatement() method
- #
- # Get FILE statements
- #
- # @param self The object pointer
- # @param Obj for whom FILE statement is got
- # @retval True Successfully find FILE statement
- # @retval False Not able to find FILE statement
- #
- def _GetOptRomFileStatement(self, Obj):
- if not self._IsKeyword("FILE"):
- return False
-
- FfsFileObj = OptRomFileStatement()
-
- if not self._IsKeyword("EFI") and not self._IsKeyword(BINARY_FILE_TYPE_BIN):
- raise Warning.Expected("Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber)
- FfsFileObj.FileType = self._Token
-
- if not self._GetNextToken():
- raise Warning.Expected("File path", self.FileName, self.CurrentLineNumber)
- FfsFileObj.FileName = self._Token
- if FfsFileObj.FileName.replace(TAB_WORKSPACE, '').find('$') == -1:
- #check for file path
- ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
- if ErrorCode != 0:
- EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
-
- if FfsFileObj.FileType == 'EFI':
- self._GetOptRomOverrides(FfsFileObj)
-
- Obj.FfsList.append(FfsFileObj)
-
- return True
-
- ## _GetCapInFd() method
- #
- # Get Cap list contained in FD
- #
- # @param self The object pointer
- # @param FdName FD name
- # @retval CapList List of Capsule in FD
- #
- def _GetCapInFd (self, FdName):
- CapList = []
- if FdName.upper() in self.Profile.FdDict:
- FdObj = self.Profile.FdDict[FdName.upper()]
- for elementRegion in FdObj.RegionList:
- if elementRegion.RegionType == 'CAPSULE':
- for elementRegionData in elementRegion.RegionDataList:
- if elementRegionData.endswith(".cap"):
- continue
- if elementRegionData is not None and elementRegionData.upper() not in CapList:
- CapList.append(elementRegionData.upper())
- return CapList
-
- ## _GetReferencedFdCapTuple() method
- #
- # Get FV and FD list referenced by a capsule image
- #
- # @param self The object pointer
- # @param CapObj Capsule section to be searched
- # @param RefFdList referenced FD by section
- # @param RefFvList referenced FV by section
- #
- def _GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):
- for CapsuleDataObj in CapObj.CapsuleDataList:
- if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName is not None and CapsuleDataObj.FvName.upper() not in RefFvList:
- RefFvList.append (CapsuleDataObj.FvName.upper())
- elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName is not None and CapsuleDataObj.FdName.upper() not in RefFdList:
- RefFdList.append (CapsuleDataObj.FdName.upper())
- elif CapsuleDataObj.Ffs is not None:
- if isinstance(CapsuleDataObj.Ffs, FileStatement):
- if CapsuleDataObj.Ffs.FvName is not None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:
- RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())
- elif CapsuleDataObj.Ffs.FdName is not None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:
- RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())
- else:
- self._GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)
-
- ## _GetFvInFd() method
- #
- # Get FV list contained in FD
- #
- # @param self The object pointer
- # @param FdName FD name
- # @retval FvList list of FV in FD
- #
- def _GetFvInFd (self, FdName):
- FvList = []
- if FdName.upper() in self.Profile.FdDict:
- FdObj = self.Profile.FdDict[FdName.upper()]
- for elementRegion in FdObj.RegionList:
- if elementRegion.RegionType == BINARY_FILE_TYPE_FV:
- for elementRegionData in elementRegion.RegionDataList:
- if elementRegionData.endswith(".fv"):
- continue
- if elementRegionData is not None and elementRegionData.upper() not in FvList:
- FvList.append(elementRegionData.upper())
- return FvList
-
- ## _GetReferencedFdFvTuple() method
- #
- # Get FD and FV list referenced by a FFS file
- #
- # @param self The object pointer
- # @param FfsFile contains sections to be searched
- # @param RefFdList referenced FD by section
- # @param RefFvList referenced FV by section
- #
- def _GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):
- for FfsObj in FvObj.FfsList:
- if isinstance(FfsObj, FileStatement):
- if FfsObj.FvName is not None and FfsObj.FvName.upper() not in RefFvList:
- RefFvList.append(FfsObj.FvName.upper())
- elif FfsObj.FdName is not None and FfsObj.FdName.upper() not in RefFdList:
- RefFdList.append(FfsObj.FdName.upper())
- else:
- self._GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)
-
- ## _GetReferencedFdFvTupleFromSection() method
- #
- # Get FD and FV list referenced by a FFS section
- #
- # @param self The object pointer
- # @param FfsFile contains sections to be searched
- # @param FdList referenced FD by section
- # @param FvList referenced FV by section
- #
- def _GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):
- SectionStack = list(FfsFile.SectionList)
- while SectionStack != []:
- SectionObj = SectionStack.pop()
- if isinstance(SectionObj, FvImageSection):
- if SectionObj.FvName is not None and SectionObj.FvName.upper() not in FvList:
- FvList.append(SectionObj.FvName.upper())
- if SectionObj.Fv is not None and SectionObj.Fv.UiFvName is not None and SectionObj.Fv.UiFvName.upper() not in FvList:
- FvList.append(SectionObj.Fv.UiFvName.upper())
- self._GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)
-
- if isinstance(SectionObj, CompressSection) or isinstance(SectionObj, GuidSection):
- SectionStack.extend(SectionObj.SectionList)
-
- ## CycleReferenceCheck() method
- #
- # Check whether cycle reference exists in FDF
- #
- # @param self The object pointer
- # @retval True cycle reference exists
- # @retval False Not exists cycle reference
- #
- def CycleReferenceCheck(self):
- #
- # Check the cycle between FV and FD image
- #
- MaxLength = len (self.Profile.FvDict)
- for FvName in self.Profile.FvDict:
- LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName
- RefFvStack = set(FvName)
- FdAnalyzedList = set()
-
- Index = 0
- while RefFvStack and Index < MaxLength:
- Index = Index + 1
- FvNameFromStack = RefFvStack.pop()
- if FvNameFromStack.upper() in self.Profile.FvDict:
- FvObj = self.Profile.FvDict[FvNameFromStack.upper()]
- else:
- continue
-
- RefFdList = []
- RefFvList = []
- self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
-
- for RefFdName in RefFdList:
- if RefFdName in FdAnalyzedList:
- continue
-
- LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)
- FvInFdList = self._GetFvInFd(RefFdName)
- if FvInFdList != []:
- for FvNameInFd in FvInFdList:
- LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd)
- if FvNameInFd not in RefFvStack:
- RefFvStack.add(FvNameInFd)
-
- if FvName in RefFvStack or FvNameFromStack in RefFvStack:
- EdkLogger.info(LogStr)
- return True
- FdAnalyzedList.add(RefFdName)
-
- for RefFvName in RefFvList:
- LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)
- if RefFvName not in RefFvStack:
- RefFvStack.add(RefFvName)
-
- if FvName in RefFvStack or FvNameFromStack in RefFvStack:
- EdkLogger.info(LogStr)
- return True
-
- #
- # Check the cycle between Capsule and FD image
- #
- MaxLength = len (self.Profile.CapsuleDict)
- for CapName in self.Profile.CapsuleDict:
- #
- # Capsule image to be checked.
- #
- LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
- RefCapStack = {CapName}
- FdAnalyzedList = set()
- FvAnalyzedList = set()
-
- Index = 0
- while RefCapStack and Index < MaxLength:
- Index = Index + 1
- CapNameFromStack = RefCapStack.pop()
- if CapNameFromStack.upper() in self.Profile.CapsuleDict:
- CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]
- else:
- continue
-
- RefFvList = []
- RefFdList = []
- self._GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)
-
- FvListLength = 0
- FdListLength = 0
- while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):
- for RefFdName in RefFdList:
- if RefFdName in FdAnalyzedList:
- continue
-
- LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)
- for CapNameInFd in self._GetCapInFd(RefFdName):
- LogStr += "FD %s contains Capsule %s\n" % (RefFdName, CapNameInFd)
- if CapNameInFd not in RefCapStack:
- RefCapStack.append(CapNameInFd)
-
- if CapName in RefCapStack or CapNameFromStack in RefCapStack:
- EdkLogger.info(LogStr)
- return True
-
- for FvNameInFd in self._GetFvInFd(RefFdName):
- LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd)
- if FvNameInFd not in RefFvList:
- RefFvList.append(FvNameInFd)
-
- FdAnalyzedList.add(RefFdName)
- #
- # the number of the parsed FV and FD image
- #
- FvListLength = len (RefFvList)
- FdListLength = len (RefFdList)
- for RefFvName in RefFvList:
- if RefFvName in FvAnalyzedList:
- continue
- LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)
- if RefFvName.upper() in self.Profile.FvDict:
- FvObj = self.Profile.FvDict[RefFvName.upper()]
- else:
- continue
- self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
- FvAnalyzedList.add(RefFvName)
-
- return False
-
- def GetAllIncludedFile (self):
- global AllIncludeFileList
- return AllIncludeFileList
-
-if __name__ == "__main__":
- import sys
- try:
- test_file = sys.argv[1]
- except IndexError as v:
- print("Usage: %s filename" % sys.argv[0])
- sys.exit(1)
-
- parser = FdfParser(test_file)
- try:
- parser.ParseFile()
- parser.CycleReferenceCheck()
- except Warning as X:
- print(str(X))
- else:
- print("Success!")
-
+## @file +# parse FDF file +# +# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import print_function +from __future__ import absolute_import +from re import compile, DOTALL +from string import hexdigits +from uuid import UUID + +from Common.BuildToolError import * +from Common import EdkLogger +from Common.Misc import PathClass, tdict, ProcessDuplicatedInf, GuidStructureStringToGuidString +from Common.StringUtils import NormPath, ReplaceMacro +from Common import GlobalData +from Common.Expression import * +from Common.DataType import * +from Common.MultipleWorkspace import MultipleWorkspace as mws +import Common.LongFilePathOs as os +from Common.LongFilePathSupport import OpenLongFilePath as open +from Common.RangeExpression import RangeExpression +from collections import OrderedDict + +from .Fd import FD +from .Region import Region +from .Fv import FV +from .AprioriSection import AprioriSection +from .FfsInfStatement import FfsInfStatement +from .FfsFileStatement import FileStatement +from .VerSection import VerSection +from .UiSection import UiSection +from .FvImageSection import FvImageSection +from .DataSection import DataSection +from .DepexSection import DepexSection +from .CompressSection import CompressSection +from .GuidSection import GuidSection +from .SubTypeGuidSection import SubTypeGuidSection +from .Capsule import EFI_CERT_TYPE_PKCS7_GUID, EFI_CERT_TYPE_RSA2048_SHA256_GUID, Capsule +from .CapsuleData import CapsuleFfs, CapsulePayload, CapsuleFv, CapsuleFd, CapsuleAnyFile, CapsuleAfile +from .RuleComplexFile import RuleComplexFile +from .RuleSimpleFile import RuleSimpleFile +from .EfiSection import EfiSection +from .OptionRom import OPTIONROM +from .OptRomInfStatement import OptRomInfStatement, OverrideAttribs +from .OptRomFileStatement import OptRomFileStatement +from .GenFdsGlobalVariable import GenFdsGlobalVariable + +T_CHAR_CR = '\r' +T_CHAR_TAB = '\t' +T_CHAR_DOUBLE_QUOTE = '\"' +T_CHAR_SINGLE_QUOTE = '\'' +T_CHAR_BRACE_R = '}' + +SEPARATORS = {TAB_EQUAL_SPLIT, TAB_VALUE_SPLIT, TAB_COMMA_SPLIT, '{', T_CHAR_BRACE_R} +ALIGNMENTS = {"Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K", "64K", "128K", + "256K", "512K", "1M", "2M", "4M", "8M", "16M"} +ALIGNMENT_NOAUTO = ALIGNMENTS - {"Auto"} +CR_LB_SET = {T_CHAR_CR, TAB_LINE_BREAK} + +RegionSizePattern = compile(r"\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*") +RegionSizeGuidPattern = compile(r"\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*") +RegionOffsetPcdPattern = compile(r"\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$") +ShortcutPcdPattern = compile(r"\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*") +BaseAddrValuePattern = compile(r'^0[xX][0-9a-fA-F]+') +FileExtensionPattern = compile(r'([a-zA-Z][a-zA-Z0-9]*)') +TokenFindPattern = compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)') +AllIncludeFileList = [] + +# Get the closest parent +def GetParentAtLine (Line): + for Profile in AllIncludeFileList: + if Profile.IsLineInFile(Line): + return Profile + return None + +# Check include loop +def IsValidInclude (File, Line): + for Profile in AllIncludeFileList: + if Profile.IsLineInFile(Line) and Profile.FileName == File: + return False + + return True + +def GetRealFileLine (File, Line): + InsertedLines = 0 + for Profile in AllIncludeFileList: + if Profile.IsLineInFile(Line): + return Profile.GetLineInFile(Line) + elif Line >= Profile.InsertStartLineNumber and Profile.Level == 1: + InsertedLines += Profile.GetTotalLines() + + return (File, Line - InsertedLines) + +## The exception class that used to report error messages when parsing FDF +# +# Currently the "ToolName" is set to be "FdfParser". +# +class Warning (Exception): + ## The constructor + # + # @param self The object pointer + # @param Str The message to record + # @param File The FDF name + # @param Line The Line number that error occurs + # + def __init__(self, Str, File = None, Line = None): + FileLineTuple = GetRealFileLine(File, Line) + self.FileName = FileLineTuple[0] + self.LineNumber = FileLineTuple[1] + self.OriginalLineNumber = Line + self.Message = Str + self.ToolName = 'FdfParser' + + def __str__(self): + return self.Message + + # helper functions to facilitate consistency in warnings + # each function is for a different common warning + @staticmethod + def Expected(Str, File, Line): + return Warning("expected {}".format(Str), File, Line) + @staticmethod + def ExpectedEquals(File, Line): + return Warning.Expected("'='", File, Line) + @staticmethod + def ExpectedCurlyOpen(File, Line): + return Warning.Expected("'{'", File, Line) + @staticmethod + def ExpectedCurlyClose(File, Line): + return Warning.Expected("'}'", File, Line) + @staticmethod + def ExpectedBracketClose(File, Line): + return Warning.Expected("']'", File, Line) + +## The Include file content class that used to record file data when parsing include file +# +# May raise Exception when opening file. +# +class IncludeFileProfile: + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName): + self.FileName = FileName + self.FileLinesList = [] + try: + with open(FileName, "r") as fsock: + self.FileLinesList = fsock.readlines() + for index, line in enumerate(self.FileLinesList): + if not line.endswith(TAB_LINE_BREAK): + self.FileLinesList[index] += TAB_LINE_BREAK + except: + EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName) + + self.InsertStartLineNumber = None + self.InsertAdjust = 0 + self.IncludeFileList = [] + self.Level = 1 # first level include file + + def GetTotalLines(self): + TotalLines = self.InsertAdjust + len(self.FileLinesList) + + for Profile in self.IncludeFileList: + TotalLines += Profile.GetTotalLines() + + return TotalLines + + def IsLineInFile(self, Line): + if Line >= self.InsertStartLineNumber and Line < self.InsertStartLineNumber + self.GetTotalLines(): + return True + + return False + + def GetLineInFile(self, Line): + if not self.IsLineInFile (Line): + return (self.FileName, -1) + + InsertedLines = self.InsertStartLineNumber + + for Profile in self.IncludeFileList: + if Profile.IsLineInFile(Line): + return Profile.GetLineInFile(Line) + elif Line >= Profile.InsertStartLineNumber: + InsertedLines += Profile.GetTotalLines() + + return (self.FileName, Line - InsertedLines + 1) + +## The FDF content class that used to record file data when parsing FDF +# +# May raise Exception when opening file. +# +class FileProfile: + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName): + self.FileLinesList = [] + try: + with open(FileName, "r") as fsock: + self.FileLinesList = fsock.readlines() + + except: + EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName) + + self.FileName = FileName + self.PcdDict = OrderedDict() + self.PcdLocalDict = OrderedDict() + self.InfList = [] + self.InfDict = {'ArchTBD':[]} + # ECC will use this Dict and List information + self.PcdFileLineDict = {} + self.InfFileLineList = [] + + self.FdDict = {} + self.FdNameNotSet = False + self.FvDict = {} + self.CapsuleDict = {} + self.RuleDict = {} + self.OptRomDict = {} + self.FmpPayloadDict = {} + +## The syntax parser for FDF +# +# PreprocessFile method should be called prior to ParseFile +# CycleReferenceCheck method can detect cycles in FDF contents +# +# GetNext*** procedures mean these procedures will get next token first, then make judgement. +# Get*** procedures mean these procedures will make judgement on current token only. +# +class FdfParser: + ## The constructor + # + # @param self The object pointer + # @param FileName The file that to be parsed + # + def __init__(self, FileName): + self.Profile = FileProfile(FileName) + self.FileName = FileName + self.CurrentLineNumber = 1 + self.CurrentOffsetWithinLine = 0 + self.CurrentFdName = None + self.CurrentFvName = None + self._Token = "" + self._SkippedChars = "" + GlobalData.gFdfParser = self + + # Used to section info + self._CurSection = [] + # Key: [section name, UI name, arch] + # Value: {MACRO_NAME: MACRO_VALUE} + self._MacroDict = tdict(True, 3) + self._PcdDict = OrderedDict() + + self._WipeOffArea = [] + if GenFdsGlobalVariable.WorkSpaceDir == '': + GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE") + + ## _SkipWhiteSpace() method + # + # Skip white spaces from current char. + # + # @param self The object pointer + # + def _SkipWhiteSpace(self): + while not self._EndOfFile(): + if self._CurrentChar() in {TAB_PRINTCHAR_NUL, T_CHAR_CR, TAB_LINE_BREAK, TAB_SPACE_SPLIT, T_CHAR_TAB}: + self._SkippedChars += str(self._CurrentChar()) + self._GetOneChar() + else: + return + return + + ## _EndOfFile() method + # + # Judge current buffer pos is at file end + # + # @param self The object pointer + # @retval True Current File buffer position is at file end + # @retval False Current File buffer position is NOT at file end + # + def _EndOfFile(self): + NumberOfLines = len(self.Profile.FileLinesList) + SizeOfLastLine = len(self.Profile.FileLinesList[-1]) + if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1: + return True + if self.CurrentLineNumber > NumberOfLines: + return True + return False + + ## _EndOfLine() method + # + # Judge current buffer pos is at line end + # + # @param self The object pointer + # @retval True Current File buffer position is at line end + # @retval False Current File buffer position is NOT at line end + # + def _EndOfLine(self): + if self.CurrentLineNumber > len(self.Profile.FileLinesList): + return True + SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) + if self.CurrentOffsetWithinLine >= SizeOfCurrentLine: + return True + return False + + ## Rewind() method + # + # Reset file data buffer to the initial state + # + # @param self The object pointer + # @param DestLine Optional new destination line number. + # @param DestOffset Optional new destination offset. + # + def Rewind(self, DestLine = 1, DestOffset = 0): + self.CurrentLineNumber = DestLine + self.CurrentOffsetWithinLine = DestOffset + + ## _UndoOneChar() method + # + # Go back one char in the file buffer + # + # @param self The object pointer + # @retval True Successfully go back one char + # @retval False Not able to go back one char as file beginning reached + # + def _UndoOneChar(self): + if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0: + return False + elif self.CurrentOffsetWithinLine == 0: + self.CurrentLineNumber -= 1 + self.CurrentOffsetWithinLine = len(self._CurrentLine()) - 1 + else: + self.CurrentOffsetWithinLine -= 1 + return True + + ## _GetOneChar() method + # + # Move forward one char in the file buffer + # + # @param self The object pointer + # + def _GetOneChar(self): + if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1: + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + else: + self.CurrentOffsetWithinLine += 1 + + ## _CurrentChar() method + # + # Get the char pointed to by the file buffer pointer + # + # @param self The object pointer + # @retval Char Current char + # + def _CurrentChar(self): + return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] + + ## _NextChar() method + # + # Get the one char pass the char pointed to by the file buffer pointer + # + # @param self The object pointer + # @retval Char Next char + # + def _NextChar(self): + if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1: + return self.Profile.FileLinesList[self.CurrentLineNumber][0] + return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1] + + ## _SetCurrentCharValue() method + # + # Modify the value of current char + # + # @param self The object pointer + # @param Value The new value of current char + # + def _SetCurrentCharValue(self, Value): + self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value + + ## _CurrentLine() method + # + # Get the list that contains current line contents + # + # @param self The object pointer + # @retval List current line contents + # + def _CurrentLine(self): + return self.Profile.FileLinesList[self.CurrentLineNumber - 1] + + def _StringToList(self): + self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList] + if not self.Profile.FileLinesList: + EdkLogger.error('FdfParser', FILE_READ_FAILURE, 'The file is empty!', File=self.FileName) + self.Profile.FileLinesList[-1].append(' ') + + def _ReplaceFragment(self, StartPos, EndPos, Value = ' '): + if StartPos[0] == EndPos[0]: + Offset = StartPos[1] + while Offset <= EndPos[1]: + self.Profile.FileLinesList[StartPos[0]][Offset] = Value + Offset += 1 + return + + Offset = StartPos[1] + while self.Profile.FileLinesList[StartPos[0]][Offset] not in CR_LB_SET: + self.Profile.FileLinesList[StartPos[0]][Offset] = Value + Offset += 1 + + Line = StartPos[0] + while Line < EndPos[0]: + Offset = 0 + while self.Profile.FileLinesList[Line][Offset] not in CR_LB_SET: + self.Profile.FileLinesList[Line][Offset] = Value + Offset += 1 + Line += 1 + + Offset = 0 + while Offset <= EndPos[1]: + self.Profile.FileLinesList[EndPos[0]][Offset] = Value + Offset += 1 + + def _SetMacroValue(self, Macro, Value): + if not self._CurSection: + return + + MacroDict = {} + if not self._MacroDict[self._CurSection[0], self._CurSection[1], self._CurSection[2]]: + self._MacroDict[self._CurSection[0], self._CurSection[1], self._CurSection[2]] = MacroDict + else: + MacroDict = self._MacroDict[self._CurSection[0], self._CurSection[1], self._CurSection[2]] + MacroDict[Macro] = Value + + def _GetMacroValue(self, Macro): + # Highest priority + if Macro in GlobalData.gCommandLineDefines: + return GlobalData.gCommandLineDefines[Macro] + if Macro in GlobalData.gGlobalDefines: + return GlobalData.gGlobalDefines[Macro] + + if self._CurSection: + MacroDict = self._MacroDict[ + self._CurSection[0], + self._CurSection[1], + self._CurSection[2] + ] + if MacroDict and Macro in MacroDict: + return MacroDict[Macro] + + # Lowest priority + if Macro in GlobalData.gPlatformDefines: + return GlobalData.gPlatformDefines[Macro] + return None + + def _SectionHeaderParser(self, Section): + # [Defines] + # [FD.UiName]: use dummy instead if UI name is optional + # [FV.UiName] + # [Capsule.UiName] + # [Rule]: don't take rule section into account, macro is not allowed in this section + # [OptionRom.DriverName] + self._CurSection = [] + Section = Section.strip()[1:-1].upper().replace(' ', '').strip(TAB_SPLIT) + ItemList = Section.split(TAB_SPLIT) + Item = ItemList[0] + if Item == '' or Item == 'RULE': + return + + if Item == TAB_COMMON_DEFINES.upper(): + self._CurSection = [TAB_COMMON, TAB_COMMON, TAB_COMMON] + elif len(ItemList) > 1: + self._CurSection = [ItemList[0], ItemList[1], TAB_COMMON] + elif len(ItemList) > 0: + self._CurSection = [ItemList[0], 'DUMMY', TAB_COMMON] + + ## PreprocessFile() method + # + # Preprocess file contents, replace comments with spaces. + # In the end, rewind the file buffer pointer to the beginning + # BUGBUG: No !include statement processing contained in this procedure + # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1] + # + # @param self The object pointer + # + def PreprocessFile(self): + self.Rewind() + InComment = False + DoubleSlashComment = False + HashComment = False + # HashComment in quoted string " " is ignored. + InString = False + + while not self._EndOfFile(): + + if self._CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment: + InString = not InString + # meet new line, then no longer in a comment for // and '#' + if self._CurrentChar() == TAB_LINE_BREAK: + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + if InComment and DoubleSlashComment: + InComment = False + DoubleSlashComment = False + if InComment and HashComment: + InComment = False + HashComment = False + # check for */ comment end + elif InComment and not DoubleSlashComment and not HashComment and self._CurrentChar() == TAB_STAR and self._NextChar() == TAB_BACK_SLASH: + self._SetCurrentCharValue(TAB_SPACE_SPLIT) + self._GetOneChar() + self._SetCurrentCharValue(TAB_SPACE_SPLIT) + self._GetOneChar() + InComment = False + # set comments to spaces + elif InComment: + self._SetCurrentCharValue(TAB_SPACE_SPLIT) + self._GetOneChar() + # check for // comment + elif self._CurrentChar() == TAB_BACK_SLASH and self._NextChar() == TAB_BACK_SLASH and not self._EndOfLine(): + InComment = True + DoubleSlashComment = True + # check for '#' comment + elif self._CurrentChar() == TAB_COMMENT_SPLIT and not self._EndOfLine() and not InString: + InComment = True + HashComment = True + # check for /* comment start + elif self._CurrentChar() == TAB_BACK_SLASH and self._NextChar() == TAB_STAR: + self._SetCurrentCharValue(TAB_SPACE_SPLIT) + self._GetOneChar() + self._SetCurrentCharValue(TAB_SPACE_SPLIT) + self._GetOneChar() + InComment = True + else: + self._GetOneChar() + + # restore from ListOfList to ListOfString + self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList] + self.Rewind() + + ## PreprocessIncludeFile() method + # + # Preprocess file contents, replace !include statements with file contents. + # In the end, rewind the file buffer pointer to the beginning + # + # @param self The object pointer + # + def PreprocessIncludeFile(self): + # nested include support + Processed = False + MacroDict = {} + while self._GetNextToken(): + + if self._Token == TAB_DEFINE: + if not self._GetNextToken(): + raise Warning.Expected("Macro name", self.FileName, self.CurrentLineNumber) + Macro = self._Token + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + Value = self._GetExpression() + MacroDict[Macro] = Value + + elif self._Token == TAB_INCLUDE: + Processed = True + IncludeLine = self.CurrentLineNumber + IncludeOffset = self.CurrentOffsetWithinLine - len(TAB_INCLUDE) + if not self._GetNextToken(): + raise Warning.Expected("include file name", self.FileName, self.CurrentLineNumber) + IncFileName = self._Token + PreIndex = 0 + StartPos = IncFileName.find('$(', PreIndex) + EndPos = IncFileName.find(')', StartPos+2) + while StartPos != -1 and EndPos != -1: + Macro = IncFileName[StartPos+2: EndPos] + MacroVal = self._GetMacroValue(Macro) + if not MacroVal: + if Macro in MacroDict: + MacroVal = MacroDict[Macro] + if MacroVal is not None: + IncFileName = IncFileName.replace('$(' + Macro + ')', MacroVal, 1) + if MacroVal.find('$(') != -1: + PreIndex = StartPos + else: + PreIndex = StartPos + len(MacroVal) + else: + raise Warning("The Macro %s is not defined" %Macro, self.FileName, self.CurrentLineNumber) + StartPos = IncFileName.find('$(', PreIndex) + EndPos = IncFileName.find(')', StartPos+2) + + IncludedFile = NormPath(IncFileName) + # + # First search the include file under the same directory as FDF file + # + IncludedFile1 = PathClass(IncludedFile, os.path.dirname(self.FileName)) + ErrorCode = IncludedFile1.Validate()[0] + if ErrorCode != 0: + # + # Then search the include file under the same directory as DSC file + # + PlatformDir = '' + if GenFdsGlobalVariable.ActivePlatform: + PlatformDir = GenFdsGlobalVariable.ActivePlatform.Dir + elif GlobalData.gActivePlatform: + PlatformDir = GlobalData.gActivePlatform.MetaFile.Dir + IncludedFile1 = PathClass(IncludedFile, PlatformDir) + ErrorCode = IncludedFile1.Validate()[0] + if ErrorCode != 0: + # + # Also search file under the WORKSPACE directory + # + IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace) + ErrorCode = IncludedFile1.Validate()[0] + if ErrorCode != 0: + raise Warning("The include file does not exist under below directories: \n%s\n%s\n%s\n"%(os.path.dirname(self.FileName), PlatformDir, GlobalData.gWorkspace), + self.FileName, self.CurrentLineNumber) + + if not IsValidInclude (IncludedFile1.Path, self.CurrentLineNumber): + raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1.Path), self.FileName, self.CurrentLineNumber) + + IncFileProfile = IncludeFileProfile(IncludedFile1.Path) + + CurrentLine = self.CurrentLineNumber + CurrentOffset = self.CurrentOffsetWithinLine + # list index of the insertion, note that line number is 'CurrentLine + 1' + InsertAtLine = CurrentLine + ParentProfile = GetParentAtLine (CurrentLine) + if ParentProfile is not None: + ParentProfile.IncludeFileList.insert(0, IncFileProfile) + IncFileProfile.Level = ParentProfile.Level + 1 + IncFileProfile.InsertStartLineNumber = InsertAtLine + 1 + # deal with remaining portions after "!include filename", if exists. + if self._GetNextToken(): + if self.CurrentLineNumber == CurrentLine: + RemainingLine = self._CurrentLine()[CurrentOffset:] + self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine) + IncFileProfile.InsertAdjust += 1 + self.CurrentLineNumber += 1 + self.CurrentOffsetWithinLine = 0 + + for Line in IncFileProfile.FileLinesList: + self.Profile.FileLinesList.insert(InsertAtLine, Line) + self.CurrentLineNumber += 1 + InsertAtLine += 1 + + # reversely sorted to better determine error in file + AllIncludeFileList.insert(0, IncFileProfile) + + # comment out the processed include file statement + TempList = list(self.Profile.FileLinesList[IncludeLine - 1]) + TempList.insert(IncludeOffset, TAB_COMMENT_SPLIT) + self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList) + if Processed: # Nested and back-to-back support + self.Rewind(DestLine = IncFileProfile.InsertStartLineNumber - 1) + Processed = False + # Preprocess done. + self.Rewind() + + @staticmethod + def _GetIfListCurrentItemStat(IfList): + if len(IfList) == 0: + return True + + for Item in IfList: + if Item[1] == False: + return False + + return True + + ## PreprocessConditionalStatement() method + # + # Preprocess conditional statement. + # In the end, rewind the file buffer pointer to the beginning + # + # @param self The object pointer + # + def PreprocessConditionalStatement(self): + # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined] + IfList = [] + RegionLayoutLine = 0 + ReplacedLine = -1 + while self._GetNextToken(): + # Determine section name and the location dependent macro + if self._GetIfListCurrentItemStat(IfList): + if self._Token.startswith(TAB_SECTION_START): + Header = self._Token + if not self._Token.endswith(TAB_SECTION_END): + self._SkipToToken(TAB_SECTION_END) + Header += self._SkippedChars + if Header.find('$(') != -1: + raise Warning("macro cannot be used in section header", self.FileName, self.CurrentLineNumber) + self._SectionHeaderParser(Header) + continue + # Replace macros except in RULE section or out of section + elif self._CurSection and ReplacedLine != self.CurrentLineNumber: + ReplacedLine = self.CurrentLineNumber + self._UndoToken() + CurLine = self.Profile.FileLinesList[ReplacedLine - 1] + PreIndex = 0 + StartPos = CurLine.find('$(', PreIndex) + EndPos = CurLine.find(')', StartPos+2) + while StartPos != -1 and EndPos != -1 and self._Token not in {TAB_IF_DEF, TAB_IF_N_DEF, TAB_IF, TAB_ELSE_IF}: + MacroName = CurLine[StartPos+2: EndPos] + MacroValue = self._GetMacroValue(MacroName) + if MacroValue is not None: + CurLine = CurLine.replace('$(' + MacroName + ')', MacroValue, 1) + if MacroValue.find('$(') != -1: + PreIndex = StartPos + else: + PreIndex = StartPos + len(MacroValue) + else: + PreIndex = EndPos + 1 + StartPos = CurLine.find('$(', PreIndex) + EndPos = CurLine.find(')', StartPos+2) + self.Profile.FileLinesList[ReplacedLine - 1] = CurLine + continue + + if self._Token == TAB_DEFINE: + if self._GetIfListCurrentItemStat(IfList): + if not self._CurSection: + raise Warning("macro cannot be defined in Rule section or out of section", self.FileName, self.CurrentLineNumber) + DefineLine = self.CurrentLineNumber - 1 + DefineOffset = self.CurrentOffsetWithinLine - len(TAB_DEFINE) + if not self._GetNextToken(): + raise Warning.Expected("Macro name", self.FileName, self.CurrentLineNumber) + Macro = self._Token + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + Value = self._GetExpression() + self._SetMacroValue(Macro, Value) + self._WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + elif self._Token == 'SET': + if not self._GetIfListCurrentItemStat(IfList): + continue + SetLine = self.CurrentLineNumber - 1 + SetOffset = self.CurrentOffsetWithinLine - len('SET') + PcdPair = self._GetNextPcdSettings() + PcdName = "%s.%s" % (PcdPair[1], PcdPair[0]) + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + Value = self._GetExpression() + Value = self._EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True) + + self._PcdDict[PcdName] = Value + + self.Profile.PcdDict[PcdPair] = Value + self.SetPcdLocalation(PcdPair) + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple + + self._WipeOffArea.append(((SetLine, SetOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + elif self._Token in {TAB_IF_DEF, TAB_IF_N_DEF, TAB_IF}: + IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self._Token)) + IfList.append([IfStartPos, None, None]) + + CondLabel = self._Token + Expression = self._GetExpression() + + if CondLabel == TAB_IF: + ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval') + else: + ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in') + if CondLabel == TAB_IF_N_DEF: + ConditionSatisfied = not ConditionSatisfied + + BranchDetermined = ConditionSatisfied + IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined] + if ConditionSatisfied: + self._WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + elif self._Token in {TAB_ELSE_IF, TAB_ELSE}: + ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self._Token)) + if len(IfList) <= 0: + raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber) + + if IfList[-1][1]: + IfList[-1] = [ElseStartPos, False, True] + self._WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + else: + self._WipeOffArea.append((IfList[-1][0], ElseStartPos)) + IfList[-1] = [ElseStartPos, True, IfList[-1][2]] + if self._Token == TAB_ELSE_IF: + Expression = self._GetExpression() + ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval') + IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]] + + if IfList[-1][1]: + if IfList[-1][2]: + IfList[-1][1] = False + else: + IfList[-1][2] = True + self._WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + elif self._Token == '!endif': + if len(IfList) <= 0: + raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber) + if IfList[-1][1]: + self._WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + else: + self._WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1))) + + IfList.pop() + elif not IfList: # Don't use PCDs inside conditional directive + if self.CurrentLineNumber <= RegionLayoutLine: + # Don't try the same line twice + continue + SetPcd = ShortcutPcdPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) + if SetPcd: + self._PcdDict[SetPcd.group('name')] = SetPcd.group('value') + RegionLayoutLine = self.CurrentLineNumber + continue + RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) + if not RegionSize: + RegionLayoutLine = self.CurrentLineNumber + continue + RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber]) + if not RegionSizeGuid: + RegionLayoutLine = self.CurrentLineNumber + 1 + continue + self._PcdDict[RegionSizeGuid.group('base')] = RegionSize.group('base') + self._PcdDict[RegionSizeGuid.group('size')] = RegionSize.group('size') + RegionLayoutLine = self.CurrentLineNumber + 1 + + if IfList: + raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber) + self.Rewind() + + def _CollectMacroPcd(self): + MacroDict = {} + + # PCD macro + MacroDict.update(GlobalData.gPlatformPcds) + MacroDict.update(self._PcdDict) + + # Lowest priority + MacroDict.update(GlobalData.gPlatformDefines) + + if self._CurSection: + # Defines macro + ScopeMacro = self._MacroDict[TAB_COMMON, TAB_COMMON, TAB_COMMON] + if ScopeMacro: + MacroDict.update(ScopeMacro) + + # Section macro + ScopeMacro = self._MacroDict[ + self._CurSection[0], + self._CurSection[1], + self._CurSection[2] + ] + if ScopeMacro: + MacroDict.update(ScopeMacro) + + MacroDict.update(GlobalData.gGlobalDefines) + MacroDict.update(GlobalData.gCommandLineDefines) + for Item in GlobalData.BuildOptionPcd: + if isinstance(Item, tuple): + continue + PcdName, TmpValue = Item.split(TAB_EQUAL_SPLIT) + TmpValue = BuildOptionValue(TmpValue, {}) + MacroDict[PcdName.strip()] = TmpValue + # Highest priority + + return MacroDict + + def _EvaluateConditional(self, Expression, Line, Op = None, Value = None): + MacroPcdDict = self._CollectMacroPcd() + if Op == 'eval': + try: + if Value: + return ValueExpression(Expression, MacroPcdDict)(True) + else: + return ValueExpression(Expression, MacroPcdDict)() + except WrnExpression as Excpt: + # + # Catch expression evaluation warning here. We need to report + # the precise number of line and return the evaluation result + # + EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt), + File=self.FileName, ExtraData=self._CurrentLine(), + Line=Line) + return Excpt.result + except Exception as Excpt: + if hasattr(Excpt, 'Pcd'): + if Excpt.Pcd in GlobalData.gPlatformOtherPcds: + Info = GlobalData.gPlatformOtherPcds[Excpt.Pcd] + raise Warning("Cannot use this PCD (%s) in an expression as" + " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section" + " of the DSC file (%s), and it is currently defined in this section:" + " %s, line #: %d." % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE'], Info[0], Info[1]), + self.FileName, Line) + else: + raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE']), + self.FileName, Line) + else: + raise Warning(str(Excpt), self.FileName, Line) + else: + if Expression.startswith('$(') and Expression[-1] == ')': + Expression = Expression[2:-1] + return Expression in MacroPcdDict + + ## _IsToken() method + # + # Check whether input string is found from current char position along + # If found, the string value is put into self._Token + # + # @param self The object pointer + # @param String The string to search + # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive + # @retval True Successfully find string, file buffer pointer moved forward + # @retval False Not able to find string, file buffer pointer not changed + # + def _IsToken(self, String, IgnoreCase = False): + self._SkipWhiteSpace() + + # Only consider the same line, no multi-line token allowed + StartPos = self.CurrentOffsetWithinLine + index = -1 + if IgnoreCase: + index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(String.upper()) + else: + index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(String) + if index == 0: + self.CurrentOffsetWithinLine += len(String) + self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine] + return True + return False + + ## _IsKeyword() method + # + # Check whether input keyword is found from current char position along, whole word only! + # If found, the string value is put into self._Token + # + # @param self The object pointer + # @param Keyword The string to search + # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive + # @retval True Successfully find string, file buffer pointer moved forward + # @retval False Not able to find string, file buffer pointer not changed + # + def _IsKeyword(self, KeyWord, IgnoreCase = False): + self._SkipWhiteSpace() + + # Only consider the same line, no multi-line token allowed + StartPos = self.CurrentOffsetWithinLine + index = -1 + if IgnoreCase: + index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(KeyWord.upper()) + else: + index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(KeyWord) + if index == 0: + followingChar = self._CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)] + if not str(followingChar).isspace() and followingChar not in SEPARATORS: + return False + self.CurrentOffsetWithinLine += len(KeyWord) + self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine] + return True + return False + + def _GetExpression(self): + Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1] + Index = len(Line) - 1 + while Line[Index] in CR_LB_SET: + Index -= 1 + ExpressionString = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:Index+1] + self.CurrentOffsetWithinLine += len(ExpressionString) + ExpressionString = ExpressionString.strip() + return ExpressionString + + ## _GetNextWord() method + # + # Get next C name from file lines + # If found, the string value is put into self._Token + # + # @param self The object pointer + # @retval True Successfully find a C name string, file buffer pointer moved forward + # @retval False Not able to find a C name string, file buffer pointer not changed + # + def _GetNextWord(self): + self._SkipWhiteSpace() + if self._EndOfFile(): + return False + + TempChar = self._CurrentChar() + StartPos = self.CurrentOffsetWithinLine + if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_': + self._GetOneChar() + while not self._EndOfLine(): + TempChar = self._CurrentChar() + if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \ + or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-': + self._GetOneChar() + + else: + break + + self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine] + return True + + return False + + def _GetNextPcdWord(self): + self._SkipWhiteSpace() + if self._EndOfFile(): + return False + + TempChar = self._CurrentChar() + StartPos = self.CurrentOffsetWithinLine + if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_' or TempChar == TAB_SECTION_START or TempChar == TAB_SECTION_END: + self._GetOneChar() + while not self._EndOfLine(): + TempChar = self._CurrentChar() + if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \ + or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-' or TempChar == TAB_SECTION_START or TempChar == TAB_SECTION_END: + self._GetOneChar() + + else: + break + + self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine] + return True + + return False + + ## _GetNextToken() method + # + # Get next token unit before a separator + # If found, the string value is put into self._Token + # + # @param self The object pointer + # @retval True Successfully find a token unit, file buffer pointer moved forward + # @retval False Not able to find a token unit, file buffer pointer not changed + # + def _GetNextToken(self): + # Skip leading spaces, if exist. + self._SkipWhiteSpace() + if self._EndOfFile(): + return False + # Record the token start position, the position of the first non-space char. + StartPos = self.CurrentOffsetWithinLine + StartLine = self.CurrentLineNumber + while StartLine == self.CurrentLineNumber: + TempChar = self._CurrentChar() + # Try to find the end char that is not a space and not in separator tuple. + # That is, when we got a space or any char in the tuple, we got the end of token. + if not str(TempChar).isspace() and TempChar not in SEPARATORS: + self._GetOneChar() + # if we happen to meet a separator as the first char, we must proceed to get it. + # That is, we get a token that is a separator char. normally it is the boundary of other tokens. + elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPARATORS: + self._GetOneChar() + break + else: + break +# else: +# return False + + EndPos = self.CurrentOffsetWithinLine + if self.CurrentLineNumber != StartLine: + EndPos = len(self.Profile.FileLinesList[StartLine-1]) + self._Token = self.Profile.FileLinesList[StartLine-1][StartPos: EndPos] + if self._Token.lower() in {TAB_IF, TAB_END_IF, TAB_ELSE_IF, TAB_ELSE, TAB_IF_DEF, TAB_IF_N_DEF, TAB_ERROR, TAB_INCLUDE}: + self._Token = self._Token.lower() + if StartPos != self.CurrentOffsetWithinLine: + return True + else: + return False + + ## _GetNextGuid() method + # + # Get next token unit before a separator + # If found, the GUID string is put into self._Token + # + # @param self The object pointer + # @retval True Successfully find a registry format GUID, file buffer pointer moved forward + # @retval False Not able to find a registry format GUID, file buffer pointer not changed + # + def _GetNextGuid(self): + if not self._GetNextToken(): + return False + if GlobalData.gGuidPattern.match(self._Token) is not None: + return True + elif self._Token in GlobalData.gGuidDict: + return True + else: + self._UndoToken() + return False + + @staticmethod + def _Verify(Name, Value, Scope): + # value verification only applies to numeric values. + if Scope not in TAB_PCD_NUMERIC_TYPES: + return + + ValueNumber = 0 + try: + ValueNumber = int(Value, 0) + except: + EdkLogger.error("FdfParser", FORMAT_INVALID, "The value is not valid dec or hex number for %s." % Name) + if ValueNumber < 0: + EdkLogger.error("FdfParser", FORMAT_INVALID, "The value can't be set to negative value for %s." % Name) + if ValueNumber > MAX_VAL_TYPE[Scope]: + EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name) + return True + + ## _UndoToken() method + # + # Go back one token unit in file buffer + # + # @param self The object pointer + # + def _UndoToken(self): + self._UndoOneChar() + while self._CurrentChar().isspace(): + if not self._UndoOneChar(): + self._GetOneChar() + return + + + StartPos = self.CurrentOffsetWithinLine + CurrentLine = self.CurrentLineNumber + while CurrentLine == self.CurrentLineNumber: + + TempChar = self._CurrentChar() + # Try to find the end char that is not a space and not in separator tuple. + # That is, when we got a space or any char in the tuple, we got the end of token. + if not str(TempChar).isspace() and not TempChar in SEPARATORS: + if not self._UndoOneChar(): + return + # if we happen to meet a separator as the first char, we must proceed to get it. + # That is, we get a token that is a separator char. normally it is the boundary of other tokens. + elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPARATORS: + return + else: + break + + self._GetOneChar() + + ## _GetNextHexNumber() method + # + # Get next HEX data before a separator + # If found, the HEX data is put into self._Token + # + # @param self The object pointer + # @retval True Successfully find a HEX data, file buffer pointer moved forward + # @retval False Not able to find a HEX data, file buffer pointer not changed + # + def _GetNextHexNumber(self): + if not self._GetNextToken(): + return False + if GlobalData.gHexPatternAll.match(self._Token): + return True + else: + self._UndoToken() + return False + + ## _GetNextDecimalNumber() method + # + # Get next decimal data before a separator + # If found, the decimal data is put into self._Token + # + # @param self The object pointer + # @retval True Successfully find a decimal data, file buffer pointer moved forward + # @retval False Not able to find a decimal data, file buffer pointer not changed + # + def _GetNextDecimalNumber(self): + if not self._GetNextToken(): + return False + if self._Token.isdigit(): + return True + else: + self._UndoToken() + return False + + def _GetNextPcdSettings(self): + if not self._GetNextWord(): + raise Warning.Expected("<PcdTokenSpaceCName>", self.FileName, self.CurrentLineNumber) + pcdTokenSpaceCName = self._Token + + if not self._IsToken(TAB_SPLIT): + raise Warning.Expected(".", self.FileName, self.CurrentLineNumber) + + if not self._GetNextWord(): + raise Warning.Expected("<PcdCName>", self.FileName, self.CurrentLineNumber) + pcdCName = self._Token + + Fields = [] + while self._IsToken(TAB_SPLIT): + if not self._GetNextPcdWord(): + raise Warning.Expected("Pcd Fields", self.FileName, self.CurrentLineNumber) + Fields.append(self._Token) + + return (pcdCName, pcdTokenSpaceCName,TAB_SPLIT.join(Fields)) + + ## _GetStringData() method + # + # Get string contents quoted in "" + # If found, the decimal data is put into self._Token + # + # @param self The object pointer + # @retval True Successfully find a string data, file buffer pointer moved forward + # @retval False Not able to find a string data, file buffer pointer not changed + # + def _GetStringData(self): + QuoteToUse = None + if self._Token.startswith(T_CHAR_DOUBLE_QUOTE) or self._Token.startswith("L\""): + QuoteToUse = T_CHAR_DOUBLE_QUOTE + elif self._Token.startswith(T_CHAR_SINGLE_QUOTE) or self._Token.startswith("L\'"): + QuoteToUse = T_CHAR_SINGLE_QUOTE + else: + return False + + self._UndoToken() + self._SkipToToken(QuoteToUse) + currentLineNumber = self.CurrentLineNumber + + if not self._SkipToToken(QuoteToUse): + raise Warning(QuoteToUse, self.FileName, self.CurrentLineNumber) + if currentLineNumber != self.CurrentLineNumber: + raise Warning(QuoteToUse, self.FileName, self.CurrentLineNumber) + self._Token = self._SkippedChars.rstrip(QuoteToUse) + return True + + ## _SkipToToken() method + # + # Search forward in file buffer for the string + # The skipped chars are put into self._SkippedChars + # + # @param self The object pointer + # @param String The string to search + # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive + # @retval True Successfully find the string, file buffer pointer moved forward + # @retval False Not able to find the string, file buffer pointer not changed + # + def _SkipToToken(self, String, IgnoreCase = False): + StartPos = self.GetFileBufferPos() + + self._SkippedChars = "" + while not self._EndOfFile(): + index = -1 + if IgnoreCase: + index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(String.upper()) + else: + index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(String) + if index == 0: + self.CurrentOffsetWithinLine += len(String) + self._SkippedChars += String + return True + self._SkippedChars += str(self._CurrentChar()) + self._GetOneChar() + + self.SetFileBufferPos(StartPos) + self._SkippedChars = "" + return False + + ## GetFileBufferPos() method + # + # Return the tuple of current line and offset within the line + # + # @param self The object pointer + # @retval Tuple Line number and offset pair + # + def GetFileBufferPos(self): + return (self.CurrentLineNumber, self.CurrentOffsetWithinLine) + + ## SetFileBufferPos() method + # + # Restore the file buffer position + # + # @param self The object pointer + # @param Pos The new file buffer position + # + def SetFileBufferPos(self, Pos): + (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos + + ## Preprocess() method + # + # Preprocess comment, conditional directive, include directive, replace macro. + # Exception will be raised if syntax error found + # + # @param self The object pointer + # + def Preprocess(self): + self._StringToList() + self.PreprocessFile() + self.PreprocessIncludeFile() + self._StringToList() + self.PreprocessFile() + self.PreprocessConditionalStatement() + self._StringToList() + for Pos in self._WipeOffArea: + self._ReplaceFragment(Pos[0], Pos[1]) + self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList] + + while self._GetDefines(): + pass + + ## ParseFile() method + # + # Parse the file profile buffer to extract fd, fv ... information + # Exception will be raised if syntax error found + # + # @param self The object pointer + # + def ParseFile(self): + try: + self.Preprocess() + self._GetError() + # + # Keep processing sections of the FDF until no new sections or a syntax error is found + # + while self._GetFd() or self._GetFv() or self._GetFmp() or self._GetCapsule() or self._GetRule() or self._GetOptionRom(): + pass + + except Warning as X: + self._UndoToken() + #'\n\tGot Token: \"%s\" from File %s\n' % (self._Token, FileLineTuple[0]) + \ + # At this point, the closest parent would be the included file itself + Profile = GetParentAtLine(X.OriginalLineNumber) + if Profile is not None: + X.Message += ' near line %d, column %d: %s' \ + % (X.LineNumber, 0, Profile.FileLinesList[X.LineNumber-1]) + else: + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + X.Message += ' near line %d, column %d: %s' \ + % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:].rstrip(TAB_LINE_BREAK).rstrip(T_CHAR_CR)) + raise + + ## SectionParser() method + # + # Parse the file section info + # Exception will be raised if syntax error found + # + # @param self The object pointer + # @param section The section string + + def SectionParser(self, section): + S = section.upper() + if not S.startswith("[DEFINES") and not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \ + and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM.") and not S.startswith('[FMPPAYLOAD.'): + raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self.FileName, self.CurrentLineNumber) + + ## _GetDefines() method + # + # Get Defines section contents and store its data into AllMacrosList + # + # @param self The object pointer + # @retval True Successfully find a Defines + # @retval False Not able to find a Defines + # + def _GetDefines(self): + if not self._GetNextToken(): + return False + + S = self._Token.upper() + if S.startswith(TAB_SECTION_START) and not S.startswith("[DEFINES"): + self.SectionParser(S) + self._UndoToken() + return False + + self._UndoToken() + if not self._IsToken("[DEFINES", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning.Expected("[DEFINES", self.FileName, self.CurrentLineNumber) + + if not self._IsToken(TAB_SECTION_END): + raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber) + + while self._GetNextWord(): + # handle the SET statement + if self._Token == 'SET': + self._UndoToken() + self._GetSetStatement(None) + continue + + Macro = self._Token + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken() or self._Token.startswith(TAB_SECTION_START): + raise Warning.Expected("MACRO value", self.FileName, self.CurrentLineNumber) + Value = self._Token + + return False + + ##_GetError() method + def _GetError(self): + #save the Current information + CurrentLine = self.CurrentLineNumber + CurrentOffset = self.CurrentOffsetWithinLine + while self._GetNextToken(): + if self._Token == TAB_ERROR: + EdkLogger.error('FdfParser', ERROR_STATEMENT, self._CurrentLine().replace(TAB_ERROR, '', 1), File=self.FileName, Line=self.CurrentLineNumber) + self.CurrentLineNumber = CurrentLine + self.CurrentOffsetWithinLine = CurrentOffset + + ## _GetFd() method + # + # Get FD section contents and store its data into FD dictionary of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a FD + # @retval False Not able to find a FD + # + def _GetFd(self): + if not self._GetNextToken(): + return False + + S = self._Token.upper() + if S.startswith(TAB_SECTION_START) and not S.startswith("[FD."): + if not S.startswith("[FV.") and not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \ + and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): + raise Warning("Unknown section", self.FileName, self.CurrentLineNumber) + self._UndoToken() + return False + + self._UndoToken() + if not self._IsToken("[FD.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning.Expected("[FD.]", self.FileName, self.CurrentLineNumber) + + FdName = self._GetUiName() + if FdName == "": + if len (self.Profile.FdDict) == 0: + FdName = GenFdsGlobalVariable.PlatformName + if FdName == "" and GlobalData.gActivePlatform: + FdName = GlobalData.gActivePlatform.PlatformName + self.Profile.FdNameNotSet = True + else: + raise Warning.Expected("FdName in [FD.] section", self.FileName, self.CurrentLineNumber) + self.CurrentFdName = FdName.upper() + + if self.CurrentFdName in self.Profile.FdDict: + raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber) + + if not self._IsToken(TAB_SECTION_END): + raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber) + + FdObj = FD() + FdObj.FdUiName = self.CurrentFdName + self.Profile.FdDict[self.CurrentFdName] = FdObj + + if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet: + raise Warning.Expected("all FDs have their name", self.FileName, self.CurrentLineNumber) + + Status = self._GetCreateFile(FdObj) + if not Status: + raise Warning("FD name error", self.FileName, self.CurrentLineNumber) + + while self._GetTokenStatements(FdObj): + pass + for Attr in ("BaseAddress", "Size", "ErasePolarity"): + if getattr(FdObj, Attr) is None: + self._GetNextToken() + raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber) + + if not FdObj.BlockSizeList: + FdObj.BlockSizeList.append((1, FdObj.Size, None)) + + self._GetDefineStatements(FdObj) + + self._GetSetStatements(FdObj) + + if not self._GetRegionLayout(FdObj): + raise Warning.Expected("region layout", self.FileName, self.CurrentLineNumber) + + while self._GetRegionLayout(FdObj): + pass + return True + + ## _GetUiName() method + # + # Return the UI name of a section + # + # @param self The object pointer + # @retval FdName UI name + # + def _GetUiName(self): + Name = "" + if self._GetNextWord(): + Name = self._Token + + return Name + + ## _GetCreateFile() method + # + # Return the output file name of object + # + # @param self The object pointer + # @param Obj object whose data will be stored in file + # @retval FdName UI name + # + def _GetCreateFile(self, Obj): + if self._IsKeyword("CREATE_FILE"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("file name", self.FileName, self.CurrentLineNumber) + + FileName = self._Token + Obj.CreateFileName = FileName + + return True + + def SetPcdLocalation(self,pcdpair): + self.Profile.PcdLocalDict[pcdpair] = (self.Profile.FileName,self.CurrentLineNumber) + + ## _GetTokenStatements() method + # + # Get token statements + # + # @param self The object pointer + # @param Obj for whom token statement is got + # + def _GetTokenStatements(self, Obj): + if self._IsKeyword("BaseAddress"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextHexNumber(): + raise Warning.Expected("Hex base address", self.FileName, self.CurrentLineNumber) + + Obj.BaseAddress = self._Token + + if self._IsToken(TAB_VALUE_SPLIT): + pcdPair = self._GetNextPcdSettings() + Obj.BaseAddressPcd = pcdPair + self.Profile.PcdDict[pcdPair] = Obj.BaseAddress + self.SetPcdLocalation(pcdPair) + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple + return True + + if self._IsKeyword("Size"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextHexNumber(): + raise Warning.Expected("Hex size", self.FileName, self.CurrentLineNumber) + + Size = self._Token + if self._IsToken(TAB_VALUE_SPLIT): + pcdPair = self._GetNextPcdSettings() + Obj.SizePcd = pcdPair + self.Profile.PcdDict[pcdPair] = Size + self.SetPcdLocalation(pcdPair) + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple + Obj.Size = int(Size, 0) + return True + + if self._IsKeyword("ErasePolarity"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("Erase Polarity", self.FileName, self.CurrentLineNumber) + + if not self._Token in {"1", "0"}: + raise Warning.Expected("1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber) + + Obj.ErasePolarity = self._Token + return True + + return self._GetBlockStatements(Obj) + + ## _GetAddressStatements() method + # + # Get address statements + # + # @param self The object pointer + # @param Obj for whom address statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def _GetAddressStatements(self, Obj): + if self._IsKeyword("BsBaseAddress"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextDecimalNumber() and not self._GetNextHexNumber(): + raise Warning.Expected("address", self.FileName, self.CurrentLineNumber) + + BsAddress = int(self._Token, 0) + Obj.BsBaseAddress = BsAddress + + if self._IsKeyword("RtBaseAddress"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextDecimalNumber() and not self._GetNextHexNumber(): + raise Warning.Expected("address", self.FileName, self.CurrentLineNumber) + + RtAddress = int(self._Token, 0) + Obj.RtBaseAddress = RtAddress + + ## _GetBlockStatements() method + # + # Get block statements + # + # @param self The object pointer + # @param Obj for whom block statement is got + # + def _GetBlockStatements(self, Obj): + IsBlock = False + while self._GetBlockStatement(Obj): + IsBlock = True + + Item = Obj.BlockSizeList[-1] + if Item[0] is None or Item[1] is None: + raise Warning.Expected("block statement", self.FileName, self.CurrentLineNumber) + return IsBlock + + ## _GetBlockStatement() method + # + # Get block statement + # + # @param self The object pointer + # @param Obj for whom block statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def _GetBlockStatement(self, Obj): + if not self._IsKeyword("BlockSize"): + return False + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextHexNumber() and not self._GetNextDecimalNumber(): + raise Warning.Expected("Hex or Integer block size", self.FileName, self.CurrentLineNumber) + + BlockSize = self._Token + BlockSizePcd = None + if self._IsToken(TAB_VALUE_SPLIT): + PcdPair = self._GetNextPcdSettings() + BlockSizePcd = PcdPair + self.Profile.PcdDict[PcdPair] = BlockSize + self.SetPcdLocalation(PcdPair) + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple + BlockSize = int(BlockSize, 0) + + BlockNumber = None + if self._IsKeyword("NumBlocks"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextDecimalNumber() and not self._GetNextHexNumber(): + raise Warning.Expected("block numbers", self.FileName, self.CurrentLineNumber) + + BlockNumber = int(self._Token, 0) + + Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd)) + return True + + ## _GetDefineStatements() method + # + # Get define statements + # + # @param self The object pointer + # @param Obj for whom define statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def _GetDefineStatements(self, Obj): + while self._GetDefineStatement(Obj): + pass + + ## _GetDefineStatement() method + # + # Get define statement + # + # @param self The object pointer + # @param Obj for whom define statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def _GetDefineStatement(self, Obj): + if self._IsKeyword(TAB_DEFINE): + self._GetNextToken() + Macro = self._Token + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("value", self.FileName, self.CurrentLineNumber) + + Value = self._Token + Macro = '$(' + Macro + ')' + Obj.DefineVarDict[Macro] = Value + return True + + return False + + ## _GetSetStatements() method + # + # Get set statements + # + # @param self The object pointer + # @param Obj for whom set statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def _GetSetStatements(self, Obj): + while self._GetSetStatement(Obj): + pass + + ## _GetSetStatement() method + # + # Get set statement + # + # @param self The object pointer + # @param Obj for whom set statement is got + # @retval True Successfully find + # @retval False Not able to find + # + def _GetSetStatement(self, Obj): + if self._IsKeyword("SET"): + PcdPair = self._GetNextPcdSettings() + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + Value = self._GetExpression() + Value = self._EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True) + + if Obj: + Obj.SetVarDict[PcdPair] = Value + self.Profile.PcdDict[PcdPair] = Value + self.SetPcdLocalation(PcdPair) + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple + return True + + return False + + ## _CalcRegionExpr(self) + # + # Calculate expression for offset or size of a region + # + # @return: None if invalid expression + # Calculated number if successfully + # + def _CalcRegionExpr(self): + StartPos = self.GetFileBufferPos() + Expr = '' + PairCount = 0 + while not self._EndOfFile(): + CurCh = self._CurrentChar() + if CurCh == '(': + PairCount += 1 + elif CurCh == ')': + PairCount -= 1 + + if CurCh in '|\r\n' and PairCount == 0: + break + Expr += CurCh + self._GetOneChar() + try: + return int( + ValueExpression(Expr, + self._CollectMacroPcd() + )(True), 0) + except Exception: + self.SetFileBufferPos(StartPos) + return None + + ## _GetRegionLayout() method + # + # Get region layout for FD + # + # @param self The object pointer + # @param theFd for whom region is got + # @retval True Successfully find + # @retval False Not able to find + # + def _GetRegionLayout(self, theFd): + Offset = self._CalcRegionExpr() + if Offset is None: + return False + + RegionObj = Region() + RegionObj.Offset = Offset + theFd.RegionList.append(RegionObj) + + if not self._IsToken(TAB_VALUE_SPLIT): + raise Warning.Expected("'|'", self.FileName, self.CurrentLineNumber) + + Size = self._CalcRegionExpr() + if Size is None: + raise Warning.Expected("Region Size", self.FileName, self.CurrentLineNumber) + RegionObj.Size = Size + + if not self._GetNextWord(): + return True + + if not self._Token in {"SET", BINARY_FILE_TYPE_FV, "FILE", "DATA", "CAPSULE", "INF"}: + # + # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]] + # Or it might be next region's offset described by an expression which starts with a PCD. + # PcdOffset[|PcdSize] or OffsetPcdExpression|Size + # + self._UndoToken() + IsRegionPcd = (RegionSizeGuidPattern.match(self._CurrentLine()[self.CurrentOffsetWithinLine:]) or + RegionOffsetPcdPattern.match(self._CurrentLine()[self.CurrentOffsetWithinLine:])) + if IsRegionPcd: + RegionObj.PcdOffset = self._GetNextPcdSettings() + self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + int(theFd.BaseAddress, 0)) + self.SetPcdLocalation(RegionObj.PcdOffset) + self._PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple + if self._IsToken(TAB_VALUE_SPLIT): + RegionObj.PcdSize = self._GetNextPcdSettings() + self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size + self.SetPcdLocalation(RegionObj.PcdSize) + self._PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple + + if not self._GetNextWord(): + return True + + if self._Token == "SET": + self._UndoToken() + self._GetSetStatements(RegionObj) + if not self._GetNextWord(): + return True + + elif self._Token == BINARY_FILE_TYPE_FV: + self._UndoToken() + self._GetRegionFvType(RegionObj) + + elif self._Token == "CAPSULE": + self._UndoToken() + self._GetRegionCapType(RegionObj) + + elif self._Token == "FILE": + self._UndoToken() + self._GetRegionFileType(RegionObj) + + elif self._Token == "INF": + self._UndoToken() + RegionObj.RegionType = "INF" + while self._IsKeyword("INF"): + self._UndoToken() + ffsInf = self._ParseInfStatement() + if not ffsInf: + break + RegionObj.RegionDataList.append(ffsInf) + + elif self._Token == "DATA": + self._UndoToken() + self._GetRegionDataType(RegionObj) + else: + self._UndoToken() + if self._GetRegionLayout(theFd): + return True + raise Warning("A valid region type was not found. " + "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred", + self.FileName, self.CurrentLineNumber) + + return True + + ## _GetRegionFvType() method + # + # Get region fv data for region + # + # @param self The object pointer + # @param RegionObj for whom region data is got + # + def _GetRegionFvType(self, RegionObj): + if not self._IsKeyword(BINARY_FILE_TYPE_FV): + raise Warning.Expected("'FV'", self.FileName, self.CurrentLineNumber) + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionType = BINARY_FILE_TYPE_FV + RegionObj.RegionDataList.append((self._Token).upper()) + + while self._IsKeyword(BINARY_FILE_TYPE_FV): + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionDataList.append((self._Token).upper()) + + ## _GetRegionCapType() method + # + # Get region capsule data for region + # + # @param self The object pointer + # @param RegionObj for whom region data is got + # + def _GetRegionCapType(self, RegionObj): + if not self._IsKeyword("CAPSULE"): + raise Warning.Expected("'CAPSULE'", self.FileName, self.CurrentLineNumber) + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("CAPSULE name", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionType = "CAPSULE" + RegionObj.RegionDataList.append(self._Token) + + while self._IsKeyword("CAPSULE"): + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("CAPSULE name", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionDataList.append(self._Token) + + ## _GetRegionFileType() method + # + # Get region file data for region + # + # @param self The object pointer + # @param RegionObj for whom region data is got + # + def _GetRegionFileType(self, RegionObj): + if not self._IsKeyword("FILE"): + raise Warning.Expected("'FILE'", self.FileName, self.CurrentLineNumber) + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionType = "FILE" + RegionObj.RegionDataList.append(self._Token) + + while self._IsKeyword("FILE"): + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("FILE name", self.FileName, self.CurrentLineNumber) + + RegionObj.RegionDataList.append(self._Token) + + ## _GetRegionDataType() method + # + # Get region array data for region + # + # @param self The object pointer + # @param RegionObj for whom region data is got + # + def _GetRegionDataType(self, RegionObj): + if not self._IsKeyword("DATA"): + raise Warning.Expected("Region Data type", self.FileName, self.CurrentLineNumber) + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._IsToken("{"): + raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber) + + if not self._GetNextHexNumber(): + raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber) + + if len(self._Token) > 18: + raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber) + + # convert hex string value to byte hex string array + AllString = self._Token + AllStrLen = len (AllString) + DataString = "" + while AllStrLen > 4: + DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + TAB_COMMA_SPLIT + AllStrLen = AllStrLen - 2 + DataString = DataString + AllString[:AllStrLen] + TAB_COMMA_SPLIT + + # byte value array + if len (self._Token) <= 4: + while self._IsToken(TAB_COMMA_SPLIT): + if not self._GetNextHexNumber(): + raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber) + if len(self._Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) + DataString += self._Token + DataString += TAB_COMMA_SPLIT + + if not self._IsToken(T_CHAR_BRACE_R): + raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber) + + DataString = DataString.rstrip(TAB_COMMA_SPLIT) + RegionObj.RegionType = "DATA" + RegionObj.RegionDataList.append(DataString) + + while self._IsKeyword("DATA"): + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._IsToken("{"): + raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber) + + if not self._GetNextHexNumber(): + raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber) + + if len(self._Token) > 18: + raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber) + + # convert hex string value to byte hex string array + AllString = self._Token + AllStrLen = len (AllString) + DataString = "" + while AllStrLen > 4: + DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + TAB_COMMA_SPLIT + AllStrLen = AllStrLen - 2 + DataString = DataString + AllString[:AllStrLen] + TAB_COMMA_SPLIT + + # byte value array + if len (self._Token) <= 4: + while self._IsToken(TAB_COMMA_SPLIT): + if not self._GetNextHexNumber(): + raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber) + if len(self._Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) + DataString += self._Token + DataString += TAB_COMMA_SPLIT + + if not self._IsToken(T_CHAR_BRACE_R): + raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber) + + DataString = DataString.rstrip(TAB_COMMA_SPLIT) + RegionObj.RegionDataList.append(DataString) + + ## _GetFv() method + # + # Get FV section contents and store its data into FV dictionary of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a FV + # @retval False Not able to find a FV + # + def _GetFv(self): + if not self._GetNextToken(): + return False + + S = self._Token.upper() + if S.startswith(TAB_SECTION_START) and not S.startswith("[FV."): + self.SectionParser(S) + self._UndoToken() + return False + + self._UndoToken() + if not self._IsToken("[FV.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning("Unknown Keyword '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + + FvName = self._GetUiName() + self.CurrentFvName = FvName.upper() + + if not self._IsToken(TAB_SECTION_END): + raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber) + + FvObj = FV(Name=self.CurrentFvName) + self.Profile.FvDict[self.CurrentFvName] = FvObj + + Status = self._GetCreateFile(FvObj) + if not Status: + raise Warning("FV name error", self.FileName, self.CurrentLineNumber) + + self._GetDefineStatements(FvObj) + + self._GetAddressStatements(FvObj) + + while True: + self._GetSetStatements(FvObj) + + if not (self._GetBlockStatement(FvObj) or self._GetFvBaseAddress(FvObj) or + self._GetFvForceRebase(FvObj) or self._GetFvAlignment(FvObj) or + self._GetFvAttributes(FvObj) or self._GetFvNameGuid(FvObj) or + self._GetFvExtEntryStatement(FvObj) or self._GetFvNameString(FvObj)): + break + + if FvObj.FvNameString == 'TRUE' and not FvObj.FvNameGuid: + raise Warning("FvNameString found but FvNameGuid was not found", self.FileName, self.CurrentLineNumber) + + self._GetAprioriSection(FvObj) + self._GetAprioriSection(FvObj) + + while True: + isInf = self._GetInfStatement(FvObj) + isFile = self._GetFileStatement(FvObj) + if not isInf and not isFile: + break + + return True + + ## _GetFvAlignment() method + # + # Get alignment for FV + # + # @param self The object pointer + # @param Obj for whom alignment is got + # @retval True Successfully find a alignment statement + # @retval False Not able to find a alignment statement + # + def _GetFvAlignment(self, Obj): + if not self._IsKeyword("FvAlignment"): + return False + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("alignment value", self.FileName, self.CurrentLineNumber) + + if self._Token.upper() not in {"1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \ + "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \ + "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \ + "1G", "2G"}: + raise Warning("Unknown alignment value '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + Obj.FvAlignment = self._Token + return True + + ## _GetFvBaseAddress() method + # + # Get BaseAddress for FV + # + # @param self The object pointer + # @param Obj for whom FvBaseAddress is got + # @retval True Successfully find a FvBaseAddress statement + # @retval False Not able to find a FvBaseAddress statement + # + def _GetFvBaseAddress(self, Obj): + if not self._IsKeyword("FvBaseAddress"): + return False + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("FV base address value", self.FileName, self.CurrentLineNumber) + + if not BaseAddrValuePattern.match(self._Token.upper()): + raise Warning("Unknown FV base address value '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + Obj.FvBaseAddress = self._Token + return True + + ## _GetFvForceRebase() method + # + # Get FvForceRebase for FV + # + # @param self The object pointer + # @param Obj for whom FvForceRebase is got + # @retval True Successfully find a FvForceRebase statement + # @retval False Not able to find a FvForceRebase statement + # + def _GetFvForceRebase(self, Obj): + if not self._IsKeyword("FvForceRebase"): + return False + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("FvForceRebase value", self.FileName, self.CurrentLineNumber) + + if self._Token.upper() not in {"TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"}: + raise Warning("Unknown FvForceRebase value '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + + if self._Token.upper() in {"TRUE", "1", "0X1", "0X01"}: + Obj.FvForceRebase = True + elif self._Token.upper() in {"FALSE", "0", "0X0", "0X00"}: + Obj.FvForceRebase = False + else: + Obj.FvForceRebase = None + + return True + + + ## _GetFvAttributes() method + # + # Get attributes for FV + # + # @param self The object pointer + # @param Obj for whom attribute is got + # @retval None + # + def _GetFvAttributes(self, FvObj): + IsWordToken = False + while self._GetNextWord(): + IsWordToken = True + name = self._Token + if name not in {"ERASE_POLARITY", "MEMORY_MAPPED", \ + "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \ + "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \ + "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \ + "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \ + "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"}: + self._UndoToken() + return False + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken() or self._Token.upper() not in {"TRUE", "FALSE", "1", "0"}: + raise Warning.Expected("TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber) + + FvObj.FvAttributeDict[name] = self._Token + + return IsWordToken + + ## _GetFvNameGuid() method + # + # Get FV GUID for FV + # + # @param self The object pointer + # @param Obj for whom GUID is got + # @retval None + # + def _GetFvNameGuid(self, FvObj): + if not self._IsKeyword("FvNameGuid"): + return False + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextGuid(): + raise Warning.Expected("GUID value", self.FileName, self.CurrentLineNumber) + if self._Token in GlobalData.gGuidDict: + self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper() + + FvObj.FvNameGuid = self._Token + + return True + + def _GetFvNameString(self, FvObj): + if not self._IsKeyword("FvNameString"): + return False + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken() or self._Token.upper() not in {'TRUE', 'FALSE'}: + raise Warning.Expected("TRUE or FALSE for FvNameString", self.FileName, self.CurrentLineNumber) + + FvObj.FvNameString = self._Token + + return True + + def _GetFvExtEntryStatement(self, FvObj): + if not (self._IsKeyword("FV_EXT_ENTRY") or self._IsKeyword("FV_EXT_ENTRY_TYPE")): + return False + + if not self._IsKeyword ("TYPE"): + raise Warning.Expected("'TYPE'", self.FileName, self.CurrentLineNumber) + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextHexNumber() and not self._GetNextDecimalNumber(): + raise Warning.Expected("Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber) + + FvObj.FvExtEntryTypeValue.append(self._Token) + + if not self._IsToken("{"): + raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber) + + if not self._IsKeyword("FILE") and not self._IsKeyword("DATA"): + raise Warning.Expected("'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber) + + FvObj.FvExtEntryType.append(self._Token) + + if self._Token == 'DATA': + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._IsToken("{"): + raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber) + + if not self._GetNextHexNumber(): + raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber) + + if len(self._Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) + + DataString = self._Token + DataString += TAB_COMMA_SPLIT + + while self._IsToken(TAB_COMMA_SPLIT): + if not self._GetNextHexNumber(): + raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber) + if len(self._Token) > 4: + raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber) + DataString += self._Token + DataString += TAB_COMMA_SPLIT + + if not self._IsToken(T_CHAR_BRACE_R): + raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber) + + if not self._IsToken(T_CHAR_BRACE_R): + raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber) + + DataString = DataString.rstrip(TAB_COMMA_SPLIT) + FvObj.FvExtEntryData.append(DataString) + + if self._Token == 'FILE': + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber) + + FvObj.FvExtEntryData.append(self._Token) + + if not self._IsToken(T_CHAR_BRACE_R): + raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber) + + return True + + ## _GetAprioriSection() method + # + # Get token statements + # + # @param self The object pointer + # @param FvObj for whom apriori is got + # @retval True Successfully find apriori statement + # @retval False Not able to find apriori statement + # + def _GetAprioriSection(self, FvObj): + if not self._IsKeyword("APRIORI"): + return False + + if not self._IsKeyword("PEI") and not self._IsKeyword("DXE"): + raise Warning.Expected("Apriori file type", self.FileName, self.CurrentLineNumber) + AprType = self._Token + + if not self._IsToken("{"): + raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber) + + AprSectionObj = AprioriSection() + AprSectionObj.AprioriType = AprType + + self._GetDefineStatements(AprSectionObj) + + while True: + IsInf = self._GetInfStatement(AprSectionObj) + IsFile = self._GetFileStatement(AprSectionObj) + if not IsInf and not IsFile: + break + + if not self._IsToken(T_CHAR_BRACE_R): + raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber) + + FvObj.AprioriSectionList.append(AprSectionObj) + return True + + def _ParseInfStatement(self): + if not self._IsKeyword("INF"): + return None + + ffsInf = FfsInfStatement() + self._GetInfOptions(ffsInf) + + if not self._GetNextToken(): + raise Warning.Expected("INF file path", self.FileName, self.CurrentLineNumber) + ffsInf.InfFileName = self._Token + if not ffsInf.InfFileName.endswith('.inf'): + raise Warning.Expected(".inf file path", self.FileName, self.CurrentLineNumber) + + ffsInf.CurrentLineNum = self.CurrentLineNumber + ffsInf.CurrentLineContent = self._CurrentLine() + + #Replace $(SAPCE) with real space + ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ') + + if ffsInf.InfFileName.replace(TAB_WORKSPACE, '').find('$') == -1: + #do case sensitive check for file path + ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate() + if ErrorCode != 0: + EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) + + NewFileName = ffsInf.InfFileName + if ffsInf.OverrideGuid: + NewFileName = ProcessDuplicatedInf(PathClass(ffsInf.InfFileName,GenFdsGlobalVariable.WorkSpaceDir), ffsInf.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir).Path + + if not NewFileName in self.Profile.InfList: + self.Profile.InfList.append(NewFileName) + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.InfFileLineList.append(FileLineTuple) + if ffsInf.UseArch: + if ffsInf.UseArch not in self.Profile.InfDict: + self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName] + else: + self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName) + else: + self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName) + + if self._IsToken(TAB_VALUE_SPLIT): + if self._IsKeyword('RELOCS_STRIPPED'): + ffsInf.KeepReloc = False + elif self._IsKeyword('RELOCS_RETAINED'): + ffsInf.KeepReloc = True + else: + raise Warning("Unknown reloc strip flag '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + return ffsInf + + ## _GetInfStatement() method + # + # Get INF statements + # + # @param self The object pointer + # @param Obj for whom inf statement is got + # @retval True Successfully find inf statement + # @retval False Not able to find inf statement + # + def _GetInfStatement(self, Obj, ForCapsule=False): + ffsInf = self._ParseInfStatement() + if not ffsInf: + return False + + if ForCapsule: + myCapsuleFfs = CapsuleFfs() + myCapsuleFfs.Ffs = ffsInf + Obj.CapsuleDataList.append(myCapsuleFfs) + else: + Obj.FfsList.append(ffsInf) + return True + + ## _GetInfOptions() method + # + # Get options for INF + # + # @param self The object pointer + # @param FfsInfObj for whom option is got + # + def _GetInfOptions(self, FfsInfObj): + if self._IsKeyword("FILE_GUID"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextGuid(): + raise Warning.Expected("GUID value", self.FileName, self.CurrentLineNumber) + if self._Token in GlobalData.gGuidDict: + self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper() + FfsInfObj.OverrideGuid = self._Token + + if self._IsKeyword("RuleOverride"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken(): + raise Warning.Expected("Rule name", self.FileName, self.CurrentLineNumber) + FfsInfObj.Rule = self._Token + + if self._IsKeyword("VERSION"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken(): + raise Warning.Expected("Version", self.FileName, self.CurrentLineNumber) + + if self._GetStringData(): + FfsInfObj.Version = self._Token + + if self._IsKeyword(BINARY_FILE_TYPE_UI): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken(): + raise Warning.Expected("UI name", self.FileName, self.CurrentLineNumber) + + if self._GetStringData(): + FfsInfObj.Ui = self._Token + + if self._IsKeyword("USE"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken(): + raise Warning.Expected("ARCH name", self.FileName, self.CurrentLineNumber) + FfsInfObj.UseArch = self._Token + + + if self._GetNextToken(): + p = compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))') + if p.match(self._Token) and p.match(self._Token).span()[1] == len(self._Token): + FfsInfObj.KeyStringList.append(self._Token) + if not self._IsToken(TAB_COMMA_SPLIT): + return + else: + self._UndoToken() + return + + while self._GetNextToken(): + if not p.match(self._Token): + raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber) + FfsInfObj.KeyStringList.append(self._Token) + + if not self._IsToken(TAB_COMMA_SPLIT): + break + + ## _GetFileStatement() method + # + # Get FILE statements + # + # @param self The object pointer + # @param Obj for whom FILE statement is got + # @retval True Successfully find FILE statement + # @retval False Not able to find FILE statement + # + def _GetFileStatement(self, Obj, ForCapsule = False): + if not self._IsKeyword("FILE"): + return False + + if not self._GetNextWord(): + raise Warning.Expected("FFS type", self.FileName, self.CurrentLineNumber) + + if ForCapsule and self._Token == 'DATA': + self._UndoToken() + self._UndoToken() + return False + + FfsFileObj = FileStatement() + FfsFileObj.FvFileType = self._Token + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextGuid(): + if not self._GetNextWord(): + raise Warning.Expected("File GUID", self.FileName, self.CurrentLineNumber) + if self._Token == 'PCD': + if not self._IsToken("("): + raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber) + PcdPair = self._GetNextPcdSettings() + if not self._IsToken(")"): + raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber) + self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')' + + if self._Token in GlobalData.gGuidDict: + self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper() + FfsFileObj.NameGuid = self._Token + + self._GetFilePart(FfsFileObj) + + if ForCapsule: + capsuleFfs = CapsuleFfs() + capsuleFfs.Ffs = FfsFileObj + Obj.CapsuleDataList.append(capsuleFfs) + else: + Obj.FfsList.append(FfsFileObj) + + return True + + ## _FileCouldHaveRelocFlag() method + # + # Check whether reloc strip flag can be set for a file type. + # + # @param FileType The file type to check with + # @retval True This type could have relocation strip flag + # @retval False No way to have it + # + @staticmethod + def _FileCouldHaveRelocFlag (FileType): + if FileType in {SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE, 'PEI_DXE_COMBO'}: + return True + else: + return False + + ## _SectionCouldHaveRelocFlag() method + # + # Check whether reloc strip flag can be set for a section type. + # + # @param SectionType The section type to check with + # @retval True This type could have relocation strip flag + # @retval False No way to have it + # + @staticmethod + def _SectionCouldHaveRelocFlag (SectionType): + if SectionType in {BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32}: + return True + else: + return False + + ## _GetFilePart() method + # + # Get components for FILE statement + # + # @param self The object pointer + # @param FfsFileObj for whom component is got + # + def _GetFilePart(self, FfsFileObj): + self._GetFileOpts(FfsFileObj) + + if not self._IsToken("{"): + if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'): + if self._FileCouldHaveRelocFlag(FfsFileObj.FvFileType): + if self._Token == 'RELOCS_STRIPPED': + FfsFileObj.KeepReloc = False + else: + FfsFileObj.KeepReloc = True + else: + raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if not self._IsToken("{"): + raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("File name or section data", self.FileName, self.CurrentLineNumber) + + if self._Token == BINARY_FILE_TYPE_FV: + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken(): + raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber) + FfsFileObj.FvName = self._Token + + elif self._Token == "FD": + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken(): + raise Warning.Expected("FD name", self.FileName, self.CurrentLineNumber) + FfsFileObj.FdName = self._Token + + elif self._Token in {TAB_DEFINE, "APRIORI", "SECTION"}: + self._UndoToken() + self._GetSectionData(FfsFileObj) + + elif hasattr(FfsFileObj, 'FvFileType') and FfsFileObj.FvFileType == 'RAW': + self._UndoToken() + self._GetRAWData(FfsFileObj) + + else: + FfsFileObj.CurrentLineNum = self.CurrentLineNumber + FfsFileObj.CurrentLineContent = self._CurrentLine() + FfsFileObj.FileName = self._Token.replace('$(SPACE)', ' ') + self._VerifyFile(FfsFileObj.FileName) + + if not self._IsToken(T_CHAR_BRACE_R): + raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber) + + ## _GetRAWData() method + # + # Get RAW data for FILE statement + # + # @param self The object pointer + # @param FfsFileObj for whom section is got + # + def _GetRAWData(self, FfsFileObj): + FfsFileObj.FileName = [] + FfsFileObj.SubAlignment = [] + while True: + AlignValue = None + if self._GetAlignment(): + if self._Token not in ALIGNMENTS: + raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + #For FFS, Auto is default option same to "" + if not self._Token == "Auto": + AlignValue = self._Token + if not self._GetNextToken(): + raise Warning.Expected("Filename value", self.FileName, self.CurrentLineNumber) + + FileName = self._Token.replace('$(SPACE)', ' ') + if FileName == T_CHAR_BRACE_R: + self._UndoToken() + raise Warning.Expected("Filename value", self.FileName, self.CurrentLineNumber) + + self._VerifyFile(FileName) + File = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir) + FfsFileObj.FileName.append(File.Path) + FfsFileObj.SubAlignment.append(AlignValue) + + if self._IsToken(T_CHAR_BRACE_R): + self._UndoToken() + break + + if len(FfsFileObj.SubAlignment) == 1: + FfsFileObj.SubAlignment = FfsFileObj.SubAlignment[0] + if len(FfsFileObj.FileName) == 1: + FfsFileObj.FileName = FfsFileObj.FileName[0] + + ## _GetFileOpts() method + # + # Get options for FILE statement + # + # @param self The object pointer + # @param FfsFileObj for whom options is got + # + def _GetFileOpts(self, FfsFileObj): + if self._GetNextToken(): + if TokenFindPattern.match(self._Token): + FfsFileObj.KeyStringList.append(self._Token) + if self._IsToken(TAB_COMMA_SPLIT): + while self._GetNextToken(): + if not TokenFindPattern.match(self._Token): + raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber) + FfsFileObj.KeyStringList.append(self._Token) + + if not self._IsToken(TAB_COMMA_SPLIT): + break + + else: + self._UndoToken() + + if self._IsKeyword("FIXED", True): + FfsFileObj.Fixed = True + + if self._IsKeyword("CHECKSUM", True): + FfsFileObj.CheckSum = True + + if self._GetAlignment(): + if self._Token not in ALIGNMENTS: + raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + #For FFS, Auto is default option same to "" + if not self._Token == "Auto": + FfsFileObj.Alignment = self._Token + + ## _GetAlignment() method + # + # Return the alignment value + # + # @param self The object pointer + # @retval True Successfully find alignment + # @retval False Not able to find alignment + # + def _GetAlignment(self): + if self._IsKeyword("Align", True): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("alignment value", self.FileName, self.CurrentLineNumber) + return True + + return False + + ## _GetSectionData() method + # + # Get section data for FILE statement + # + # @param self The object pointer + # @param FfsFileObj for whom section is got + # + def _GetSectionData(self, FfsFileObj): + self._GetDefineStatements(FfsFileObj) + + while True: + IsLeafSection = self._GetLeafSection(FfsFileObj) + IsEncapSection = self._GetEncapsulationSec(FfsFileObj) + if not IsLeafSection and not IsEncapSection: + break + + ## _GetLeafSection() method + # + # Get leaf section for Obj + # + # @param self The object pointer + # @param Obj for whom leaf section is got + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def _GetLeafSection(self, Obj): + OldPos = self.GetFileBufferPos() + + if not self._IsKeyword("SECTION"): + if len(Obj.SectionList) == 0: + raise Warning.Expected("SECTION", self.FileName, self.CurrentLineNumber) + else: + return False + + AlignValue = None + if self._GetAlignment(): + if self._Token not in ALIGNMENTS: + raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + AlignValue = self._Token + + BuildNum = None + if self._IsKeyword("BUILD_NUM"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("Build number value", self.FileName, self.CurrentLineNumber) + + BuildNum = self._Token + + if self._IsKeyword("VERSION"): + if AlignValue == 'Auto': + raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken(): + raise Warning.Expected("version", self.FileName, self.CurrentLineNumber) + VerSectionObj = VerSection() + VerSectionObj.Alignment = AlignValue + VerSectionObj.BuildNum = BuildNum + if self._GetStringData(): + VerSectionObj.StringData = self._Token + else: + VerSectionObj.FileName = self._Token + Obj.SectionList.append(VerSectionObj) + + elif self._IsKeyword(BINARY_FILE_TYPE_UI): + if AlignValue == 'Auto': + raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken(): + raise Warning.Expected("UI", self.FileName, self.CurrentLineNumber) + UiSectionObj = UiSection() + UiSectionObj.Alignment = AlignValue + if self._GetStringData(): + UiSectionObj.StringData = self._Token + else: + UiSectionObj.FileName = self._Token + Obj.SectionList.append(UiSectionObj) + + elif self._IsKeyword("FV_IMAGE"): + if AlignValue == 'Auto': + raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken(): + raise Warning.Expected("FV name or FV file path", self.FileName, self.CurrentLineNumber) + + FvName = self._Token + FvObj = None + + if self._IsToken("{"): + FvObj = FV() + FvObj.UiFvName = FvName.upper() + self._GetDefineStatements(FvObj) + + self._GetBlockStatement(FvObj) + self._GetSetStatements(FvObj) + self._GetFvAlignment(FvObj) + self._GetFvAttributes(FvObj) + + while True: + IsInf = self._GetInfStatement(FvObj) + IsFile = self._GetFileStatement(FvObj) + if not IsInf and not IsFile: + break + + if not self._IsToken(T_CHAR_BRACE_R): + raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber) + + FvImageSectionObj = FvImageSection() + FvImageSectionObj.Alignment = AlignValue + if FvObj is not None: + FvImageSectionObj.Fv = FvObj + FvImageSectionObj.FvName = None + else: + FvImageSectionObj.FvName = FvName.upper() + FvImageSectionObj.FvFileName = FvName + + Obj.SectionList.append(FvImageSectionObj) + + elif self._IsKeyword("PEI_DEPEX_EXP") or self._IsKeyword("DXE_DEPEX_EXP") or self._IsKeyword("SMM_DEPEX_EXP"): + if AlignValue == 'Auto': + raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + DepexSectionObj = DepexSection() + DepexSectionObj.Alignment = AlignValue + DepexSectionObj.DepexType = self._Token + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._IsToken("{"): + raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber) + if not self._SkipToToken(T_CHAR_BRACE_R): + raise Warning.Expected("Depex expression ending '}'", self.FileName, self.CurrentLineNumber) + + DepexSectionObj.Expression = self._SkippedChars.rstrip(T_CHAR_BRACE_R) + Obj.SectionList.append(DepexSectionObj) + + elif self._IsKeyword("SUBTYPE_GUID"): + if AlignValue == 'Auto': + raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + SubTypeGuidValue = None + if not self._GetNextGuid(): + raise Warning.Expected("GUID", self.FileName, self.CurrentLineNumber) + else: + SubTypeGuidValue = self._Token + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken(): + raise Warning.Expected("section file path", self.FileName, self.CurrentLineNumber) + FileName = self._Token + + SubTypeGuidSectionObj = SubTypeGuidSection() + SubTypeGuidSectionObj.Alignment = AlignValue + SubTypeGuidSectionObj.SubTypeGuid = SubTypeGuidValue + SubTypeGuidSectionObj.SectFileName = FileName + Obj.SectionList.append(SubTypeGuidSectionObj) + + else: + if not self._GetNextWord(): + raise Warning.Expected("section type", self.FileName, self.CurrentLineNumber) + + # Encapsulation section appear, UndoToken and return + if self._Token == "COMPRESS" or self._Token == "GUIDED": + self.SetFileBufferPos(OldPos) + return False + + if self._Token not in {"COMPAT16", BINARY_FILE_TYPE_PE32, BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\ + BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX}: + raise Warning("Unknown section type '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + if AlignValue == 'Auto'and (not self._Token == BINARY_FILE_TYPE_PE32) and (not self._Token == BINARY_FILE_TYPE_TE): + raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + + # DataSection + DataSectionObj = DataSection() + DataSectionObj.Alignment = AlignValue + DataSectionObj.SecType = self._Token + + if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'): + if self._FileCouldHaveRelocFlag(Obj.FvFileType) and self._SectionCouldHaveRelocFlag(DataSectionObj.SecType): + if self._Token == 'RELOCS_STRIPPED': + DataSectionObj.KeepReloc = False + else: + DataSectionObj.KeepReloc = True + else: + raise Warning("File type %s, section type %s, could not have reloc strip flag%d" % (Obj.FvFileType, DataSectionObj.SecType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if self._IsToken(TAB_EQUAL_SPLIT): + if not self._GetNextToken(): + raise Warning.Expected("section file path", self.FileName, self.CurrentLineNumber) + DataSectionObj.SectFileName = self._Token + self._VerifyFile(DataSectionObj.SectFileName) + else: + if not self._GetCglSection(DataSectionObj): + return False + + Obj.SectionList.append(DataSectionObj) + + return True + + ## _VerifyFile + # + # Check if file exists or not: + # If current phase if GenFds, the file must exist; + # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist + # @param FileName: File path to be verified. + # + def _VerifyFile(self, FileName): + if FileName.replace(TAB_WORKSPACE, '').find('$') != -1: + return + if not GlobalData.gAutoGenPhase or not self._GetMacroValue(TAB_DSC_DEFINES_OUTPUT_DIRECTORY) in FileName: + ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate() + if ErrorCode != 0: + EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) + + ## _GetCglSection() method + # + # Get compressed or GUIDed section for Obj + # + # @param self The object pointer + # @param Obj for whom leaf section is got + # @param AlignValue alignment value for complex section + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def _GetCglSection(self, Obj, AlignValue = None): + + if self._IsKeyword("COMPRESS"): + type = "PI_STD" + if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"): + type = self._Token + + if not self._IsToken("{"): + raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber) + + CompressSectionObj = CompressSection() + CompressSectionObj.Alignment = AlignValue + CompressSectionObj.CompType = type + # Recursive sections... + while True: + IsLeafSection = self._GetLeafSection(CompressSectionObj) + IsEncapSection = self._GetEncapsulationSec(CompressSectionObj) + if not IsLeafSection and not IsEncapSection: + break + + + if not self._IsToken(T_CHAR_BRACE_R): + raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber) + Obj.SectionList.append(CompressSectionObj) + return True + + elif self._IsKeyword("GUIDED"): + GuidValue = None + if self._GetNextGuid(): + if self._Token in GlobalData.gGuidDict: + self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper() + GuidValue = self._Token + + AttribDict = self._GetGuidAttrib() + if not self._IsToken("{"): + raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber) + GuidSectionObj = GuidSection() + GuidSectionObj.Alignment = AlignValue + GuidSectionObj.NameGuid = GuidValue + GuidSectionObj.SectionType = "GUIDED" + GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"] + GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"] + GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"] + # Recursive sections... + while True: + IsLeafSection = self._GetLeafSection(GuidSectionObj) + IsEncapSection = self._GetEncapsulationSec(GuidSectionObj) + if not IsLeafSection and not IsEncapSection: + break + + if not self._IsToken(T_CHAR_BRACE_R): + raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber) + Obj.SectionList.append(GuidSectionObj) + + return True + + return False + + ## _GetGuidAttri() method + # + # Get attributes for GUID section + # + # @param self The object pointer + # @retval AttribDict Dictionary of key-value pair of section attributes + # + def _GetGuidAttrib(self): + AttribDict = {} + AttribDict["PROCESSING_REQUIRED"] = "NONE" + AttribDict["AUTH_STATUS_VALID"] = "NONE" + AttribDict["EXTRA_HEADER_SIZE"] = -1 + while self._IsKeyword("PROCESSING_REQUIRED") or self._IsKeyword("AUTH_STATUS_VALID") \ + or self._IsKeyword("EXTRA_HEADER_SIZE"): + AttribKey = self._Token + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber) + elif AttribKey == "EXTRA_HEADER_SIZE": + Base = 10 + if self._Token[0:2].upper() == "0X": + Base = 16 + try: + AttribDict[AttribKey] = int(self._Token, Base) + continue + except ValueError: + raise Warning.Expected("Number", self.FileName, self.CurrentLineNumber) + elif self._Token.upper() not in {"TRUE", "FALSE", "1", "0"}: + raise Warning.Expected("TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber) + AttribDict[AttribKey] = self._Token + + return AttribDict + + ## _GetEncapsulationSec() method + # + # Get encapsulation section for FILE + # + # @param self The object pointer + # @param FfsFile for whom section is got + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def _GetEncapsulationSec(self, FfsFileObj): + OldPos = self.GetFileBufferPos() + if not self._IsKeyword("SECTION"): + if len(FfsFileObj.SectionList) == 0: + raise Warning.Expected("SECTION", self.FileName, self.CurrentLineNumber) + else: + return False + + AlignValue = None + if self._GetAlignment(): + if self._Token not in ALIGNMENT_NOAUTO: + raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + AlignValue = self._Token + + if not self._GetCglSection(FfsFileObj, AlignValue): + self.SetFileBufferPos(OldPos) + return False + else: + return True + + def _GetFmp(self): + if not self._GetNextToken(): + return False + S = self._Token.upper() + if S.startswith(TAB_SECTION_START) and not S.startswith("[FMPPAYLOAD."): + self.SectionParser(S) + self._UndoToken() + return False + + self._UndoToken() + self._SkipToToken("[FMPPAYLOAD.", True) + FmpUiName = self._GetUiName().upper() + if FmpUiName in self.Profile.FmpPayloadDict: + raise Warning("Duplicated FMP UI name found: %s" % FmpUiName, self.FileName, self.CurrentLineNumber) + + FmpData = CapsulePayload() + FmpData.UiName = FmpUiName + + if not self._IsToken(TAB_SECTION_END): + raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber) + FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT'] + while self._Token in FmpKeyList: + Name = self._Token + FmpKeyList.remove(Name) + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if Name == 'IMAGE_TYPE_ID': + if not self._GetNextGuid(): + raise Warning.Expected("GUID value for IMAGE_TYPE_ID.", self.FileName, self.CurrentLineNumber) + FmpData.ImageTypeId = self._Token + elif Name == 'CERTIFICATE_GUID': + if not self._GetNextGuid(): + raise Warning.Expected("GUID value for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber) + FmpData.Certificate_Guid = self._Token + if UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_RSA2048_SHA256_GUID and UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_PKCS7_GUID: + raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber) + else: + if not self._GetNextToken(): + raise Warning.Expected("value of %s" % Name, self.FileName, self.CurrentLineNumber) + Value = self._Token + if Name == 'IMAGE_HEADER_INIT_VERSION': + if FdfParser._Verify(Name, Value, 'UINT8'): + FmpData.Version = Value + elif Name == 'IMAGE_INDEX': + if FdfParser._Verify(Name, Value, 'UINT8'): + FmpData.ImageIndex = Value + elif Name == 'HARDWARE_INSTANCE': + if FdfParser._Verify(Name, Value, 'UINT8'): + FmpData.HardwareInstance = Value + elif Name == 'MONOTONIC_COUNT': + if FdfParser._Verify(Name, Value, 'UINT64'): + FmpData.MonotonicCount = Value + if FmpData.MonotonicCount.upper().startswith('0X'): + FmpData.MonotonicCount = int(FmpData.MonotonicCount, 16) + else: + FmpData.MonotonicCount = int(FmpData.MonotonicCount) + if not self._GetNextToken(): + break + else: + self._UndoToken() + + if (FmpData.MonotonicCount and not FmpData.Certificate_Guid) or (not FmpData.MonotonicCount and FmpData.Certificate_Guid): + EdkLogger.error("FdfParser", FORMAT_INVALID, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.") + + # Only the IMAGE_TYPE_ID is required item + if FmpKeyList and 'IMAGE_TYPE_ID' in FmpKeyList: + raise Warning("'IMAGE_TYPE_ID' in FMP payload section.", self.FileName, self.CurrentLineNumber) + # get the Image file and Vendor code file + self._GetFMPCapsuleData(FmpData) + if not FmpData.ImageFile: + raise Warning("Missing image file in FMP payload section.", self.FileName, self.CurrentLineNumber) + # check whether more than one Vendor code file + if len(FmpData.VendorCodeFile) > 1: + raise Warning("Vendor code file max of 1 per FMP payload section.", self.FileName, self.CurrentLineNumber) + self.Profile.FmpPayloadDict[FmpUiName] = FmpData + return True + + ## _GetCapsule() method + # + # Get capsule section contents and store its data into capsule list of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a capsule + # @retval False Not able to find a capsule + # + def _GetCapsule(self): + if not self._GetNextToken(): + return False + + S = self._Token.upper() + if S.startswith(TAB_SECTION_START) and not S.startswith("[CAPSULE."): + self.SectionParser(S) + self._UndoToken() + return False + + self._UndoToken() + if not self._IsToken("[CAPSULE.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning.Expected("[Capsule.]", self.FileName, self.CurrentLineNumber) + + CapsuleObj = Capsule() + + CapsuleName = self._GetUiName() + if not CapsuleName: + raise Warning.Expected("capsule name", self.FileName, self.CurrentLineNumber) + + CapsuleObj.UiCapsuleName = CapsuleName.upper() + + if not self._IsToken(TAB_SECTION_END): + raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber) + + if self._IsKeyword("CREATE_FILE"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("file name", self.FileName, self.CurrentLineNumber) + + CapsuleObj.CreateFile = self._Token + + self._GetCapsuleStatements(CapsuleObj) + self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj + return True + + ## _GetCapsuleStatements() method + # + # Get statements for capsule + # + # @param self The object pointer + # @param Obj for whom statements are got + # + def _GetCapsuleStatements(self, Obj): + self._GetCapsuleTokens(Obj) + self._GetDefineStatements(Obj) + self._GetSetStatements(Obj) + self._GetCapsuleData(Obj) + + ## _GetCapsuleTokens() method + # + # Get token statements for capsule + # + # @param self The object pointer + # @param Obj for whom token statements are got + # + def _GetCapsuleTokens(self, Obj): + if not self._GetNextToken(): + return False + while self._Token in {"CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"}: + Name = self._Token.strip() + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken(): + raise Warning.Expected("value", self.FileName, self.CurrentLineNumber) + if Name == 'CAPSULE_FLAGS': + if not self._Token in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}: + raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber) + Value = self._Token.strip() + while self._IsToken(TAB_COMMA_SPLIT): + Value += TAB_COMMA_SPLIT + if not self._GetNextToken(): + raise Warning.Expected("value", self.FileName, self.CurrentLineNumber) + if not self._Token in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}: + raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber) + Value += self._Token.strip() + elif Name == 'OEM_CAPSULE_FLAGS': + Value = self._Token.strip() + if not Value.upper().startswith('0X'): + raise Warning.Expected("hex value starting with 0x", self.FileName, self.CurrentLineNumber) + try: + Value = int(Value, 0) + except ValueError: + raise Warning.Expected("hex string failed to convert to value", self.FileName, self.CurrentLineNumber) + if not 0x0000 <= Value <= 0xFFFF: + raise Warning.Expected("hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber) + Value = self._Token.strip() + else: + Value = self._Token.strip() + Obj.TokensDict[Name] = Value + if not self._GetNextToken(): + return False + self._UndoToken() + + ## _GetCapsuleData() method + # + # Get capsule data for capsule + # + # @param self The object pointer + # @param Obj for whom capsule data are got + # + def _GetCapsuleData(self, Obj): + while True: + IsInf = self._GetInfStatement(Obj, True) + IsFile = self._GetFileStatement(Obj, True) + IsFv = self._GetFvStatement(Obj) + IsFd = self._GetFdStatement(Obj) + IsAnyFile = self._GetAnyFileStatement(Obj) + IsAfile = self._GetAfileStatement(Obj) + IsFmp = self._GetFmpStatement(Obj) + if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp): + break + + ## _GetFMPCapsuleData() method + # + # Get capsule data for FMP capsule + # + # @param self The object pointer + # @param Obj for whom capsule data are got + # + def _GetFMPCapsuleData(self, Obj): + while True: + IsFv = self._GetFvStatement(Obj, True) + IsFd = self._GetFdStatement(Obj, True) + IsAnyFile = self._GetAnyFileStatement(Obj, True) + if not (IsFv or IsFd or IsAnyFile): + break + + ## _GetFvStatement() method + # + # Get FV for capsule + # + # @param self The object pointer + # @param CapsuleObj for whom FV is got + # @retval True Successfully find a FV statement + # @retval False Not able to find a FV statement + # + def _GetFvStatement(self, CapsuleObj, FMPCapsule = False): + if not self._IsKeyword(BINARY_FILE_TYPE_FV): + return False + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber) + + if self._Token.upper() not in self.Profile.FvDict: + raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber) + + myCapsuleFv = CapsuleFv() + myCapsuleFv.FvName = self._Token + if FMPCapsule: + if not CapsuleObj.ImageFile: + CapsuleObj.ImageFile.append(myCapsuleFv) + else: + CapsuleObj.VendorCodeFile.append(myCapsuleFv) + else: + CapsuleObj.CapsuleDataList.append(myCapsuleFv) + return True + + ## _GetFdStatement() method + # + # Get FD for capsule + # + # @param self The object pointer + # @param CapsuleObj for whom FD is got + # @retval True Successfully find a FD statement + # @retval False Not able to find a FD statement + # + def _GetFdStatement(self, CapsuleObj, FMPCapsule = False): + if not self._IsKeyword("FD"): + return False + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("FD name", self.FileName, self.CurrentLineNumber) + + if self._Token.upper() not in self.Profile.FdDict: + raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber) + + myCapsuleFd = CapsuleFd() + myCapsuleFd.FdName = self._Token + if FMPCapsule: + if not CapsuleObj.ImageFile: + CapsuleObj.ImageFile.append(myCapsuleFd) + else: + CapsuleObj.VendorCodeFile.append(myCapsuleFd) + else: + CapsuleObj.CapsuleDataList.append(myCapsuleFd) + return True + + def _GetFmpStatement(self, CapsuleObj): + if not self._IsKeyword("FMP_PAYLOAD"): + if not self._IsKeyword("FMP"): + return False + + if not self._IsKeyword("PAYLOAD"): + self._UndoToken() + return False + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("payload name after FMP_PAYLOAD =", self.FileName, self.CurrentLineNumber) + Payload = self._Token.upper() + if Payload not in self.Profile.FmpPayloadDict: + raise Warning("This FMP Payload does not exist: %s" % self._Token, self.FileName, self.CurrentLineNumber) + CapsuleObj.FmpPayloadList.append(self.Profile.FmpPayloadDict[Payload]) + return True + + def _ParseRawFileStatement(self): + if not self._IsKeyword("FILE"): + return None + + if not self._IsKeyword("DATA"): + self._UndoToken() + return None + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber) + + AnyFileName = self._Token + self._VerifyFile(AnyFileName) + + if not os.path.isabs(AnyFileName): + AnyFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, AnyFileName) + + return AnyFileName + + ## _GetAnyFileStatement() method + # + # Get AnyFile for capsule + # + # @param self The object pointer + # @param CapsuleObj for whom AnyFile is got + # @retval True Successfully find a Anyfile statement + # @retval False Not able to find a AnyFile statement + # + def _GetAnyFileStatement(self, CapsuleObj, FMPCapsule = False): + AnyFileName = self._ParseRawFileStatement() + if not AnyFileName: + return False + + myCapsuleAnyFile = CapsuleAnyFile() + myCapsuleAnyFile.FileName = AnyFileName + if FMPCapsule: + if not CapsuleObj.ImageFile: + CapsuleObj.ImageFile.append(myCapsuleAnyFile) + else: + CapsuleObj.VendorCodeFile.append(myCapsuleAnyFile) + else: + CapsuleObj.CapsuleDataList.append(myCapsuleAnyFile) + return True + + ## _GetAfileStatement() method + # + # Get Afile for capsule + # + # @param self The object pointer + # @param CapsuleObj for whom Afile is got + # @retval True Successfully find a Afile statement + # @retval False Not able to find a Afile statement + # + def _GetAfileStatement(self, CapsuleObj): + if not self._IsKeyword("APPEND"): + return False + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("Afile name", self.FileName, self.CurrentLineNumber) + + AfileName = self._Token + AfileBaseName = os.path.basename(AfileName) + + if os.path.splitext(AfileBaseName)[1] not in {".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"}: + raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \ + self.FileName, self.CurrentLineNumber) + + if not os.path.isabs(AfileName): + AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName) + self._VerifyFile(AfileName) + else: + if not os.path.exists(AfileName): + raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber) + else: + pass + + myCapsuleAfile = CapsuleAfile() + myCapsuleAfile.FileName = AfileName + CapsuleObj.CapsuleDataList.append(myCapsuleAfile) + return True + + ## _GetRule() method + # + # Get Rule section contents and store its data into rule list of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a Rule + # @retval False Not able to find a Rule + # + def _GetRule(self): + if not self._GetNextToken(): + return False + + S = self._Token.upper() + if S.startswith(TAB_SECTION_START) and not S.startswith("[RULE."): + self.SectionParser(S) + self._UndoToken() + return False + self._UndoToken() + if not self._IsToken("[Rule.", True): + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \ + # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine) + raise Warning.Expected("[Rule.]", self.FileName, self.CurrentLineNumber) + + if not self._SkipToToken(TAB_SPLIT): + raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber) + + Arch = self._SkippedChars.rstrip(TAB_SPLIT) + + ModuleType = self._GetModuleType() + + TemplateName = "" + if self._IsToken(TAB_SPLIT): + if not self._GetNextWord(): + raise Warning.Expected("template name", self.FileName, self.CurrentLineNumber) + TemplateName = self._Token + + if not self._IsToken(TAB_SECTION_END): + raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber) + + RuleObj = self._GetRuleFileStatements() + RuleObj.Arch = Arch.upper() + RuleObj.ModuleType = ModuleType + RuleObj.TemplateName = TemplateName + if TemplateName == '': + self.Profile.RuleDict['RULE' + \ + TAB_SPLIT + \ + Arch.upper() + \ + TAB_SPLIT + \ + ModuleType.upper() ] = RuleObj + else: + self.Profile.RuleDict['RULE' + \ + TAB_SPLIT + \ + Arch.upper() + \ + TAB_SPLIT + \ + ModuleType.upper() + \ + TAB_SPLIT + \ + TemplateName.upper() ] = RuleObj + return True + + ## _GetModuleType() method + # + # Return the module type + # + # @param self The object pointer + # @retval string module type + # + def _GetModuleType(self): + if not self._GetNextWord(): + raise Warning.Expected("Module type", self.FileName, self.CurrentLineNumber) + if self._Token.upper() not in { + SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, + SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER, + SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_DXE_SMM_DRIVER, + SUP_MODULE_DXE_RUNTIME_DRIVER, SUP_MODULE_UEFI_DRIVER, + SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_USER_DEFINED, SUP_MODULE_HOST_APPLICATION, + TAB_DEFAULT, SUP_MODULE_BASE, + EDK_COMPONENT_TYPE_SECURITY_CORE, + EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER, + EDK_COMPONENT_TYPE_PIC_PEIM, + EDK_COMPONENT_TYPE_RELOCATABLE_PEIM, "PE32_PEIM", + EDK_COMPONENT_TYPE_BS_DRIVER, EDK_COMPONENT_TYPE_RT_DRIVER, + EDK_COMPONENT_TYPE_SAL_RT_DRIVER, + EDK_COMPONENT_TYPE_APPLICATION, "ACPITABLE", + SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE, + SUP_MODULE_MM_CORE_STANDALONE}: + raise Warning("Unknown Module type '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + return self._Token + + ## _GetFileExtension() method + # + # Return the file extension + # + # @param self The object pointer + # @retval string file name extension + # + def _GetFileExtension(self): + if not self._IsToken(TAB_SPLIT): + raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber) + + Ext = "" + if self._GetNextToken(): + if FileExtensionPattern.match(self._Token): + Ext = self._Token + return TAB_SPLIT + Ext + else: + raise Warning("Unknown file extension '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + + else: + raise Warning.Expected("file extension", self.FileName, self.CurrentLineNumber) + + ## _GetRuleFileStatement() method + # + # Get rule contents + # + # @param self The object pointer + # @retval Rule Rule object + # + def _GetRuleFileStatements(self): + if not self._IsKeyword("FILE"): + raise Warning.Expected("FILE", self.FileName, self.CurrentLineNumber) + + if not self._GetNextWord(): + raise Warning.Expected("FFS type", self.FileName, self.CurrentLineNumber) + + Type = self._Token.strip().upper() + if Type not in {"RAW", "FREEFORM", SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, + "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE, EDK_COMPONENT_TYPE_APPLICATION, + "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE, + SUP_MODULE_MM_CORE_STANDALONE}: + raise Warning("Unknown FV type '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._IsKeyword("$(NAMED_GUID)"): + if not self._GetNextWord(): + NamedGuid = self._CurrentLine()[self.CurrentOffsetWithinLine:].split()[0].strip() + if GlobalData.gGuidPatternEnd.match(NamedGuid): + self.CurrentOffsetWithinLine += len(NamedGuid) + self._Token = NamedGuid + else: + raise Warning.Expected("$(NAMED_GUID)", self.FileName, self.CurrentLineNumber) + if self._Token == 'PCD': + if not self._IsToken("("): + raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber) + PcdPair = self._GetNextPcdSettings() + if not self._IsToken(")"): + raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber) + self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')' + + NameGuid = self._Token + + KeepReloc = None + if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'): + if self._FileCouldHaveRelocFlag(Type): + if self._Token == 'RELOCS_STRIPPED': + KeepReloc = False + else: + KeepReloc = True + else: + raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + KeyStringList = [] + if self._GetNextToken(): + if TokenFindPattern.match(self._Token): + KeyStringList.append(self._Token) + if self._IsToken(TAB_COMMA_SPLIT): + while self._GetNextToken(): + if not TokenFindPattern.match(self._Token): + raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber) + KeyStringList.append(self._Token) + + if not self._IsToken(TAB_COMMA_SPLIT): + break + + else: + self._UndoToken() + + + Fixed = False + if self._IsKeyword("Fixed", True): + Fixed = True + + CheckSum = False + if self._IsKeyword("CheckSum", True): + CheckSum = True + + AlignValue = "" + if self._GetAlignment(): + if self._Token not in ALIGNMENTS: + raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + #For FFS, Auto is default option same to "" + if not self._Token == "Auto": + AlignValue = self._Token + + if self._IsToken("{"): + # Complex file rule expected + NewRule = RuleComplexFile() + NewRule.FvFileType = Type + NewRule.NameGuid = NameGuid + NewRule.Alignment = AlignValue + NewRule.CheckSum = CheckSum + NewRule.Fixed = Fixed + NewRule.KeyStringList = KeyStringList + if KeepReloc is not None: + NewRule.KeepReloc = KeepReloc + + while True: + IsEncapsulate = self._GetRuleEncapsulationSection(NewRule) + IsLeaf = self._GetEfiSection(NewRule) + if not IsEncapsulate and not IsLeaf: + break + + if not self._IsToken(T_CHAR_BRACE_R): + raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber) + + return NewRule + + else: + # Simple file rule expected + if not self._GetNextWord(): + raise Warning.Expected("leaf section type", self.FileName, self.CurrentLineNumber) + + SectionName = self._Token + + if SectionName not in { + "COMPAT16", BINARY_FILE_TYPE_PE32, + BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE", + "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI, + BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID", + BINARY_FILE_TYPE_SMM_DEPEX}: + raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber) + + + if self._IsKeyword("Fixed", True): + Fixed = True + + if self._IsKeyword("CheckSum", True): + CheckSum = True + + SectAlignment = "" + if self._GetAlignment(): + if self._Token not in ALIGNMENTS: + raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE): + raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + SectAlignment = self._Token + + Ext = None + if self._IsToken(TAB_VALUE_SPLIT): + Ext = self._GetFileExtension() + elif not self._GetNextToken(): + raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber) + + NewRule = RuleSimpleFile() + NewRule.SectionType = SectionName + NewRule.FvFileType = Type + NewRule.NameGuid = NameGuid + NewRule.Alignment = AlignValue + NewRule.SectAlignment = SectAlignment + NewRule.CheckSum = CheckSum + NewRule.Fixed = Fixed + NewRule.KeyStringList = KeyStringList + if KeepReloc is not None: + NewRule.KeepReloc = KeepReloc + NewRule.FileExtension = Ext + NewRule.FileName = self._Token + return NewRule + + ## _GetEfiSection() method + # + # Get section list for Rule + # + # @param self The object pointer + # @param Obj for whom section is got + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def _GetEfiSection(self, Obj): + OldPos = self.GetFileBufferPos() + EfiSectionObj = EfiSection() + if not self._GetNextWord(): + CurrentLine = self._CurrentLine()[self.CurrentOffsetWithinLine:].split()[0].strip() + if self._Token == '{' and Obj.FvFileType == "RAW" and TAB_SPLIT in CurrentLine: + if self._IsToken(TAB_VALUE_SPLIT): + EfiSectionObj.FileExtension = self._GetFileExtension() + elif self._GetNextToken(): + EfiSectionObj.FileName = self._Token + EfiSectionObj.SectionType = BINARY_FILE_TYPE_RAW + Obj.SectionList.append(EfiSectionObj) + return True + else: + return False + SectionName = self._Token + + if SectionName not in { + "COMPAT16", BINARY_FILE_TYPE_PE32, + BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE", + "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI, + BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID", + BINARY_FILE_TYPE_SMM_DEPEX, BINARY_FILE_TYPE_GUID}: + self._UndoToken() + return False + + if SectionName == "FV_IMAGE": + FvImageSectionObj = FvImageSection() + if self._IsKeyword("FV_IMAGE"): + pass + if self._IsToken("{"): + FvObj = FV() + self._GetDefineStatements(FvObj) + self._GetBlockStatement(FvObj) + self._GetSetStatements(FvObj) + self._GetFvAlignment(FvObj) + self._GetFvAttributes(FvObj) + self._GetAprioriSection(FvObj) + self._GetAprioriSection(FvObj) + + while True: + IsInf = self._GetInfStatement(FvObj) + IsFile = self._GetFileStatement(FvObj) + if not IsInf and not IsFile: + break + + if not self._IsToken(T_CHAR_BRACE_R): + raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber) + FvImageSectionObj.Fv = FvObj + FvImageSectionObj.FvName = None + + else: + if not self._IsKeyword(BINARY_FILE_TYPE_FV): + raise Warning.Expected("'FV'", self.FileName, self.CurrentLineNumber) + FvImageSectionObj.FvFileType = self._Token + + if self._GetAlignment(): + if self._Token not in ALIGNMENT_NOAUTO: + raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + FvImageSectionObj.Alignment = self._Token + + if self._IsToken(TAB_VALUE_SPLIT): + FvImageSectionObj.FvFileExtension = self._GetFileExtension() + elif self._GetNextToken(): + if self._Token not in { + T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32, + BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, + "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX, + BINARY_FILE_TYPE_UI, "VERSION", + BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID, + BINARY_FILE_TYPE_SMM_DEPEX}: + FvImageSectionObj.FvFileName = self._Token + else: + self._UndoToken() + else: + raise Warning.Expected("FV file name", self.FileName, self.CurrentLineNumber) + + Obj.SectionList.append(FvImageSectionObj) + return True + + EfiSectionObj.SectionType = SectionName + + if not self._GetNextToken(): + raise Warning.Expected("file type", self.FileName, self.CurrentLineNumber) + + if self._Token == "STRING": + if not self._RuleSectionCouldHaveString(EfiSectionObj.SectionType): + raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + + if not self._GetNextToken(): + raise Warning.Expected("Quoted String", self.FileName, self.CurrentLineNumber) + + if self._GetStringData(): + EfiSectionObj.StringData = self._Token + + if self._IsKeyword("BUILD_NUM"): + if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType): + raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken(): + raise Warning.Expected("Build number", self.FileName, self.CurrentLineNumber) + EfiSectionObj.BuildNum = self._Token + + else: + EfiSectionObj.FileType = self._Token + self._CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType) + + if self._IsKeyword("Optional"): + if not self._RuleSectionCouldBeOptional(EfiSectionObj.SectionType): + raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + EfiSectionObj.Optional = True + + if self._IsKeyword("BUILD_NUM"): + if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType): + raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber) + + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken(): + raise Warning.Expected("Build number", self.FileName, self.CurrentLineNumber) + EfiSectionObj.BuildNum = self._Token + + if self._GetAlignment(): + if self._Token not in ALIGNMENTS: + raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE): + raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) + EfiSectionObj.Alignment = self._Token + + if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'): + if self._SectionCouldHaveRelocFlag(EfiSectionObj.SectionType): + if self._Token == 'RELOCS_STRIPPED': + EfiSectionObj.KeepReloc = False + else: + EfiSectionObj.KeepReloc = True + if Obj.KeepReloc is not None and Obj.KeepReloc != EfiSectionObj.KeepReloc: + raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber) + else: + raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber) + + + if self._IsToken(TAB_VALUE_SPLIT): + EfiSectionObj.FileExtension = self._GetFileExtension() + elif self._GetNextToken(): + if self._Token not in { + T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32, + BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, + "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX, + BINARY_FILE_TYPE_UI, "VERSION", + BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID, + BINARY_FILE_TYPE_SMM_DEPEX}: + + if self._Token.startswith('PCD'): + self._UndoToken() + self._GetNextWord() + + if self._Token == 'PCD': + if not self._IsToken("("): + raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber) + PcdPair = self._GetNextPcdSettings() + if not self._IsToken(")"): + raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber) + self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')' + + EfiSectionObj.FileName = self._Token + + else: + self._UndoToken() + else: + raise Warning.Expected("section file name", self.FileName, self.CurrentLineNumber) + + Obj.SectionList.append(EfiSectionObj) + return True + + ## _RuleSectionCouldBeOptional() method + # + # Get whether a section could be optional + # + # @param SectionType The section type to check + # @retval True section could be optional + # @retval False section never optional + # + @staticmethod + def _RuleSectionCouldBeOptional(SectionType): + if SectionType in {BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "RAW", BINARY_FILE_TYPE_SMM_DEPEX}: + return True + else: + return False + + ## _RuleSectionCouldHaveBuildNum() method + # + # Get whether a section could have build number information + # + # @param SectionType The section type to check + # @retval True section could have build number information + # @retval False section never have build number information + # + @staticmethod + def _RuleSectionCouldHaveBuildNum(SectionType): + if SectionType == "VERSION": + return True + else: + return False + + ## _RuleSectionCouldHaveString() method + # + # Get whether a section could have string + # + # @param SectionType The section type to check + # @retval True section could have string + # @retval False section never have string + # + @staticmethod + def _RuleSectionCouldHaveString(SectionType): + if SectionType in {BINARY_FILE_TYPE_UI, "VERSION"}: + return True + else: + return False + + ## _CheckRuleSectionFileType() method + # + # Get whether a section matches a file type + # + # @param self The object pointer + # @param SectionType The section type to check + # @param FileType The file type to check + # + def _CheckRuleSectionFileType(self, SectionType, FileType): + WarningString = "Incorrect section file type '%s'" + if SectionType == "COMPAT16": + if FileType not in {"COMPAT16", "SEC_COMPAT16"}: + raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == BINARY_FILE_TYPE_PE32: + if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_PE32"}: + raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == BINARY_FILE_TYPE_PIC: + if FileType not in {BINARY_FILE_TYPE_PIC, "SEC_PIC"}: + raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == BINARY_FILE_TYPE_TE: + if FileType not in {BINARY_FILE_TYPE_TE, "SEC_TE"}: + raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "RAW": + if FileType not in {BINARY_FILE_TYPE_BIN, "SEC_BIN", "RAW", "ASL", "ACPI"}: + raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == BINARY_FILE_TYPE_DXE_DEPEX or SectionType == BINARY_FILE_TYPE_SMM_DEPEX: + if FileType not in {BINARY_FILE_TYPE_DXE_DEPEX, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX}: + raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == BINARY_FILE_TYPE_UI: + if FileType not in {BINARY_FILE_TYPE_UI, "SEC_UI"}: + raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == "VERSION": + if FileType not in {"VERSION", "SEC_VERSION"}: + raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == BINARY_FILE_TYPE_PEI_DEPEX: + if FileType not in {BINARY_FILE_TYPE_PEI_DEPEX, "SEC_PEI_DEPEX"}: + raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) + elif SectionType == BINARY_FILE_TYPE_GUID: + if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_GUID"}: + raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber) + + ## _GetRuleEncapsulationSection() method + # + # Get encapsulation section for Rule + # + # @param self The object pointer + # @param theRule for whom section is got + # @retval True Successfully find section statement + # @retval False Not able to find section statement + # + def _GetRuleEncapsulationSection(self, theRule): + if self._IsKeyword("COMPRESS"): + Type = "PI_STD" + if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"): + Type = self._Token + + if not self._IsToken("{"): + raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber) + + CompressSectionObj = CompressSection() + + CompressSectionObj.CompType = Type + # Recursive sections... + while True: + IsEncapsulate = self._GetRuleEncapsulationSection(CompressSectionObj) + IsLeaf = self._GetEfiSection(CompressSectionObj) + if not IsEncapsulate and not IsLeaf: + break + + if not self._IsToken(T_CHAR_BRACE_R): + raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber) + theRule.SectionList.append(CompressSectionObj) + + return True + + elif self._IsKeyword("GUIDED"): + GuidValue = None + if self._GetNextGuid(): + if self._Token in GlobalData.gGuidDict: + self._Token = GuidStructureStringToGuidString(GlobalData.gGuidDict[self._Token]).upper() + GuidValue = self._Token + + if self._IsKeyword("$(NAMED_GUID)"): + GuidValue = self._Token + + AttribDict = self._GetGuidAttrib() + + if not self._IsToken("{"): + raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber) + GuidSectionObj = GuidSection() + GuidSectionObj.NameGuid = GuidValue + GuidSectionObj.SectionType = "GUIDED" + GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"] + GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"] + GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"] + + # Efi sections... + while True: + IsEncapsulate = self._GetRuleEncapsulationSection(GuidSectionObj) + IsLeaf = self._GetEfiSection(GuidSectionObj) + if not IsEncapsulate and not IsLeaf: + break + + if not self._IsToken(T_CHAR_BRACE_R): + raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber) + theRule.SectionList.append(GuidSectionObj) + + return True + + return False + + ## _GetOptionRom() method + # + # Get OptionROM section contents and store its data into OptionROM list of self.Profile + # + # @param self The object pointer + # @retval True Successfully find a OptionROM + # @retval False Not able to find a OptionROM + # + def _GetOptionRom(self): + if not self._GetNextToken(): + return False + + S = self._Token.upper() + if S.startswith(TAB_SECTION_START) and not S.startswith("[OPTIONROM."): + self.SectionParser(S) + self._UndoToken() + return False + + self._UndoToken() + if not self._IsToken("[OptionRom.", True): + raise Warning("Unknown Keyword '%s'" % self._Token, self.FileName, self.CurrentLineNumber) + + OptRomName = self._GetUiName() + + if not self._IsToken(TAB_SECTION_END): + raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber) + + OptRomObj = OPTIONROM(OptRomName) + self.Profile.OptRomDict[OptRomName] = OptRomObj + + while True: + isInf = self._GetOptRomInfStatement(OptRomObj) + isFile = self._GetOptRomFileStatement(OptRomObj) + if not isInf and not isFile: + break + + return True + + ## _GetOptRomInfStatement() method + # + # Get INF statements + # + # @param self The object pointer + # @param Obj for whom inf statement is got + # @retval True Successfully find inf statement + # @retval False Not able to find inf statement + # + def _GetOptRomInfStatement(self, Obj): + if not self._IsKeyword("INF"): + return False + + ffsInf = OptRomInfStatement() + self._GetInfOptions(ffsInf) + + if not self._GetNextToken(): + raise Warning.Expected("INF file path", self.FileName, self.CurrentLineNumber) + ffsInf.InfFileName = self._Token + if ffsInf.InfFileName.replace(TAB_WORKSPACE, '').find('$') == -1: + #check for file path + ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate() + if ErrorCode != 0: + EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) + + NewFileName = ffsInf.InfFileName + if ffsInf.OverrideGuid: + NewFileName = ProcessDuplicatedInf(PathClass(ffsInf.InfFileName,GenFdsGlobalVariable.WorkSpaceDir), ffsInf.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir).Path + + if not NewFileName in self.Profile.InfList: + self.Profile.InfList.append(NewFileName) + FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) + self.Profile.InfFileLineList.append(FileLineTuple) + if ffsInf.UseArch: + if ffsInf.UseArch not in self.Profile.InfDict: + self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName] + else: + self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName) + else: + self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName) + + + self._GetOptRomOverrides (ffsInf) + + Obj.FfsList.append(ffsInf) + return True + + ## _GetOptRomOverrides() method + # + # Get overrides for OptROM INF & FILE + # + # @param self The object pointer + # @param FfsInfObj for whom overrides is got + # + def _GetOptRomOverrides(self, Obj): + if self._IsToken('{'): + Overrides = OverrideAttribs() + while True: + if self._IsKeyword("PCI_VENDOR_ID"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextHexNumber(): + raise Warning.Expected("Hex vendor id", self.FileName, self.CurrentLineNumber) + Overrides.PciVendorId = self._Token + continue + + if self._IsKeyword("PCI_CLASS_CODE"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextHexNumber(): + raise Warning.Expected("Hex class code", self.FileName, self.CurrentLineNumber) + Overrides.PciClassCode = self._Token + continue + + if self._IsKeyword("PCI_DEVICE_ID"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + # Get a list of PCI IDs + Overrides.PciDeviceId = "" + while (self._GetNextHexNumber()): + Overrides.PciDeviceId = "{} {}".format(Overrides.PciDeviceId, self._Token) + if not Overrides.PciDeviceId: + raise Warning.Expected("one or more Hex device ids", self.FileName, self.CurrentLineNumber) + continue + + if self._IsKeyword("PCI_REVISION"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextHexNumber(): + raise Warning.Expected("Hex revision", self.FileName, self.CurrentLineNumber) + Overrides.PciRevision = self._Token + continue + + if self._IsKeyword("PCI_COMPRESS"): + if not self._IsToken(TAB_EQUAL_SPLIT): + raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber) + if not self._GetNextToken(): + raise Warning.Expected("TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber) + Overrides.NeedCompress = self._Token.upper() == 'TRUE' + continue + + if self._IsToken(T_CHAR_BRACE_R): + break + else: + EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber) + + Obj.OverrideAttribs = Overrides + + ## _GetOptRomFileStatement() method + # + # Get FILE statements + # + # @param self The object pointer + # @param Obj for whom FILE statement is got + # @retval True Successfully find FILE statement + # @retval False Not able to find FILE statement + # + def _GetOptRomFileStatement(self, Obj): + if not self._IsKeyword("FILE"): + return False + + FfsFileObj = OptRomFileStatement() + + if not self._IsKeyword("EFI") and not self._IsKeyword(BINARY_FILE_TYPE_BIN): + raise Warning.Expected("Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber) + FfsFileObj.FileType = self._Token + + if not self._GetNextToken(): + raise Warning.Expected("File path", self.FileName, self.CurrentLineNumber) + FfsFileObj.FileName = self._Token + if FfsFileObj.FileName.replace(TAB_WORKSPACE, '').find('$') == -1: + #check for file path + ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate() + if ErrorCode != 0: + EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) + + if FfsFileObj.FileType == 'EFI': + self._GetOptRomOverrides(FfsFileObj) + + Obj.FfsList.append(FfsFileObj) + + return True + + ## _GetCapInFd() method + # + # Get Cap list contained in FD + # + # @param self The object pointer + # @param FdName FD name + # @retval CapList List of Capsule in FD + # + def _GetCapInFd (self, FdName): + CapList = [] + if FdName.upper() in self.Profile.FdDict: + FdObj = self.Profile.FdDict[FdName.upper()] + for elementRegion in FdObj.RegionList: + if elementRegion.RegionType == 'CAPSULE': + for elementRegionData in elementRegion.RegionDataList: + if elementRegionData.endswith(".cap"): + continue + if elementRegionData is not None and elementRegionData.upper() not in CapList: + CapList.append(elementRegionData.upper()) + return CapList + + ## _GetReferencedFdCapTuple() method + # + # Get FV and FD list referenced by a capsule image + # + # @param self The object pointer + # @param CapObj Capsule section to be searched + # @param RefFdList referenced FD by section + # @param RefFvList referenced FV by section + # + def _GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []): + for CapsuleDataObj in CapObj.CapsuleDataList: + if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName is not None and CapsuleDataObj.FvName.upper() not in RefFvList: + RefFvList.append (CapsuleDataObj.FvName.upper()) + elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName is not None and CapsuleDataObj.FdName.upper() not in RefFdList: + RefFdList.append (CapsuleDataObj.FdName.upper()) + elif CapsuleDataObj.Ffs is not None: + if isinstance(CapsuleDataObj.Ffs, FileStatement): + if CapsuleDataObj.Ffs.FvName is not None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList: + RefFvList.append(CapsuleDataObj.Ffs.FvName.upper()) + elif CapsuleDataObj.Ffs.FdName is not None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList: + RefFdList.append(CapsuleDataObj.Ffs.FdName.upper()) + else: + self._GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList) + + ## _GetFvInFd() method + # + # Get FV list contained in FD + # + # @param self The object pointer + # @param FdName FD name + # @retval FvList list of FV in FD + # + def _GetFvInFd (self, FdName): + FvList = [] + if FdName.upper() in self.Profile.FdDict: + FdObj = self.Profile.FdDict[FdName.upper()] + for elementRegion in FdObj.RegionList: + if elementRegion.RegionType == BINARY_FILE_TYPE_FV: + for elementRegionData in elementRegion.RegionDataList: + if elementRegionData.endswith(".fv"): + continue + if elementRegionData is not None and elementRegionData.upper() not in FvList: + FvList.append(elementRegionData.upper()) + return FvList + + ## _GetReferencedFdFvTuple() method + # + # Get FD and FV list referenced by a FFS file + # + # @param self The object pointer + # @param FfsFile contains sections to be searched + # @param RefFdList referenced FD by section + # @param RefFvList referenced FV by section + # + def _GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []): + for FfsObj in FvObj.FfsList: + if isinstance(FfsObj, FileStatement): + if FfsObj.FvName is not None and FfsObj.FvName.upper() not in RefFvList: + RefFvList.append(FfsObj.FvName.upper()) + elif FfsObj.FdName is not None and FfsObj.FdName.upper() not in RefFdList: + RefFdList.append(FfsObj.FdName.upper()) + else: + self._GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList) + + ## _GetReferencedFdFvTupleFromSection() method + # + # Get FD and FV list referenced by a FFS section + # + # @param self The object pointer + # @param FfsFile contains sections to be searched + # @param FdList referenced FD by section + # @param FvList referenced FV by section + # + def _GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []): + SectionStack = list(FfsFile.SectionList) + while SectionStack != []: + SectionObj = SectionStack.pop() + if isinstance(SectionObj, FvImageSection): + if SectionObj.FvName is not None and SectionObj.FvName.upper() not in FvList: + FvList.append(SectionObj.FvName.upper()) + if SectionObj.Fv is not None and SectionObj.Fv.UiFvName is not None and SectionObj.Fv.UiFvName.upper() not in FvList: + FvList.append(SectionObj.Fv.UiFvName.upper()) + self._GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList) + + if isinstance(SectionObj, CompressSection) or isinstance(SectionObj, GuidSection): + SectionStack.extend(SectionObj.SectionList) + + ## CycleReferenceCheck() method + # + # Check whether cycle reference exists in FDF + # + # @param self The object pointer + # @retval True cycle reference exists + # @retval False Not exists cycle reference + # + def CycleReferenceCheck(self): + # + # Check the cycle between FV and FD image + # + MaxLength = len (self.Profile.FvDict) + for FvName in self.Profile.FvDict: + LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName + RefFvStack = set(FvName) + FdAnalyzedList = set() + + Index = 0 + while RefFvStack and Index < MaxLength: + Index = Index + 1 + FvNameFromStack = RefFvStack.pop() + if FvNameFromStack.upper() in self.Profile.FvDict: + FvObj = self.Profile.FvDict[FvNameFromStack.upper()] + else: + continue + + RefFdList = [] + RefFvList = [] + self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList) + + for RefFdName in RefFdList: + if RefFdName in FdAnalyzedList: + continue + + LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName) + FvInFdList = self._GetFvInFd(RefFdName) + if FvInFdList != []: + for FvNameInFd in FvInFdList: + LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd) + if FvNameInFd not in RefFvStack: + RefFvStack.add(FvNameInFd) + + if FvName in RefFvStack or FvNameFromStack in RefFvStack: + EdkLogger.info(LogStr) + return True + FdAnalyzedList.add(RefFdName) + + for RefFvName in RefFvList: + LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName) + if RefFvName not in RefFvStack: + RefFvStack.add(RefFvName) + + if FvName in RefFvStack or FvNameFromStack in RefFvStack: + EdkLogger.info(LogStr) + return True + + # + # Check the cycle between Capsule and FD image + # + MaxLength = len (self.Profile.CapsuleDict) + for CapName in self.Profile.CapsuleDict: + # + # Capsule image to be checked. + # + LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName + RefCapStack = {CapName} + FdAnalyzedList = set() + FvAnalyzedList = set() + + Index = 0 + while RefCapStack and Index < MaxLength: + Index = Index + 1 + CapNameFromStack = RefCapStack.pop() + if CapNameFromStack.upper() in self.Profile.CapsuleDict: + CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()] + else: + continue + + RefFvList = [] + RefFdList = [] + self._GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList) + + FvListLength = 0 + FdListLength = 0 + while FvListLength < len (RefFvList) or FdListLength < len (RefFdList): + for RefFdName in RefFdList: + if RefFdName in FdAnalyzedList: + continue + + LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName) + for CapNameInFd in self._GetCapInFd(RefFdName): + LogStr += "FD %s contains Capsule %s\n" % (RefFdName, CapNameInFd) + if CapNameInFd not in RefCapStack: + RefCapStack.append(CapNameInFd) + + if CapName in RefCapStack or CapNameFromStack in RefCapStack: + EdkLogger.info(LogStr) + return True + + for FvNameInFd in self._GetFvInFd(RefFdName): + LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd) + if FvNameInFd not in RefFvList: + RefFvList.append(FvNameInFd) + + FdAnalyzedList.add(RefFdName) + # + # the number of the parsed FV and FD image + # + FvListLength = len (RefFvList) + FdListLength = len (RefFdList) + for RefFvName in RefFvList: + if RefFvName in FvAnalyzedList: + continue + LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName) + if RefFvName.upper() in self.Profile.FvDict: + FvObj = self.Profile.FvDict[RefFvName.upper()] + else: + continue + self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList) + FvAnalyzedList.add(RefFvName) + + return False + + def GetAllIncludedFile (self): + global AllIncludeFileList + return AllIncludeFileList + +if __name__ == "__main__": + import sys + try: + test_file = sys.argv[1] + except IndexError as v: + print("Usage: %s filename" % sys.argv[0]) + sys.exit(1) + + parser = FdfParser(test_file) + try: + parser.ParseFile() + parser.CycleReferenceCheck() + except Warning as X: + print(str(X)) + else: + print("Success!") + diff --git a/BaseTools/Source/Python/GenFds/Ffs.py b/BaseTools/Source/Python/GenFds/Ffs.py index 4e58df279b..f55524c3ed 100644 --- a/BaseTools/Source/Python/GenFds/Ffs.py +++ b/BaseTools/Source/Python/GenFds/Ffs.py @@ -1,49 +1,49 @@ -## @file
-# process FFS generation
-#
-# Copyright (c) 2007-2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from Common.DataType import *
-
-# mapping between FILE type in FDF and file type for GenFfs
-FdfFvFileTypeToFileType = {
- SUP_MODULE_SEC : 'EFI_FV_FILETYPE_SECURITY_CORE',
- SUP_MODULE_PEI_CORE : 'EFI_FV_FILETYPE_PEI_CORE',
- SUP_MODULE_PEIM : 'EFI_FV_FILETYPE_PEIM',
- SUP_MODULE_DXE_CORE : 'EFI_FV_FILETYPE_DXE_CORE',
- 'FREEFORM' : 'EFI_FV_FILETYPE_FREEFORM',
- 'DRIVER' : 'EFI_FV_FILETYPE_DRIVER',
- 'APPLICATION' : 'EFI_FV_FILETYPE_APPLICATION',
- 'FV_IMAGE' : 'EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE',
- 'RAW' : 'EFI_FV_FILETYPE_RAW',
- 'PEI_DXE_COMBO' : 'EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER',
- 'SMM' : 'EFI_FV_FILETYPE_SMM',
- SUP_MODULE_SMM_CORE : 'EFI_FV_FILETYPE_SMM_CORE',
- SUP_MODULE_MM_STANDALONE : 'EFI_FV_FILETYPE_MM_STANDALONE',
- SUP_MODULE_MM_CORE_STANDALONE : 'EFI_FV_FILETYPE_MM_CORE_STANDALONE'
-}
-
-# mapping between section type in FDF and file suffix
-SectionSuffix = {
- BINARY_FILE_TYPE_PE32 : '.pe32',
- BINARY_FILE_TYPE_PIC : '.pic',
- BINARY_FILE_TYPE_TE : '.te',
- BINARY_FILE_TYPE_DXE_DEPEX : '.dpx',
- 'VERSION' : '.ver',
- BINARY_FILE_TYPE_UI : '.ui',
- 'COMPAT16' : '.com16',
- 'RAW' : '.raw',
- 'FREEFORM_SUBTYPE_GUID': '.guid',
- 'SUBTYPE_GUID' : '.guid',
- 'FV_IMAGE' : 'fv.sec',
- 'COMPRESS' : '.com',
- 'GUIDED' : '.guided',
- BINARY_FILE_TYPE_PEI_DEPEX : '.dpx',
- BINARY_FILE_TYPE_SMM_DEPEX : '.dpx'
-}
+## @file +# process FFS generation +# +# Copyright (c) 2007-2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from Common.DataType import * + +# mapping between FILE type in FDF and file type for GenFfs +FdfFvFileTypeToFileType = { + SUP_MODULE_SEC : 'EFI_FV_FILETYPE_SECURITY_CORE', + SUP_MODULE_PEI_CORE : 'EFI_FV_FILETYPE_PEI_CORE', + SUP_MODULE_PEIM : 'EFI_FV_FILETYPE_PEIM', + SUP_MODULE_DXE_CORE : 'EFI_FV_FILETYPE_DXE_CORE', + 'FREEFORM' : 'EFI_FV_FILETYPE_FREEFORM', + 'DRIVER' : 'EFI_FV_FILETYPE_DRIVER', + 'APPLICATION' : 'EFI_FV_FILETYPE_APPLICATION', + 'FV_IMAGE' : 'EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE', + 'RAW' : 'EFI_FV_FILETYPE_RAW', + 'PEI_DXE_COMBO' : 'EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER', + 'SMM' : 'EFI_FV_FILETYPE_SMM', + SUP_MODULE_SMM_CORE : 'EFI_FV_FILETYPE_SMM_CORE', + SUP_MODULE_MM_STANDALONE : 'EFI_FV_FILETYPE_MM_STANDALONE', + SUP_MODULE_MM_CORE_STANDALONE : 'EFI_FV_FILETYPE_MM_CORE_STANDALONE' +} + +# mapping between section type in FDF and file suffix +SectionSuffix = { + BINARY_FILE_TYPE_PE32 : '.pe32', + BINARY_FILE_TYPE_PIC : '.pic', + BINARY_FILE_TYPE_TE : '.te', + BINARY_FILE_TYPE_DXE_DEPEX : '.dpx', + 'VERSION' : '.ver', + BINARY_FILE_TYPE_UI : '.ui', + 'COMPAT16' : '.com16', + 'RAW' : '.raw', + 'FREEFORM_SUBTYPE_GUID': '.guid', + 'SUBTYPE_GUID' : '.guid', + 'FV_IMAGE' : 'fv.sec', + 'COMPRESS' : '.com', + 'GUIDED' : '.guided', + BINARY_FILE_TYPE_PEI_DEPEX : '.dpx', + BINARY_FILE_TYPE_SMM_DEPEX : '.dpx' +} diff --git a/BaseTools/Source/Python/GenFds/FfsFileStatement.py b/BaseTools/Source/Python/GenFds/FfsFileStatement.py index 1c6e59bac7..7ab1507d04 100644 --- a/BaseTools/Source/Python/GenFds/FfsFileStatement.py +++ b/BaseTools/Source/Python/GenFds/FfsFileStatement.py @@ -1,175 +1,175 @@ -## @file
-# process FFS generation from FILE statement
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from io import BytesIO
-from struct import pack
-from CommonDataClass.FdfClass import FileStatementClassObject
-from Common import EdkLogger
-from Common.BuildToolError import GENFDS_ERROR
-from Common.Misc import GuidStructureByteArrayToGuidString, SaveFileOnChange
-import Common.LongFilePathOs as os
-from .GuidSection import GuidSection
-from .FvImageSection import FvImageSection
-from .Ffs import FdfFvFileTypeToFileType
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-import shutil
-
-## generate FFS from FILE
-#
-#
-class FileStatement (FileStatementClassObject):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- FileStatementClassObject.__init__(self)
- self.CurrentLineNum = None
- self.CurrentLineContent = None
- self.FileName = None
- self.InfFileName = None
- self.SubAlignment = None
-
- ## 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):
-
- if self.NameGuid and self.NameGuid.startswith('PCD('):
- PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid)
- if len(PcdValue) == 0:
- EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
- % (self.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.' \
- % (self.NameGuid))
- self.NameGuid = RegistryGuidStr
-
- Str = self.NameGuid
- if FvName:
- Str += FvName
- OutputDir = os.path.join(GenFdsGlobalVariable.FfsDir, Str)
- if os.path.exists(OutputDir):
- shutil.rmtree(OutputDir)
- if not os.path.exists(OutputDir):
- os.makedirs(OutputDir)
-
- if Dict is None:
- Dict = {}
-
- Dict.update(self.DefineVarDict)
- SectionAlignments = None
- if self.FvName:
- Buffer = BytesIO()
- if self.FvName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FvDict:
- EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (self.FvName))
- Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper())
- FileName = Fv.AddToBuffer(Buffer)
- SectionFiles = [FileName]
-
- elif self.FdName:
- if self.FdName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FdDict:
- EdkLogger.error("GenFds", GENFDS_ERROR, "FD (%s) is NOT described in FDF file!" % (self.FdName))
- Fd = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(self.FdName.upper())
- FileName = Fd.GenFd()
- SectionFiles = [FileName]
-
- elif self.FileName:
- if hasattr(self, 'FvFileType') and self.FvFileType == 'RAW':
- if isinstance(self.FileName, list) and isinstance(self.SubAlignment, list) and len(self.FileName) == len(self.SubAlignment):
- FileContent = BytesIO()
- MaxAlignIndex = 0
- MaxAlignValue = 1
- for Index, File in enumerate(self.FileName):
- try:
- f = open(File, 'rb')
- except:
- GenFdsGlobalVariable.ErrorLogger("Error opening RAW file %s." % (File))
- Content = f.read()
- f.close()
- AlignValue = 1
- if self.SubAlignment[Index]:
- AlignValue = GenFdsGlobalVariable.GetAlignment(self.SubAlignment[Index])
- if AlignValue > MaxAlignValue:
- MaxAlignIndex = Index
- MaxAlignValue = AlignValue
- FileContent.write(Content)
- if len(FileContent.getvalue()) % AlignValue != 0:
- Size = AlignValue - len(FileContent.getvalue()) % AlignValue
- for i in range(0, Size):
- FileContent.write(pack('B', 0xFF))
-
- if FileContent.getvalue() != b'':
- OutputRAWFile = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid, self.NameGuid + '.raw')
- SaveFileOnChange(OutputRAWFile, FileContent.getvalue(), True)
- self.FileName = OutputRAWFile
- self.SubAlignment = self.SubAlignment[MaxAlignIndex]
-
- if self.Alignment and self.SubAlignment:
- if GenFdsGlobalVariable.GetAlignment (self.Alignment) < GenFdsGlobalVariable.GetAlignment (self.SubAlignment):
- self.Alignment = self.SubAlignment
- elif self.SubAlignment:
- self.Alignment = self.SubAlignment
-
- self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
- #Replace $(SAPCE) with real space
- self.FileName = self.FileName.replace('$(SPACE)', ' ')
- SectionFiles = [GenFdsGlobalVariable.MacroExtend(self.FileName, Dict)]
-
- else:
- SectionFiles = []
- Index = 0
- SectionAlignments = []
- for section in self.SectionList:
- Index = Index + 1
- SecIndex = '%d' %Index
- # process the inside FvImage from FvSection or GuidSection
- if FvChildAddr != []:
- if isinstance(section, FvImageSection):
- section.FvAddr = FvChildAddr.pop(0)
- elif isinstance(section, GuidSection):
- section.FvAddr = FvChildAddr
- if FvParentAddr and isinstance(section, GuidSection):
- section.FvParentAddr = FvParentAddr
-
- if self.KeepReloc == False:
- section.KeepReloc = False
- sectList, align = section.GenSection(OutputDir, self.NameGuid, SecIndex, self.KeyStringList, None, Dict)
- if sectList != []:
- for sect in sectList:
- SectionFiles.append(sect)
- SectionAlignments.append(align)
-
- #
- # Prepare the parameter
- #
- FfsFileOutput = os.path.join(OutputDir, self.NameGuid + '.ffs')
- GenFdsGlobalVariable.GenerateFfs(FfsFileOutput, SectionFiles,
- FdfFvFileTypeToFileType.get(self.FvFileType),
- self.NameGuid,
- Fixed=self.Fixed,
- CheckSum=self.CheckSum,
- Align=self.Alignment,
- SectionAlign=SectionAlignments
- )
-
- return FfsFileOutput
+## @file +# process FFS generation from FILE statement +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from io import BytesIO +from struct import pack +from CommonDataClass.FdfClass import FileStatementClassObject +from Common import EdkLogger +from Common.BuildToolError import GENFDS_ERROR +from Common.Misc import GuidStructureByteArrayToGuidString, SaveFileOnChange +import Common.LongFilePathOs as os +from .GuidSection import GuidSection +from .FvImageSection import FvImageSection +from .Ffs import FdfFvFileTypeToFileType +from .GenFdsGlobalVariable import GenFdsGlobalVariable +import shutil + +## generate FFS from FILE +# +# +class FileStatement (FileStatementClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FileStatementClassObject.__init__(self) + self.CurrentLineNum = None + self.CurrentLineContent = None + self.FileName = None + self.InfFileName = None + self.SubAlignment = None + + ## 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): + + if self.NameGuid and self.NameGuid.startswith('PCD('): + PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid) + if len(PcdValue) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \ + % (self.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.' \ + % (self.NameGuid)) + self.NameGuid = RegistryGuidStr + + Str = self.NameGuid + if FvName: + Str += FvName + OutputDir = os.path.join(GenFdsGlobalVariable.FfsDir, Str) + if os.path.exists(OutputDir): + shutil.rmtree(OutputDir) + if not os.path.exists(OutputDir): + os.makedirs(OutputDir) + + if Dict is None: + Dict = {} + + Dict.update(self.DefineVarDict) + SectionAlignments = None + if self.FvName: + Buffer = BytesIO() + if self.FvName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FvDict: + EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (self.FvName)) + Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName.upper()) + FileName = Fv.AddToBuffer(Buffer) + SectionFiles = [FileName] + + elif self.FdName: + if self.FdName.upper() not in GenFdsGlobalVariable.FdfParser.Profile.FdDict: + EdkLogger.error("GenFds", GENFDS_ERROR, "FD (%s) is NOT described in FDF file!" % (self.FdName)) + Fd = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get(self.FdName.upper()) + FileName = Fd.GenFd() + SectionFiles = [FileName] + + elif self.FileName: + if hasattr(self, 'FvFileType') and self.FvFileType == 'RAW': + if isinstance(self.FileName, list) and isinstance(self.SubAlignment, list) and len(self.FileName) == len(self.SubAlignment): + FileContent = BytesIO() + MaxAlignIndex = 0 + MaxAlignValue = 1 + for Index, File in enumerate(self.FileName): + try: + f = open(File, 'rb') + except: + GenFdsGlobalVariable.ErrorLogger("Error opening RAW file %s." % (File)) + Content = f.read() + f.close() + AlignValue = 1 + if self.SubAlignment[Index]: + AlignValue = GenFdsGlobalVariable.GetAlignment(self.SubAlignment[Index]) + if AlignValue > MaxAlignValue: + MaxAlignIndex = Index + MaxAlignValue = AlignValue + FileContent.write(Content) + if len(FileContent.getvalue()) % AlignValue != 0: + Size = AlignValue - len(FileContent.getvalue()) % AlignValue + for i in range(0, Size): + FileContent.write(pack('B', 0xFF)) + + if FileContent.getvalue() != b'': + OutputRAWFile = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid, self.NameGuid + '.raw') + SaveFileOnChange(OutputRAWFile, FileContent.getvalue(), True) + self.FileName = OutputRAWFile + self.SubAlignment = self.SubAlignment[MaxAlignIndex] + + if self.Alignment and self.SubAlignment: + if GenFdsGlobalVariable.GetAlignment (self.Alignment) < GenFdsGlobalVariable.GetAlignment (self.SubAlignment): + self.Alignment = self.SubAlignment + elif self.SubAlignment: + self.Alignment = self.SubAlignment + + self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName) + #Replace $(SAPCE) with real space + self.FileName = self.FileName.replace('$(SPACE)', ' ') + SectionFiles = [GenFdsGlobalVariable.MacroExtend(self.FileName, Dict)] + + else: + SectionFiles = [] + Index = 0 + SectionAlignments = [] + for section in self.SectionList: + Index = Index + 1 + SecIndex = '%d' %Index + # process the inside FvImage from FvSection or GuidSection + if FvChildAddr != []: + if isinstance(section, FvImageSection): + section.FvAddr = FvChildAddr.pop(0) + elif isinstance(section, GuidSection): + section.FvAddr = FvChildAddr + if FvParentAddr and isinstance(section, GuidSection): + section.FvParentAddr = FvParentAddr + + if self.KeepReloc == False: + section.KeepReloc = False + sectList, align = section.GenSection(OutputDir, self.NameGuid, SecIndex, self.KeyStringList, None, Dict) + if sectList != []: + for sect in sectList: + SectionFiles.append(sect) + SectionAlignments.append(align) + + # + # Prepare the parameter + # + FfsFileOutput = os.path.join(OutputDir, self.NameGuid + '.ffs') + GenFdsGlobalVariable.GenerateFfs(FfsFileOutput, SectionFiles, + FdfFvFileTypeToFileType.get(self.FvFileType), + self.NameGuid, + Fixed=self.Fixed, + CheckSum=self.CheckSum, + Align=self.Alignment, + SectionAlign=SectionAlignments + ) + + return FfsFileOutput 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 () + + diff --git a/BaseTools/Source/Python/GenFds/Fv.py b/BaseTools/Source/Python/GenFds/Fv.py index 16c944a0bd..798eb1f598 100644 --- a/BaseTools/Source/Python/GenFds/Fv.py +++ b/BaseTools/Source/Python/GenFds/Fv.py @@ -1,431 +1,431 @@ -## @file
-# process FV generation
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-import Common.LongFilePathOs as os
-import subprocess
-from io import BytesIO
-from struct import *
-from . import FfsFileStatement
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-from Common.Misc import SaveFileOnChange, PackGUID
-from Common.LongFilePathSupport import CopyLongFilePath
-from Common.LongFilePathSupport import OpenLongFilePath as open
-from Common.DataType import *
-
-FV_UI_EXT_ENTY_GUID = 'A67DF1FA-8DE8-4E98-AF09-4BDF2EFFBC7C'
-
-## generate FV
-#
-#
-class FV (object):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self, Name=None):
- self.UiFvName = Name
- self.CreateFileName = None
- self.BlockSizeList = []
- self.DefineVarDict = {}
- self.SetVarDict = {}
- self.FvAlignment = None
- self.FvAttributeDict = {}
- self.FvNameGuid = None
- self.FvNameString = None
- self.AprioriSectionList = []
- self.FfsList = []
- self.BsBaseAddress = None
- self.RtBaseAddress = None
- self.FvInfFile = None
- self.FvAddressFile = None
- self.BaseAddress = None
- self.InfFileName = None
- self.FvAddressFileName = None
- self.CapsuleName = None
- self.FvBaseAddress = None
- self.FvForceRebase = None
- self.FvRegionInFD = None
- self.UsedSizeEnable = False
- self.FvExtEntryTypeValue = []
- self.FvExtEntryType = []
- self.FvExtEntryData = []
- ## AddToBuffer()
- #
- # Generate Fv and add it to the Buffer
- #
- # @param self The object pointer
- # @param Buffer The buffer generated FV data will be put
- # @param BaseAddress base address of FV
- # @param BlockSize block size of FV
- # @param BlockNum How many blocks in FV
- # @param ErasePolarity Flash erase polarity
- # @param MacroDict macro value pair
- # @retval string Generated FV file path
- #
- def AddToBuffer (self, Buffer, BaseAddress=None, BlockSize= None, BlockNum=None, ErasePloarity='1', MacroDict = None, Flag=False):
- if BaseAddress is None and self.UiFvName.upper() + 'fv' in GenFdsGlobalVariable.ImageBinDict:
- return GenFdsGlobalVariable.ImageBinDict[self.UiFvName.upper() + 'fv']
- if MacroDict is None:
- MacroDict = {}
-
- #
- # Check whether FV in Capsule is in FD flash region.
- # If yes, return error. Doesn't support FV in Capsule image is also in FD flash region.
- #
- if self.CapsuleName is not None:
- for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():
- for RegionObj in FdObj.RegionList:
- if RegionObj.RegionType == BINARY_FILE_TYPE_FV:
- for RegionData in RegionObj.RegionDataList:
- if RegionData.endswith(".fv"):
- continue
- elif RegionData.upper() + 'fv' in GenFdsGlobalVariable.ImageBinDict:
- continue
- elif self.UiFvName.upper() == RegionData.upper():
- GenFdsGlobalVariable.ErrorLogger("Capsule %s in FD region can't contain a FV %s in FD region." % (self.CapsuleName, self.UiFvName.upper()))
- if not Flag:
- GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV" %self.UiFvName)
- GenFdsGlobalVariable.LargeFileInFvFlags.append(False)
- FFSGuid = None
-
- if self.FvBaseAddress is not None:
- BaseAddress = self.FvBaseAddress
- if not Flag:
- self._InitializeInf(BaseAddress, BlockSize, BlockNum, ErasePloarity)
- #
- # First Process the Apriori section
- #
- MacroDict.update(self.DefineVarDict)
-
- GenFdsGlobalVariable.VerboseLogger('First generate Apriori file !')
- FfsFileList = []
- for AprSection in self.AprioriSectionList:
- FileName = AprSection.GenFfs (self.UiFvName, MacroDict, IsMakefile=Flag)
- FfsFileList.append(FileName)
- # Add Apriori file name to Inf file
- if not Flag:
- self.FvInfFile.append("EFI_FILE_NAME = " + \
- FileName + \
- TAB_LINE_BREAK)
-
- # Process Modules in FfsList
- for FfsFile in self.FfsList:
- if Flag:
- if isinstance(FfsFile, FfsFileStatement.FileStatement):
- continue
- if GenFdsGlobalVariable.EnableGenfdsMultiThread and GenFdsGlobalVariable.ModuleFile and GenFdsGlobalVariable.ModuleFile.Path.find(os.path.normpath(FfsFile.InfFileName)) == -1:
- continue
- FileName = FfsFile.GenFfs(MacroDict, FvParentAddr=BaseAddress, IsMakefile=Flag, FvName=self.UiFvName)
- FfsFileList.append(FileName)
- if not Flag:
- self.FvInfFile.append("EFI_FILE_NAME = " + \
- FileName + \
- TAB_LINE_BREAK)
- if not Flag:
- FvInfFile = ''.join(self.FvInfFile)
- SaveFileOnChange(self.InfFileName, FvInfFile, False)
- #
- # Call GenFv tool
- #
- FvOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiFvName)
- FvOutputFile = FvOutputFile + '.Fv'
- # BUGBUG: FvOutputFile could be specified from FDF file (FV section, CreateFile statement)
- if self.CreateFileName is not None:
- FvOutputFile = self.CreateFileName
-
- if Flag:
- GenFdsGlobalVariable.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile
- return FvOutputFile
-
- FvInfoFileName = os.path.join(GenFdsGlobalVariable.FfsDir, self.UiFvName + '.inf')
- if not Flag:
- CopyLongFilePath(GenFdsGlobalVariable.FvAddressFileName, FvInfoFileName)
- OrigFvInfo = None
- if os.path.exists (FvInfoFileName):
- OrigFvInfo = open(FvInfoFileName, 'r').read()
- if GenFdsGlobalVariable.LargeFileInFvFlags[-1]:
- FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID
- GenFdsGlobalVariable.GenerateFirmwareVolume(
- FvOutputFile,
- [self.InfFileName],
- AddressFile=FvInfoFileName,
- FfsList=FfsFileList,
- ForceRebase=self.FvForceRebase,
- FileSystemGuid=FFSGuid
- )
-
- NewFvInfo = None
- if os.path.exists (FvInfoFileName):
- NewFvInfo = open(FvInfoFileName, 'r').read()
- if NewFvInfo is not None and NewFvInfo != OrigFvInfo:
- FvChildAddr = []
- AddFileObj = open(FvInfoFileName, 'r')
- AddrStrings = AddFileObj.readlines()
- AddrKeyFound = False
- for AddrString in AddrStrings:
- if AddrKeyFound:
- #get base address for the inside FvImage
- FvChildAddr.append (AddrString)
- elif AddrString.find ("[FV_BASE_ADDRESS]") != -1:
- AddrKeyFound = True
- AddFileObj.close()
-
- if FvChildAddr != []:
- # Update Ffs again
- for FfsFile in self.FfsList:
- FileName = FfsFile.GenFfs(MacroDict, FvChildAddr, BaseAddress, IsMakefile=Flag, FvName=self.UiFvName)
-
- if GenFdsGlobalVariable.LargeFileInFvFlags[-1]:
- FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID;
- #Update GenFv again
- GenFdsGlobalVariable.GenerateFirmwareVolume(
- FvOutputFile,
- [self.InfFileName],
- AddressFile=FvInfoFileName,
- FfsList=FfsFileList,
- ForceRebase=self.FvForceRebase,
- FileSystemGuid=FFSGuid
- )
-
- #
- # Write the Fv contents to Buffer
- #
- if os.path.isfile(FvOutputFile) and os.path.getsize(FvOutputFile) >= 0x48:
- FvFileObj = open(FvOutputFile, 'rb')
- # PI FvHeader is 0x48 byte
- FvHeaderBuffer = FvFileObj.read(0x48)
- Signature = FvHeaderBuffer[0x28:0x32]
- if Signature and Signature.startswith(b'_FVH'):
- GenFdsGlobalVariable.VerboseLogger("\nGenerate %s FV Successfully" % self.UiFvName)
- GenFdsGlobalVariable.SharpCounter = 0
-
- FvFileObj.seek(0)
- Buffer.write(FvFileObj.read())
- # FV alignment position.
- FvAlignmentValue = 1 << (ord(FvHeaderBuffer[0x2E:0x2F]) & 0x1F)
- if FvAlignmentValue >= 0x400:
- if FvAlignmentValue >= 0x100000:
- if FvAlignmentValue >= 0x1000000:
- #The max alignment supported by FFS is 16M.
- self.FvAlignment = "16M"
- else:
- self.FvAlignment = str(FvAlignmentValue // 0x100000) + "M"
- else:
- self.FvAlignment = str(FvAlignmentValue // 0x400) + "K"
- else:
- # FvAlignmentValue is less than 1K
- self.FvAlignment = str (FvAlignmentValue)
- FvFileObj.close()
- GenFdsGlobalVariable.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile
- GenFdsGlobalVariable.LargeFileInFvFlags.pop()
- else:
- GenFdsGlobalVariable.ErrorLogger("Invalid FV file %s." % self.UiFvName)
- else:
- GenFdsGlobalVariable.ErrorLogger("Failed to generate %s FV file." %self.UiFvName)
- return FvOutputFile
-
- ## _GetBlockSize()
- #
- # Calculate FV's block size
- # Inherit block size from FD if no block size specified in FV
- #
- def _GetBlockSize(self):
- if self.BlockSizeList:
- return True
-
- for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():
- for RegionObj in FdObj.RegionList:
- if RegionObj.RegionType != BINARY_FILE_TYPE_FV:
- continue
- for RegionData in RegionObj.RegionDataList:
- #
- # Found the FD and region that contain this FV
- #
- if self.UiFvName.upper() == RegionData.upper():
- RegionObj.BlockInfoOfRegion(FdObj.BlockSizeList, self)
- if self.BlockSizeList:
- return True
- return False
-
- ## _InitializeInf()
- #
- # Initialize the inf file to create FV
- #
- # @param self The object pointer
- # @param BaseAddress base address of FV
- # @param BlockSize block size of FV
- # @param BlockNum How many blocks in FV
- # @param ErasePolarity Flash erase polarity
- #
- def _InitializeInf (self, BaseAddress = None, BlockSize= None, BlockNum = None, ErasePloarity='1'):
- #
- # Create FV inf file
- #
- self.InfFileName = os.path.join(GenFdsGlobalVariable.FvDir,
- self.UiFvName + '.inf')
- self.FvInfFile = []
-
- #
- # Add [Options]
- #
- self.FvInfFile.append("[options]" + TAB_LINE_BREAK)
- if BaseAddress is not None:
- self.FvInfFile.append("EFI_BASE_ADDRESS = " + \
- BaseAddress + \
- TAB_LINE_BREAK)
-
- if BlockSize is not None:
- self.FvInfFile.append("EFI_BLOCK_SIZE = " + \
- '0x%X' %BlockSize + \
- TAB_LINE_BREAK)
- if BlockNum is not None:
- self.FvInfFile.append("EFI_NUM_BLOCKS = " + \
- ' 0x%X' %BlockNum + \
- TAB_LINE_BREAK)
- else:
- if self.BlockSizeList == []:
- if not self._GetBlockSize():
- #set default block size is 1
- self.FvInfFile.append("EFI_BLOCK_SIZE = 0x1" + TAB_LINE_BREAK)
-
- for BlockSize in self.BlockSizeList:
- if BlockSize[0] is not None:
- self.FvInfFile.append("EFI_BLOCK_SIZE = " + \
- '0x%X' %BlockSize[0] + \
- TAB_LINE_BREAK)
-
- if BlockSize[1] is not None:
- self.FvInfFile.append("EFI_NUM_BLOCKS = " + \
- ' 0x%X' %BlockSize[1] + \
- TAB_LINE_BREAK)
-
- if self.BsBaseAddress is not None:
- self.FvInfFile.append('EFI_BOOT_DRIVER_BASE_ADDRESS = ' + \
- '0x%X' %self.BsBaseAddress)
- if self.RtBaseAddress is not None:
- self.FvInfFile.append('EFI_RUNTIME_DRIVER_BASE_ADDRESS = ' + \
- '0x%X' %self.RtBaseAddress)
- #
- # Add attribute
- #
- self.FvInfFile.append("[attributes]" + TAB_LINE_BREAK)
-
- self.FvInfFile.append("EFI_ERASE_POLARITY = " + \
- ' %s' %ErasePloarity + \
- TAB_LINE_BREAK)
- if not (self.FvAttributeDict is None):
- for FvAttribute in self.FvAttributeDict.keys():
- if FvAttribute == "FvUsedSizeEnable":
- if self.FvAttributeDict[FvAttribute].upper() in ('TRUE', '1'):
- self.UsedSizeEnable = True
- continue
- self.FvInfFile.append("EFI_" + \
- FvAttribute + \
- ' = ' + \
- self.FvAttributeDict[FvAttribute] + \
- TAB_LINE_BREAK )
- if self.FvAlignment is not None:
- self.FvInfFile.append("EFI_FVB2_ALIGNMENT_" + \
- self.FvAlignment.strip() + \
- " = TRUE" + \
- TAB_LINE_BREAK)
-
- #
- # Generate FV extension header file
- #
- if not self.FvNameGuid:
- if len(self.FvExtEntryType) > 0 or self.UsedSizeEnable:
- GenFdsGlobalVariable.ErrorLogger("FV Extension Header Entries declared for %s with no FvNameGuid declaration." % (self.UiFvName))
- else:
- TotalSize = 16 + 4
- Buffer = bytearray()
- if self.UsedSizeEnable:
- TotalSize += (4 + 4)
- ## define EFI_FV_EXT_TYPE_USED_SIZE_TYPE 0x03
- #typedef struct
- # {
- # EFI_FIRMWARE_VOLUME_EXT_ENTRY Hdr;
- # UINT32 UsedSize;
- # } EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE;
- Buffer += pack('HHL', 8, 3, 0)
-
- if self.FvNameString == 'TRUE':
- #
- # Create EXT entry for FV UI name
- # This GUID is used: A67DF1FA-8DE8-4E98-AF09-4BDF2EFFBC7C
- #
- FvUiLen = len(self.UiFvName)
- TotalSize += (FvUiLen + 16 + 4)
- Guid = FV_UI_EXT_ENTY_GUID.split('-')
- #
- # Layout:
- # EFI_FIRMWARE_VOLUME_EXT_ENTRY: size 4
- # GUID: size 16
- # FV UI name
- #
- Buffer += (pack('HH', (FvUiLen + 16 + 4), 0x0002)
- + PackGUID(Guid)
- + self.UiFvName.encode('utf-8'))
-
- for Index in range (0, len(self.FvExtEntryType)):
- if self.FvExtEntryType[Index] == 'FILE':
- # check if the path is absolute or relative
- if os.path.isabs(self.FvExtEntryData[Index]):
- FileFullPath = os.path.normpath(self.FvExtEntryData[Index])
- else:
- FileFullPath = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.FvExtEntryData[Index]))
- # check if the file path exists or not
- if not os.path.isfile(FileFullPath):
- GenFdsGlobalVariable.ErrorLogger("Error opening FV Extension Header Entry file %s." % (self.FvExtEntryData[Index]))
- FvExtFile = open (FileFullPath, 'rb')
- FvExtFile.seek(0, 2)
- Size = FvExtFile.tell()
- if Size >= 0x10000:
- GenFdsGlobalVariable.ErrorLogger("The size of FV Extension Header Entry file %s exceeds 0x10000." % (self.FvExtEntryData[Index]))
- TotalSize += (Size + 4)
- FvExtFile.seek(0)
- Buffer += pack('HH', (Size + 4), int(self.FvExtEntryTypeValue[Index], 16))
- Buffer += FvExtFile.read()
- FvExtFile.close()
- if self.FvExtEntryType[Index] == 'DATA':
- ByteList = self.FvExtEntryData[Index].split(',')
- Size = len (ByteList)
- if Size >= 0x10000:
- GenFdsGlobalVariable.ErrorLogger("The size of FV Extension Header Entry data %s exceeds 0x10000." % (self.FvExtEntryData[Index]))
- TotalSize += (Size + 4)
- Buffer += pack('HH', (Size + 4), int(self.FvExtEntryTypeValue[Index], 16))
- for Index1 in range (0, Size):
- Buffer += pack('B', int(ByteList[Index1], 16))
-
- Guid = self.FvNameGuid.split('-')
- Buffer = PackGUID(Guid) + pack('=L', TotalSize) + Buffer
-
- #
- # Generate FV extension header file if the total size is not zero
- #
- if TotalSize > 0:
- FvExtHeaderFileName = os.path.join(GenFdsGlobalVariable.FvDir, self.UiFvName + '.ext')
- FvExtHeaderFile = BytesIO()
- FvExtHeaderFile.write(Buffer)
- Changed = SaveFileOnChange(FvExtHeaderFileName, FvExtHeaderFile.getvalue(), True)
- FvExtHeaderFile.close()
- if Changed:
- if os.path.exists (self.InfFileName):
- os.remove (self.InfFileName)
- self.FvInfFile.append("EFI_FV_EXT_HEADER_FILE_NAME = " + \
- FvExtHeaderFileName + \
- TAB_LINE_BREAK)
-
- #
- # Add [Files]
- #
- self.FvInfFile.append("[files]" + TAB_LINE_BREAK)
+## @file +# process FV generation +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +import Common.LongFilePathOs as os +import subprocess +from io import BytesIO +from struct import * +from . import FfsFileStatement +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from Common.Misc import SaveFileOnChange, PackGUID +from Common.LongFilePathSupport import CopyLongFilePath +from Common.LongFilePathSupport import OpenLongFilePath as open +from Common.DataType import * + +FV_UI_EXT_ENTY_GUID = 'A67DF1FA-8DE8-4E98-AF09-4BDF2EFFBC7C' + +## generate FV +# +# +class FV (object): + ## The constructor + # + # @param self The object pointer + # + def __init__(self, Name=None): + self.UiFvName = Name + self.CreateFileName = None + self.BlockSizeList = [] + self.DefineVarDict = {} + self.SetVarDict = {} + self.FvAlignment = None + self.FvAttributeDict = {} + self.FvNameGuid = None + self.FvNameString = None + self.AprioriSectionList = [] + self.FfsList = [] + self.BsBaseAddress = None + self.RtBaseAddress = None + self.FvInfFile = None + self.FvAddressFile = None + self.BaseAddress = None + self.InfFileName = None + self.FvAddressFileName = None + self.CapsuleName = None + self.FvBaseAddress = None + self.FvForceRebase = None + self.FvRegionInFD = None + self.UsedSizeEnable = False + self.FvExtEntryTypeValue = [] + self.FvExtEntryType = [] + self.FvExtEntryData = [] + ## AddToBuffer() + # + # Generate Fv and add it to the Buffer + # + # @param self The object pointer + # @param Buffer The buffer generated FV data will be put + # @param BaseAddress base address of FV + # @param BlockSize block size of FV + # @param BlockNum How many blocks in FV + # @param ErasePolarity Flash erase polarity + # @param MacroDict macro value pair + # @retval string Generated FV file path + # + def AddToBuffer (self, Buffer, BaseAddress=None, BlockSize= None, BlockNum=None, ErasePloarity='1', MacroDict = None, Flag=False): + if BaseAddress is None and self.UiFvName.upper() + 'fv' in GenFdsGlobalVariable.ImageBinDict: + return GenFdsGlobalVariable.ImageBinDict[self.UiFvName.upper() + 'fv'] + if MacroDict is None: + MacroDict = {} + + # + # Check whether FV in Capsule is in FD flash region. + # If yes, return error. Doesn't support FV in Capsule image is also in FD flash region. + # + if self.CapsuleName is not None: + for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values(): + for RegionObj in FdObj.RegionList: + if RegionObj.RegionType == BINARY_FILE_TYPE_FV: + for RegionData in RegionObj.RegionDataList: + if RegionData.endswith(".fv"): + continue + elif RegionData.upper() + 'fv' in GenFdsGlobalVariable.ImageBinDict: + continue + elif self.UiFvName.upper() == RegionData.upper(): + GenFdsGlobalVariable.ErrorLogger("Capsule %s in FD region can't contain a FV %s in FD region." % (self.CapsuleName, self.UiFvName.upper())) + if not Flag: + GenFdsGlobalVariable.InfLogger( "\nGenerating %s FV" %self.UiFvName) + GenFdsGlobalVariable.LargeFileInFvFlags.append(False) + FFSGuid = None + + if self.FvBaseAddress is not None: + BaseAddress = self.FvBaseAddress + if not Flag: + self._InitializeInf(BaseAddress, BlockSize, BlockNum, ErasePloarity) + # + # First Process the Apriori section + # + MacroDict.update(self.DefineVarDict) + + GenFdsGlobalVariable.VerboseLogger('First generate Apriori file !') + FfsFileList = [] + for AprSection in self.AprioriSectionList: + FileName = AprSection.GenFfs (self.UiFvName, MacroDict, IsMakefile=Flag) + FfsFileList.append(FileName) + # Add Apriori file name to Inf file + if not Flag: + self.FvInfFile.append("EFI_FILE_NAME = " + \ + FileName + \ + TAB_LINE_BREAK) + + # Process Modules in FfsList + for FfsFile in self.FfsList: + if Flag: + if isinstance(FfsFile, FfsFileStatement.FileStatement): + continue + if GenFdsGlobalVariable.EnableGenfdsMultiThread and GenFdsGlobalVariable.ModuleFile and GenFdsGlobalVariable.ModuleFile.Path.find(os.path.normpath(FfsFile.InfFileName)) == -1: + continue + FileName = FfsFile.GenFfs(MacroDict, FvParentAddr=BaseAddress, IsMakefile=Flag, FvName=self.UiFvName) + FfsFileList.append(FileName) + if not Flag: + self.FvInfFile.append("EFI_FILE_NAME = " + \ + FileName + \ + TAB_LINE_BREAK) + if not Flag: + FvInfFile = ''.join(self.FvInfFile) + SaveFileOnChange(self.InfFileName, FvInfFile, False) + # + # Call GenFv tool + # + FvOutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.UiFvName) + FvOutputFile = FvOutputFile + '.Fv' + # BUGBUG: FvOutputFile could be specified from FDF file (FV section, CreateFile statement) + if self.CreateFileName is not None: + FvOutputFile = self.CreateFileName + + if Flag: + GenFdsGlobalVariable.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile + return FvOutputFile + + FvInfoFileName = os.path.join(GenFdsGlobalVariable.FfsDir, self.UiFvName + '.inf') + if not Flag: + CopyLongFilePath(GenFdsGlobalVariable.FvAddressFileName, FvInfoFileName) + OrigFvInfo = None + if os.path.exists (FvInfoFileName): + OrigFvInfo = open(FvInfoFileName, 'r').read() + if GenFdsGlobalVariable.LargeFileInFvFlags[-1]: + FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID + GenFdsGlobalVariable.GenerateFirmwareVolume( + FvOutputFile, + [self.InfFileName], + AddressFile=FvInfoFileName, + FfsList=FfsFileList, + ForceRebase=self.FvForceRebase, + FileSystemGuid=FFSGuid + ) + + NewFvInfo = None + if os.path.exists (FvInfoFileName): + NewFvInfo = open(FvInfoFileName, 'r').read() + if NewFvInfo is not None and NewFvInfo != OrigFvInfo: + FvChildAddr = [] + AddFileObj = open(FvInfoFileName, 'r') + AddrStrings = AddFileObj.readlines() + AddrKeyFound = False + for AddrString in AddrStrings: + if AddrKeyFound: + #get base address for the inside FvImage + FvChildAddr.append (AddrString) + elif AddrString.find ("[FV_BASE_ADDRESS]") != -1: + AddrKeyFound = True + AddFileObj.close() + + if FvChildAddr != []: + # Update Ffs again + for FfsFile in self.FfsList: + FileName = FfsFile.GenFfs(MacroDict, FvChildAddr, BaseAddress, IsMakefile=Flag, FvName=self.UiFvName) + + if GenFdsGlobalVariable.LargeFileInFvFlags[-1]: + FFSGuid = GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID; + #Update GenFv again + GenFdsGlobalVariable.GenerateFirmwareVolume( + FvOutputFile, + [self.InfFileName], + AddressFile=FvInfoFileName, + FfsList=FfsFileList, + ForceRebase=self.FvForceRebase, + FileSystemGuid=FFSGuid + ) + + # + # Write the Fv contents to Buffer + # + if os.path.isfile(FvOutputFile) and os.path.getsize(FvOutputFile) >= 0x48: + FvFileObj = open(FvOutputFile, 'rb') + # PI FvHeader is 0x48 byte + FvHeaderBuffer = FvFileObj.read(0x48) + Signature = FvHeaderBuffer[0x28:0x32] + if Signature and Signature.startswith(b'_FVH'): + GenFdsGlobalVariable.VerboseLogger("\nGenerate %s FV Successfully" % self.UiFvName) + GenFdsGlobalVariable.SharpCounter = 0 + + FvFileObj.seek(0) + Buffer.write(FvFileObj.read()) + # FV alignment position. + FvAlignmentValue = 1 << (ord(FvHeaderBuffer[0x2E:0x2F]) & 0x1F) + if FvAlignmentValue >= 0x400: + if FvAlignmentValue >= 0x100000: + if FvAlignmentValue >= 0x1000000: + #The max alignment supported by FFS is 16M. + self.FvAlignment = "16M" + else: + self.FvAlignment = str(FvAlignmentValue // 0x100000) + "M" + else: + self.FvAlignment = str(FvAlignmentValue // 0x400) + "K" + else: + # FvAlignmentValue is less than 1K + self.FvAlignment = str (FvAlignmentValue) + FvFileObj.close() + GenFdsGlobalVariable.ImageBinDict[self.UiFvName.upper() + 'fv'] = FvOutputFile + GenFdsGlobalVariable.LargeFileInFvFlags.pop() + else: + GenFdsGlobalVariable.ErrorLogger("Invalid FV file %s." % self.UiFvName) + else: + GenFdsGlobalVariable.ErrorLogger("Failed to generate %s FV file." %self.UiFvName) + return FvOutputFile + + ## _GetBlockSize() + # + # Calculate FV's block size + # Inherit block size from FD if no block size specified in FV + # + def _GetBlockSize(self): + if self.BlockSizeList: + return True + + for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values(): + for RegionObj in FdObj.RegionList: + if RegionObj.RegionType != BINARY_FILE_TYPE_FV: + continue + for RegionData in RegionObj.RegionDataList: + # + # Found the FD and region that contain this FV + # + if self.UiFvName.upper() == RegionData.upper(): + RegionObj.BlockInfoOfRegion(FdObj.BlockSizeList, self) + if self.BlockSizeList: + return True + return False + + ## _InitializeInf() + # + # Initialize the inf file to create FV + # + # @param self The object pointer + # @param BaseAddress base address of FV + # @param BlockSize block size of FV + # @param BlockNum How many blocks in FV + # @param ErasePolarity Flash erase polarity + # + def _InitializeInf (self, BaseAddress = None, BlockSize= None, BlockNum = None, ErasePloarity='1'): + # + # Create FV inf file + # + self.InfFileName = os.path.join(GenFdsGlobalVariable.FvDir, + self.UiFvName + '.inf') + self.FvInfFile = [] + + # + # Add [Options] + # + self.FvInfFile.append("[options]" + TAB_LINE_BREAK) + if BaseAddress is not None: + self.FvInfFile.append("EFI_BASE_ADDRESS = " + \ + BaseAddress + \ + TAB_LINE_BREAK) + + if BlockSize is not None: + self.FvInfFile.append("EFI_BLOCK_SIZE = " + \ + '0x%X' %BlockSize + \ + TAB_LINE_BREAK) + if BlockNum is not None: + self.FvInfFile.append("EFI_NUM_BLOCKS = " + \ + ' 0x%X' %BlockNum + \ + TAB_LINE_BREAK) + else: + if self.BlockSizeList == []: + if not self._GetBlockSize(): + #set default block size is 1 + self.FvInfFile.append("EFI_BLOCK_SIZE = 0x1" + TAB_LINE_BREAK) + + for BlockSize in self.BlockSizeList: + if BlockSize[0] is not None: + self.FvInfFile.append("EFI_BLOCK_SIZE = " + \ + '0x%X' %BlockSize[0] + \ + TAB_LINE_BREAK) + + if BlockSize[1] is not None: + self.FvInfFile.append("EFI_NUM_BLOCKS = " + \ + ' 0x%X' %BlockSize[1] + \ + TAB_LINE_BREAK) + + if self.BsBaseAddress is not None: + self.FvInfFile.append('EFI_BOOT_DRIVER_BASE_ADDRESS = ' + \ + '0x%X' %self.BsBaseAddress) + if self.RtBaseAddress is not None: + self.FvInfFile.append('EFI_RUNTIME_DRIVER_BASE_ADDRESS = ' + \ + '0x%X' %self.RtBaseAddress) + # + # Add attribute + # + self.FvInfFile.append("[attributes]" + TAB_LINE_BREAK) + + self.FvInfFile.append("EFI_ERASE_POLARITY = " + \ + ' %s' %ErasePloarity + \ + TAB_LINE_BREAK) + if not (self.FvAttributeDict is None): + for FvAttribute in self.FvAttributeDict.keys(): + if FvAttribute == "FvUsedSizeEnable": + if self.FvAttributeDict[FvAttribute].upper() in ('TRUE', '1'): + self.UsedSizeEnable = True + continue + self.FvInfFile.append("EFI_" + \ + FvAttribute + \ + ' = ' + \ + self.FvAttributeDict[FvAttribute] + \ + TAB_LINE_BREAK ) + if self.FvAlignment is not None: + self.FvInfFile.append("EFI_FVB2_ALIGNMENT_" + \ + self.FvAlignment.strip() + \ + " = TRUE" + \ + TAB_LINE_BREAK) + + # + # Generate FV extension header file + # + if not self.FvNameGuid: + if len(self.FvExtEntryType) > 0 or self.UsedSizeEnable: + GenFdsGlobalVariable.ErrorLogger("FV Extension Header Entries declared for %s with no FvNameGuid declaration." % (self.UiFvName)) + else: + TotalSize = 16 + 4 + Buffer = bytearray() + if self.UsedSizeEnable: + TotalSize += (4 + 4) + ## define EFI_FV_EXT_TYPE_USED_SIZE_TYPE 0x03 + #typedef struct + # { + # EFI_FIRMWARE_VOLUME_EXT_ENTRY Hdr; + # UINT32 UsedSize; + # } EFI_FIRMWARE_VOLUME_EXT_ENTRY_USED_SIZE_TYPE; + Buffer += pack('HHL', 8, 3, 0) + + if self.FvNameString == 'TRUE': + # + # Create EXT entry for FV UI name + # This GUID is used: A67DF1FA-8DE8-4E98-AF09-4BDF2EFFBC7C + # + FvUiLen = len(self.UiFvName) + TotalSize += (FvUiLen + 16 + 4) + Guid = FV_UI_EXT_ENTY_GUID.split('-') + # + # Layout: + # EFI_FIRMWARE_VOLUME_EXT_ENTRY: size 4 + # GUID: size 16 + # FV UI name + # + Buffer += (pack('HH', (FvUiLen + 16 + 4), 0x0002) + + PackGUID(Guid) + + self.UiFvName.encode('utf-8')) + + for Index in range (0, len(self.FvExtEntryType)): + if self.FvExtEntryType[Index] == 'FILE': + # check if the path is absolute or relative + if os.path.isabs(self.FvExtEntryData[Index]): + FileFullPath = os.path.normpath(self.FvExtEntryData[Index]) + else: + FileFullPath = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.FvExtEntryData[Index])) + # check if the file path exists or not + if not os.path.isfile(FileFullPath): + GenFdsGlobalVariable.ErrorLogger("Error opening FV Extension Header Entry file %s." % (self.FvExtEntryData[Index])) + FvExtFile = open (FileFullPath, 'rb') + FvExtFile.seek(0, 2) + Size = FvExtFile.tell() + if Size >= 0x10000: + GenFdsGlobalVariable.ErrorLogger("The size of FV Extension Header Entry file %s exceeds 0x10000." % (self.FvExtEntryData[Index])) + TotalSize += (Size + 4) + FvExtFile.seek(0) + Buffer += pack('HH', (Size + 4), int(self.FvExtEntryTypeValue[Index], 16)) + Buffer += FvExtFile.read() + FvExtFile.close() + if self.FvExtEntryType[Index] == 'DATA': + ByteList = self.FvExtEntryData[Index].split(',') + Size = len (ByteList) + if Size >= 0x10000: + GenFdsGlobalVariable.ErrorLogger("The size of FV Extension Header Entry data %s exceeds 0x10000." % (self.FvExtEntryData[Index])) + TotalSize += (Size + 4) + Buffer += pack('HH', (Size + 4), int(self.FvExtEntryTypeValue[Index], 16)) + for Index1 in range (0, Size): + Buffer += pack('B', int(ByteList[Index1], 16)) + + Guid = self.FvNameGuid.split('-') + Buffer = PackGUID(Guid) + pack('=L', TotalSize) + Buffer + + # + # Generate FV extension header file if the total size is not zero + # + if TotalSize > 0: + FvExtHeaderFileName = os.path.join(GenFdsGlobalVariable.FvDir, self.UiFvName + '.ext') + FvExtHeaderFile = BytesIO() + FvExtHeaderFile.write(Buffer) + Changed = SaveFileOnChange(FvExtHeaderFileName, FvExtHeaderFile.getvalue(), True) + FvExtHeaderFile.close() + if Changed: + if os.path.exists (self.InfFileName): + os.remove (self.InfFileName) + self.FvInfFile.append("EFI_FV_EXT_HEADER_FILE_NAME = " + \ + FvExtHeaderFileName + \ + TAB_LINE_BREAK) + + # + # Add [Files] + # + self.FvInfFile.append("[files]" + TAB_LINE_BREAK) diff --git a/BaseTools/Source/Python/GenFds/FvImageSection.py b/BaseTools/Source/Python/GenFds/FvImageSection.py index ff2d5ca3c0..8590c64b1a 100644 --- a/BaseTools/Source/Python/GenFds/FvImageSection.py +++ b/BaseTools/Source/Python/GenFds/FvImageSection.py @@ -1,158 +1,158 @@ -## @file
-# process FV image section generation
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from . import Section
-from io import BytesIO
-from .Ffs import SectionSuffix
-import subprocess
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-import Common.LongFilePathOs as os
-from CommonDataClass.FdfClass import FvImageSectionClassObject
-from Common.MultipleWorkspace import MultipleWorkspace as mws
-from Common import EdkLogger
-from Common.BuildToolError import *
-from Common.DataType import *
-
-## generate FV image section
-#
-#
-class FvImageSection(FvImageSectionClassObject):
-
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- FvImageSectionClassObject.__init__(self)
-
- ## GenSection() method
- #
- # Generate FV image section
- #
- # @param self The object pointer
- # @param OutputPath Where to place output file
- # @param ModuleName Which module this section belongs to
- # @param SecNum Index of section
- # @param KeyStringList Filter for inputs of section generation
- # @param FfsInf FfsInfStatement object that contains this section data
- # @param Dict dictionary contains macro and its value
- # @retval tuple (Generated file name, section alignment)
- #
- def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = None, IsMakefile = False):
-
- OutputFileList = []
- if Dict is None:
- Dict = {}
- if self.FvFileType is not None:
- FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FvFileType, self.FvFileExtension)
- if IsSect :
- return FileList, self.Alignment
-
- Num = SecNum
-
- MaxFvAlignment = 0
- for FvFileName in FileList:
- FvAlignmentValue = 0
- if os.path.isfile(FvFileName):
- FvFileObj = open (FvFileName, 'rb')
- FvFileObj.seek(0)
- # PI FvHeader is 0x48 byte
- FvHeaderBuffer = FvFileObj.read(0x48)
- # FV alignment position.
- if isinstance(FvHeaderBuffer[0x2E], str):
- FvAlignmentValue = 1 << (ord(FvHeaderBuffer[0x2E]) & 0x1F)
- else:
- FvAlignmentValue = 1 << (FvHeaderBuffer[0x2E] & 0x1F)
- FvFileObj.close()
- if FvAlignmentValue > MaxFvAlignment:
- MaxFvAlignment = FvAlignmentValue
-
- OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get("FV_IMAGE"))
- GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile)
- OutputFileList.append(OutputFile)
-
- # MaxFvAlignment is larger than or equal to 1K
- if MaxFvAlignment >= 0x400:
- if MaxFvAlignment >= 0x100000:
- #The max alignment supported by FFS is 16M.
- if MaxFvAlignment >= 0x1000000:
- self.Alignment = "16M"
- else:
- self.Alignment = str(MaxFvAlignment // 0x100000) + "M"
- else:
- self.Alignment = str (MaxFvAlignment // 0x400) + "K"
- else:
- # MaxFvAlignment is less than 1K
- self.Alignment = str (MaxFvAlignment)
-
- return OutputFileList, self.Alignment
- #
- # Generate Fv
- #
- if self.FvName is not None:
- Buffer = BytesIO()
- Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName)
- if Fv is not None:
- self.Fv = Fv
- if not self.FvAddr and self.Fv.BaseAddress:
- self.FvAddr = self.Fv.BaseAddress
- FvFileName = Fv.AddToBuffer(Buffer, self.FvAddr, MacroDict = Dict, Flag=IsMakefile)
- if Fv.FvAlignment is not None:
- if self.Alignment is None:
- self.Alignment = Fv.FvAlignment
- else:
- if GenFdsGlobalVariable.GetAlignment (Fv.FvAlignment) > GenFdsGlobalVariable.GetAlignment (self.Alignment):
- self.Alignment = Fv.FvAlignment
- else:
- if self.FvFileName is not None:
- FvFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvFileName)
- if os.path.isfile(FvFileName):
- FvFileObj = open (FvFileName, 'rb')
- FvFileObj.seek(0)
- # PI FvHeader is 0x48 byte
- FvHeaderBuffer = FvFileObj.read(0x48)
- # FV alignment position.
- if isinstance(FvHeaderBuffer[0x2E], str):
- FvAlignmentValue = 1 << (ord(FvHeaderBuffer[0x2E]) & 0x1F)
- else:
- FvAlignmentValue = 1 << (FvHeaderBuffer[0x2E] & 0x1F)
- # FvAlignmentValue is larger than or equal to 1K
- if FvAlignmentValue >= 0x400:
- if FvAlignmentValue >= 0x100000:
- #The max alignment supported by FFS is 16M.
- if FvAlignmentValue >= 0x1000000:
- self.Alignment = "16M"
- else:
- self.Alignment = str(FvAlignmentValue // 0x100000) + "M"
- else:
- self.Alignment = str (FvAlignmentValue // 0x400) + "K"
- else:
- # FvAlignmentValue is less than 1K
- self.Alignment = str (FvAlignmentValue)
- FvFileObj.close()
- else:
- if len (mws.getPkgPath()) == 0:
- EdkLogger.error("GenFds", FILE_NOT_FOUND, "%s is not found in WORKSPACE: %s" % self.FvFileName, GenFdsGlobalVariable.WorkSpaceDir)
- else:
- EdkLogger.error("GenFds", FILE_NOT_FOUND, "%s is not found in packages path:\n\t%s" % (self.FvFileName, '\n\t'.join(mws.getPkgPath())))
-
- else:
- EdkLogger.error("GenFds", GENFDS_ERROR, "FvImageSection Failed! %s NOT found in FDF" % self.FvName)
-
- #
- # Prepare the parameter of GenSection
- #
- OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + SectionSuffix.get("FV_IMAGE"))
- GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile)
- OutputFileList.append(OutputFile)
-
- return OutputFileList, self.Alignment
+## @file +# process FV image section generation +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from . import Section +from io import BytesIO +from .Ffs import SectionSuffix +import subprocess +from .GenFdsGlobalVariable import GenFdsGlobalVariable +import Common.LongFilePathOs as os +from CommonDataClass.FdfClass import FvImageSectionClassObject +from Common.MultipleWorkspace import MultipleWorkspace as mws +from Common import EdkLogger +from Common.BuildToolError import * +from Common.DataType import * + +## generate FV image section +# +# +class FvImageSection(FvImageSectionClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FvImageSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate FV image section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = None, IsMakefile = False): + + OutputFileList = [] + if Dict is None: + Dict = {} + if self.FvFileType is not None: + FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FvFileType, self.FvFileExtension) + if IsSect : + return FileList, self.Alignment + + Num = SecNum + + MaxFvAlignment = 0 + for FvFileName in FileList: + FvAlignmentValue = 0 + if os.path.isfile(FvFileName): + FvFileObj = open (FvFileName, 'rb') + FvFileObj.seek(0) + # PI FvHeader is 0x48 byte + FvHeaderBuffer = FvFileObj.read(0x48) + # FV alignment position. + if isinstance(FvHeaderBuffer[0x2E], str): + FvAlignmentValue = 1 << (ord(FvHeaderBuffer[0x2E]) & 0x1F) + else: + FvAlignmentValue = 1 << (FvHeaderBuffer[0x2E] & 0x1F) + FvFileObj.close() + if FvAlignmentValue > MaxFvAlignment: + MaxFvAlignment = FvAlignmentValue + + OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get("FV_IMAGE")) + GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile) + OutputFileList.append(OutputFile) + + # MaxFvAlignment is larger than or equal to 1K + if MaxFvAlignment >= 0x400: + if MaxFvAlignment >= 0x100000: + #The max alignment supported by FFS is 16M. + if MaxFvAlignment >= 0x1000000: + self.Alignment = "16M" + else: + self.Alignment = str(MaxFvAlignment // 0x100000) + "M" + else: + self.Alignment = str (MaxFvAlignment // 0x400) + "K" + else: + # MaxFvAlignment is less than 1K + self.Alignment = str (MaxFvAlignment) + + return OutputFileList, self.Alignment + # + # Generate Fv + # + if self.FvName is not None: + Buffer = BytesIO() + Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName) + if Fv is not None: + self.Fv = Fv + if not self.FvAddr and self.Fv.BaseAddress: + self.FvAddr = self.Fv.BaseAddress + FvFileName = Fv.AddToBuffer(Buffer, self.FvAddr, MacroDict = Dict, Flag=IsMakefile) + if Fv.FvAlignment is not None: + if self.Alignment is None: + self.Alignment = Fv.FvAlignment + else: + if GenFdsGlobalVariable.GetAlignment (Fv.FvAlignment) > GenFdsGlobalVariable.GetAlignment (self.Alignment): + self.Alignment = Fv.FvAlignment + else: + if self.FvFileName is not None: + FvFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FvFileName) + if os.path.isfile(FvFileName): + FvFileObj = open (FvFileName, 'rb') + FvFileObj.seek(0) + # PI FvHeader is 0x48 byte + FvHeaderBuffer = FvFileObj.read(0x48) + # FV alignment position. + if isinstance(FvHeaderBuffer[0x2E], str): + FvAlignmentValue = 1 << (ord(FvHeaderBuffer[0x2E]) & 0x1F) + else: + FvAlignmentValue = 1 << (FvHeaderBuffer[0x2E] & 0x1F) + # FvAlignmentValue is larger than or equal to 1K + if FvAlignmentValue >= 0x400: + if FvAlignmentValue >= 0x100000: + #The max alignment supported by FFS is 16M. + if FvAlignmentValue >= 0x1000000: + self.Alignment = "16M" + else: + self.Alignment = str(FvAlignmentValue // 0x100000) + "M" + else: + self.Alignment = str (FvAlignmentValue // 0x400) + "K" + else: + # FvAlignmentValue is less than 1K + self.Alignment = str (FvAlignmentValue) + FvFileObj.close() + else: + if len (mws.getPkgPath()) == 0: + EdkLogger.error("GenFds", FILE_NOT_FOUND, "%s is not found in WORKSPACE: %s" % self.FvFileName, GenFdsGlobalVariable.WorkSpaceDir) + else: + EdkLogger.error("GenFds", FILE_NOT_FOUND, "%s is not found in packages path:\n\t%s" % (self.FvFileName, '\n\t'.join(mws.getPkgPath()))) + + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "FvImageSection Failed! %s NOT found in FDF" % self.FvName) + + # + # Prepare the parameter of GenSection + # + OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + SectionSuffix.get("FV_IMAGE")) + GenFdsGlobalVariable.GenerateSection(OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile) + OutputFileList.append(OutputFile) + + return OutputFileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py index b48fe761e0..67c95f7948 100644 --- a/BaseTools/Source/Python/GenFds/GenFds.py +++ b/BaseTools/Source/Python/GenFds/GenFds.py @@ -1,800 +1,800 @@ -## @file
-# generate flash image
-#
-# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import print_function
-from __future__ import absolute_import
-from re import compile
-from optparse import OptionParser
-from sys import exit
-from glob import glob
-from struct import unpack
-from linecache import getlines
-from io import BytesIO
-
-import Common.LongFilePathOs as os
-from Common.TargetTxtClassObject import TargetTxtDict,gDefaultTargetTxtFile
-from Common.DataType import *
-import Common.GlobalData as GlobalData
-from Common import EdkLogger
-from Common.StringUtils import NormPath
-from Common.Misc import DirCache, PathClass, GuidStructureStringToGuidString
-from Common.Misc import SaveFileOnChange, ClearDuplicatedInf
-from Common.BuildVersion import gBUILD_VERSION
-from Common.MultipleWorkspace import MultipleWorkspace as mws
-from Common.BuildToolError import FatalError, GENFDS_ERROR, CODE_ERROR, FORMAT_INVALID, RESOURCE_NOT_AVAILABLE, FILE_NOT_FOUND, OPTION_MISSING, FORMAT_NOT_SUPPORTED, OPTION_VALUE_INVALID, PARAMETER_INVALID
-from Workspace.WorkspaceDatabase import WorkspaceDatabase
-
-from .FdfParser import FdfParser, Warning
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-from .FfsFileStatement import FileStatement
-import Common.DataType as DataType
-from struct import Struct
-
-## Version and Copyright
-versionNumber = "1.0" + ' ' + gBUILD_VERSION
-__version__ = "%prog Version " + versionNumber
-__copyright__ = "Copyright (c) 2007 - 2018, Intel Corporation All rights reserved."
-
-## Tool entrance method
-#
-# This method mainly dispatch specific methods per the command line options.
-# If no error found, return zero value so the caller of this tool can know
-# if it's executed successfully or not.
-#
-# @retval 0 Tool was successful
-# @retval 1 Tool failed
-#
-def main():
- global Options
- Options = myOptionParser()
- EdkLogger.Initialize()
- return GenFdsApi(OptionsToCommandDict(Options))
-
-def resetFdsGlobalVariable():
- GenFdsGlobalVariable.FvDir = ''
- GenFdsGlobalVariable.OutputDirDict = {}
- GenFdsGlobalVariable.BinDir = ''
- # will be FvDir + os.sep + 'Ffs'
- GenFdsGlobalVariable.FfsDir = ''
- GenFdsGlobalVariable.FdfParser = None
- GenFdsGlobalVariable.LibDir = ''
- GenFdsGlobalVariable.WorkSpace = None
- GenFdsGlobalVariable.WorkSpaceDir = ''
- GenFdsGlobalVariable.ConfDir = ''
- GenFdsGlobalVariable.OutputDirFromDscDict = {}
- GenFdsGlobalVariable.TargetName = ''
- GenFdsGlobalVariable.ToolChainTag = ''
- GenFdsGlobalVariable.RuleDict = {}
- GenFdsGlobalVariable.ArchList = None
- GenFdsGlobalVariable.ActivePlatform = None
- GenFdsGlobalVariable.FvAddressFileName = ''
- GenFdsGlobalVariable.VerboseMode = False
- GenFdsGlobalVariable.DebugLevel = -1
- GenFdsGlobalVariable.SharpCounter = 0
- GenFdsGlobalVariable.SharpNumberPerLine = 40
- GenFdsGlobalVariable.FdfFile = ''
- GenFdsGlobalVariable.FdfFileTimeStamp = 0
- GenFdsGlobalVariable.FixedLoadAddress = False
- GenFdsGlobalVariable.PlatformName = ''
-
- GenFdsGlobalVariable.BuildRuleFamily = DataType.TAB_COMPILER_MSFT
- GenFdsGlobalVariable.ToolChainFamily = DataType.TAB_COMPILER_MSFT
- GenFdsGlobalVariable.__BuildRuleDatabase = None
- GenFdsGlobalVariable.GuidToolDefinition = {}
- GenFdsGlobalVariable.FfsCmdDict = {}
- GenFdsGlobalVariable.SecCmdList = []
- GenFdsGlobalVariable.CopyList = []
- GenFdsGlobalVariable.ModuleFile = ''
- GenFdsGlobalVariable.EnableGenfdsMultiThread = True
-
- GenFdsGlobalVariable.LargeFileInFvFlags = []
- GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'
- GenFdsGlobalVariable.LARGE_FILE_SIZE = 0x1000000
-
- GenFdsGlobalVariable.SectionHeader = Struct("3B 1B")
-
- # FvName, FdName, CapName in FDF, Image file name
- GenFdsGlobalVariable.ImageBinDict = {}
-
-def GenFdsApi(FdsCommandDict, WorkSpaceDataBase=None):
- global Workspace
- Workspace = ""
- ArchList = None
- ReturnCode = 0
- resetFdsGlobalVariable()
-
- try:
- if FdsCommandDict.get("verbose"):
- EdkLogger.SetLevel(EdkLogger.VERBOSE)
- GenFdsGlobalVariable.VerboseMode = True
-
- if FdsCommandDict.get("FixedAddress"):
- GenFdsGlobalVariable.FixedLoadAddress = True
-
- if FdsCommandDict.get("quiet"):
- EdkLogger.SetLevel(EdkLogger.QUIET)
- if FdsCommandDict.get("debug"):
- EdkLogger.SetLevel(FdsCommandDict.get("debug") + 1)
- GenFdsGlobalVariable.DebugLevel = FdsCommandDict.get("debug")
- else:
- EdkLogger.SetLevel(EdkLogger.INFO)
-
- if not FdsCommandDict.get("Workspace",os.environ.get('WORKSPACE')):
- EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined",
- ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")
- elif not os.path.exists(FdsCommandDict.get("Workspace",os.environ.get('WORKSPACE'))):
- EdkLogger.error("GenFds", PARAMETER_INVALID, "WORKSPACE is invalid",
- ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")
- else:
- Workspace = os.path.normcase(FdsCommandDict.get("Workspace",os.environ.get('WORKSPACE')))
- GenFdsGlobalVariable.WorkSpaceDir = Workspace
- if FdsCommandDict.get("debug"):
- GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace)
- if FdsCommandDict.get("GenfdsMultiThread"):
- GenFdsGlobalVariable.EnableGenfdsMultiThread = True
- else:
- GenFdsGlobalVariable.EnableGenfdsMultiThread = False
- os.chdir(GenFdsGlobalVariable.WorkSpaceDir)
-
- # set multiple workspace
- PackagesPath = os.getenv("PACKAGES_PATH")
- mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath)
-
- if FdsCommandDict.get("fdf_file"):
- FdfFilename = FdsCommandDict.get("fdf_file")[0].Path
- FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename)
-
- if FdfFilename[0:2] == '..':
- FdfFilename = os.path.abspath(FdfFilename)
- if not os.path.isabs(FdfFilename):
- FdfFilename = mws.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename)
- if not os.path.exists(FdfFilename):
- EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=FdfFilename)
-
- GenFdsGlobalVariable.FdfFile = FdfFilename
- GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename)
- else:
- EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF filename")
-
- if FdsCommandDict.get("build_target"):
- GenFdsGlobalVariable.TargetName = FdsCommandDict.get("build_target")
-
- if FdsCommandDict.get("toolchain_tag"):
- GenFdsGlobalVariable.ToolChainTag = FdsCommandDict.get("toolchain_tag")
-
- if FdsCommandDict.get("active_platform"):
- ActivePlatform = FdsCommandDict.get("active_platform")
- ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform)
-
- if ActivePlatform[0:2] == '..':
- ActivePlatform = os.path.abspath(ActivePlatform)
-
- if not os.path.isabs (ActivePlatform):
- ActivePlatform = mws.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform)
-
- if not os.path.exists(ActivePlatform):
- EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!")
- else:
- EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform")
-
- GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform))
-
- if FdsCommandDict.get("conf_directory"):
- # Get alternate Conf location, if it is absolute, then just use the absolute directory name
- ConfDirectoryPath = os.path.normpath(FdsCommandDict.get("conf_directory"))
- if ConfDirectoryPath.startswith('"'):
- ConfDirectoryPath = ConfDirectoryPath[1:]
- if ConfDirectoryPath.endswith('"'):
- ConfDirectoryPath = ConfDirectoryPath[:-1]
- if not os.path.isabs(ConfDirectoryPath):
- # Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE
- # This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf
- ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ConfDirectoryPath)
- else:
- if "CONF_PATH" in os.environ:
- ConfDirectoryPath = os.path.normcase(os.environ["CONF_PATH"])
- else:
- # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf
- ConfDirectoryPath = mws.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf')
- GenFdsGlobalVariable.ConfDir = ConfDirectoryPath
- if not GlobalData.gConfDirectory:
- GlobalData.gConfDirectory = GenFdsGlobalVariable.ConfDir
- BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, gDefaultTargetTxtFile))
- if os.path.isfile(BuildConfigurationFile) == True:
- # if no build target given in command line, get it from target.txt
- TargetObj = TargetTxtDict()
- TargetTxt = TargetObj.Target
- if not GenFdsGlobalVariable.TargetName:
- BuildTargetList = TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_TARGET]
- if len(BuildTargetList) != 1:
- EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for Target.")
- GenFdsGlobalVariable.TargetName = BuildTargetList[0]
-
- # if no tool chain given in command line, get it from target.txt
- if not GenFdsGlobalVariable.ToolChainTag:
- ToolChainList = TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_TOOL_CHAIN_TAG]
- if ToolChainList is None or len(ToolChainList) == 0:
- EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.")
- if len(ToolChainList) != 1:
- EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for ToolChain.")
- GenFdsGlobalVariable.ToolChainTag = ToolChainList[0]
- else:
- EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile)
-
- #Set global flag for build mode
- GlobalData.gIgnoreSource = FdsCommandDict.get("IgnoreSources")
-
- if FdsCommandDict.get("macro"):
- for Pair in FdsCommandDict.get("macro"):
- if Pair.startswith('"'):
- Pair = Pair[1:]
- if Pair.endswith('"'):
- Pair = Pair[:-1]
- List = Pair.split('=')
- if len(List) == 2:
- if not List[1].strip():
- EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="No Value given for Macro %s" %List[0])
- if List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]:
- GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip()
- else:
- GlobalData.gCommandLineDefines[List[0].strip()] = List[1].strip()
- else:
- GlobalData.gCommandLineDefines[List[0].strip()] = "TRUE"
- os.environ["WORKSPACE"] = Workspace
-
- # Use the -t and -b option as gGlobalDefines's TOOLCHAIN and TARGET if they are not defined
- if "TARGET" not in GlobalData.gGlobalDefines:
- GlobalData.gGlobalDefines["TARGET"] = GenFdsGlobalVariable.TargetName
- if "TOOLCHAIN" not in GlobalData.gGlobalDefines:
- GlobalData.gGlobalDefines["TOOLCHAIN"] = GenFdsGlobalVariable.ToolChainTag
- if "TOOL_CHAIN_TAG" not in GlobalData.gGlobalDefines:
- GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = GenFdsGlobalVariable.ToolChainTag
-
- """call Workspace build create database"""
- GlobalData.gDatabasePath = os.path.normpath(os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath))
-
- if WorkSpaceDataBase:
- BuildWorkSpace = WorkSpaceDataBase
- else:
- BuildWorkSpace = WorkspaceDatabase()
- #
- # Get files real name in workspace dir
- #
- GlobalData.gAllFiles = DirCache(Workspace)
- GlobalData.gWorkspace = Workspace
-
- if FdsCommandDict.get("build_architecture_list"):
- ArchList = FdsCommandDict.get("build_architecture_list").split(',')
- else:
- ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].SupArchList
-
- TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].SupArchList) & set(ArchList)
- if len(TargetArchList) == 0:
- EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON].SupArchList)))
-
- for Arch in ArchList:
- GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].OutputDirectory)
-
- # assign platform name based on last entry in ArchList
- GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, ArchList[-1], FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].PlatformName
-
- if FdsCommandDict.get("platform_build_directory"):
- OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdsCommandDict.get("platform_build_directory"))
- if not os.path.isabs (OutputDirFromCommandLine):
- OutputDirFromCommandLine = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, OutputDirFromCommandLine)
- for Arch in ArchList:
- GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine
- else:
- for Arch in ArchList:
- GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag)
-
- for Key in GenFdsGlobalVariable.OutputDirDict:
- OutputDir = GenFdsGlobalVariable.OutputDirDict[Key]
- if OutputDir[0:2] == '..':
- OutputDir = os.path.abspath(OutputDir)
-
- if OutputDir[1] != ':':
- OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir)
-
- if not os.path.exists(OutputDir):
- EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=OutputDir)
- GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir
-
- """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """
- if WorkSpaceDataBase:
- FdfParserObj = GlobalData.gFdfParser
- else:
- FdfParserObj = FdfParser(FdfFilename)
- FdfParserObj.ParseFile()
-
- if FdfParserObj.CycleReferenceCheck():
- EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file")
-
- if FdsCommandDict.get("fd"):
- if FdsCommandDict.get("fd")[0].upper() in FdfParserObj.Profile.FdDict:
- GenFds.OnlyGenerateThisFd = FdsCommandDict.get("fd")[0]
- else:
- EdkLogger.error("GenFds", OPTION_VALUE_INVALID,
- "No such an FD in FDF file: %s" % FdsCommandDict.get("fd")[0])
-
- if FdsCommandDict.get("fv"):
- if FdsCommandDict.get("fv")[0].upper() in FdfParserObj.Profile.FvDict:
- GenFds.OnlyGenerateThisFv = FdsCommandDict.get("fv")[0]
- else:
- EdkLogger.error("GenFds", OPTION_VALUE_INVALID,
- "No such an FV in FDF file: %s" % FdsCommandDict.get("fv")[0])
-
- if FdsCommandDict.get("cap"):
- if FdsCommandDict.get("cap")[0].upper() in FdfParserObj.Profile.CapsuleDict:
- GenFds.OnlyGenerateThisCap = FdsCommandDict.get("cap")[0]
- else:
- EdkLogger.error("GenFds", OPTION_VALUE_INVALID,
- "No such a Capsule in FDF file: %s" % FdsCommandDict.get("cap")[0])
-
- GenFdsGlobalVariable.WorkSpace = BuildWorkSpace
- if ArchList:
- GenFdsGlobalVariable.ArchList = ArchList
-
- # Dsc Build Data will handle Pcd Settings from CommandLine.
-
- """Modify images from build output if the feature of loading driver at fixed address is on."""
- if GenFdsGlobalVariable.FixedLoadAddress:
- GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform)
-
- # Record the FV Region info that may specific in the FD
- if FdfParserObj.Profile.FvDict and FdfParserObj.Profile.FdDict:
- for FvObj in FdfParserObj.Profile.FvDict.values():
- for FdObj in FdfParserObj.Profile.FdDict.values():
- for RegionObj in FdObj.RegionList:
- if RegionObj.RegionType != BINARY_FILE_TYPE_FV:
- continue
- for RegionData in RegionObj.RegionDataList:
- if FvObj.UiFvName.upper() == RegionData.upper():
- if not FvObj.BaseAddress:
- FvObj.BaseAddress = '0x%x' % (int(FdObj.BaseAddress, 0) + RegionObj.Offset)
- if FvObj.FvRegionInFD:
- if FvObj.FvRegionInFD != RegionObj.Size:
- EdkLogger.error("GenFds", FORMAT_INVALID, "The FV %s's region is specified in multiple FD with different value." %FvObj.UiFvName)
- else:
- FvObj.FvRegionInFD = RegionObj.Size
- RegionObj.BlockInfoOfRegion(FdObj.BlockSizeList, FvObj)
-
- """Call GenFds"""
- GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)
-
- """Generate GUID cross reference file"""
- GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList, FdfParserObj)
-
- """Display FV space info."""
- GenFds.DisplayFvSpaceInfo(FdfParserObj)
-
- except Warning as X:
- EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)
- ReturnCode = FORMAT_INVALID
- except FatalError as X:
- if FdsCommandDict.get("debug") is not None:
- import traceback
- EdkLogger.quiet(traceback.format_exc())
- ReturnCode = X.args[0]
- except:
- import traceback
- EdkLogger.error(
- "\nPython",
- CODE_ERROR,
- "Tools code failure",
- ExtraData="Please send email to %s for help, attaching following call stack trace!\n" % MSG_EDKII_MAIL_ADDR,
- RaiseError=False
- )
- EdkLogger.quiet(traceback.format_exc())
- ReturnCode = CODE_ERROR
- finally:
- ClearDuplicatedInf()
- return ReturnCode
-
-def OptionsToCommandDict(Options):
- FdsCommandDict = {}
- FdsCommandDict["verbose"] = Options.verbose
- FdsCommandDict["FixedAddress"] = Options.FixedAddress
- FdsCommandDict["quiet"] = Options.quiet
- FdsCommandDict["debug"] = Options.debug
- FdsCommandDict["Workspace"] = Options.Workspace
- FdsCommandDict["GenfdsMultiThread"] = not Options.NoGenfdsMultiThread
- FdsCommandDict["fdf_file"] = [PathClass(Options.filename)] if Options.filename else []
- FdsCommandDict["build_target"] = Options.BuildTarget
- FdsCommandDict["toolchain_tag"] = Options.ToolChain
- FdsCommandDict["active_platform"] = Options.activePlatform
- FdsCommandDict["OptionPcd"] = Options.OptionPcd
- FdsCommandDict["conf_directory"] = Options.ConfDirectory
- FdsCommandDict["IgnoreSources"] = Options.IgnoreSources
- FdsCommandDict["macro"] = Options.Macros
- FdsCommandDict["build_architecture_list"] = Options.archList
- FdsCommandDict["platform_build_directory"] = Options.outputDir
- FdsCommandDict["fd"] = [Options.uiFdName] if Options.uiFdName else []
- FdsCommandDict["fv"] = [Options.uiFvName] if Options.uiFvName else []
- FdsCommandDict["cap"] = [Options.uiCapName] if Options.uiCapName else []
- return FdsCommandDict
-
-
-gParamCheck = []
-def SingleCheckCallback(option, opt_str, value, parser):
- if option not in gParamCheck:
- setattr(parser.values, option.dest, value)
- gParamCheck.append(option)
- else:
- parser.error("Option %s only allows one instance in command line!" % option)
-
-## Parse command line options
-#
-# Using standard Python module optparse to parse command line option of this tool.
-#
-# @retval Opt A optparse.Values object containing the parsed options
-#
-def myOptionParser():
- usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""
- Parser = OptionParser(usage=usage, description=__copyright__, version="%prog " + str(versionNumber))
- Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback)
- Parser.add_option("-a", "--arch", dest="archList", help="comma separated list containing one or more of: IA32, X64, IPF, ARM, AARCH64 or EBC which should be built, overrides target.txt?s TARGET_ARCH")
- Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
- Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")
- Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")
- Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",
- action="callback", callback=SingleCheckCallback)
- Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE",
- action="callback", callback=SingleCheckCallback)
- Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory",
- action="callback", callback=SingleCheckCallback)
- Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")
- Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Build the FV image using the [FV] section named by UiFvName")
- Parser.add_option("-C", "--CapsuleImage", dest="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName")
- Parser.add_option("-b", "--buildtarget", type="string", dest="BuildTarget", help="Set the build TARGET, overrides target.txt TARGET setting.",
- action="callback", callback=SingleCheckCallback)
- Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",
- action="callback", callback=SingleCheckCallback)
- Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")
- Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")
- Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")
- Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files")
- Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")
- Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=True, help="Enable GenFds multi thread to generate ffs file.")
- Parser.add_option("--no-genfds-multi-thread", action="store_true", dest="NoGenfdsMultiThread", default=False, help="Disable GenFds multi thread to generate ffs file.")
-
- Options, _ = Parser.parse_args()
- return Options
-
-## The class implementing the EDK2 flash image generation process
-#
-# This process includes:
-# 1. Collect workspace information, includes platform and module information
-# 2. Call methods of Fd class to generate FD
-# 3. Call methods of Fv class to generate FV that not belong to FD
-#
-class GenFds(object):
- FdfParsef = None
- OnlyGenerateThisFd = None
- OnlyGenerateThisFv = None
- OnlyGenerateThisCap = None
-
- ## GenFd()
- #
- # @param OutputDir Output directory
- # @param FdfParserObject FDF contents parser
- # @param Workspace The directory of workspace
- # @param ArchList The Arch list of platform
- #
- @staticmethod
- def GenFd (OutputDir, FdfParserObject, WorkSpace, ArchList):
- GenFdsGlobalVariable.SetDir ('', FdfParserObject, WorkSpace, ArchList)
-
- GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")
- if GenFds.OnlyGenerateThisCap is not None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict:
- CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[GenFds.OnlyGenerateThisCap.upper()]
- if CapsuleObj is not None:
- CapsuleObj.GenCapsule()
- return
-
- if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict:
- FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]
- if FdObj is not None:
- FdObj.GenFd()
- return
- elif GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisFv is None:
- for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():
- FdObj.GenFd()
-
- GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")
- if GenFds.OnlyGenerateThisFv is not None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict:
- FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[GenFds.OnlyGenerateThisFv.upper()]
- if FvObj is not None:
- Buffer = BytesIO()
- FvObj.AddToBuffer(Buffer)
- Buffer.close()
- return
- elif GenFds.OnlyGenerateThisFv is None:
- for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict.values():
- Buffer = BytesIO()
- FvObj.AddToBuffer(Buffer)
- Buffer.close()
-
- if GenFds.OnlyGenerateThisFv is None and GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisCap is None:
- if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:
- GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")
- for CapsuleObj in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.values():
- CapsuleObj.GenCapsule()
-
- if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:
- GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")
- for OptRomObj in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.values():
- OptRomObj.AddToBuffer(None)
-
- @staticmethod
- def GenFfsMakefile(OutputDir, FdfParserObject, WorkSpace, ArchList, GlobalData):
- GenFdsGlobalVariable.SetEnv(FdfParserObject, WorkSpace, ArchList, GlobalData)
- for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():
- FdObj.GenFd(Flag=True)
-
- for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict.values():
- FvObj.AddToBuffer(Buffer=None, Flag=True)
-
- if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:
- for OptRomObj in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.values():
- OptRomObj.AddToBuffer(Buffer=None, Flag=True)
-
- return GenFdsGlobalVariable.FfsCmdDict
-
- ## GetFvBlockSize()
- #
- # @param FvObj Whose block size to get
- # @retval int Block size value
- #
- @staticmethod
- def GetFvBlockSize(FvObj):
- DefaultBlockSize = 0x1
- FdObj = None
- if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict:
- FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]
- if FdObj is None:
- for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():
- for ElementRegion in ElementFd.RegionList:
- if ElementRegion.RegionType == BINARY_FILE_TYPE_FV:
- for ElementRegionData in ElementRegion.RegionDataList:
- if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:
- if FvObj.BlockSizeList != []:
- return FvObj.BlockSizeList[0][0]
- else:
- return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)
- if FvObj.BlockSizeList != []:
- return FvObj.BlockSizeList[0][0]
- return DefaultBlockSize
- else:
- for ElementRegion in FdObj.RegionList:
- if ElementRegion.RegionType == BINARY_FILE_TYPE_FV:
- for ElementRegionData in ElementRegion.RegionDataList:
- if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:
- if FvObj.BlockSizeList != []:
- return FvObj.BlockSizeList[0][0]
- else:
- return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)
- return DefaultBlockSize
-
- ## DisplayFvSpaceInfo()
- #
- # @param FvObj Whose block size to get
- # @retval None
- #
- @staticmethod
- def DisplayFvSpaceInfo(FdfParserObject):
-
- FvSpaceInfoList = []
- MaxFvNameLength = 0
- for FvName in FdfParserObject.Profile.FvDict:
- if len(FvName) > MaxFvNameLength:
- MaxFvNameLength = len(FvName)
- FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map')
- if os.path.exists(FvSpaceInfoFileName):
- FileLinesList = getlines(FvSpaceInfoFileName)
- TotalFound = False
- Total = ''
- UsedFound = False
- Used = ''
- FreeFound = False
- Free = ''
- for Line in FileLinesList:
- NameValue = Line.split('=')
- if len(NameValue) == 2:
- if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE':
- TotalFound = True
- Total = NameValue[1].strip()
- if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE':
- UsedFound = True
- Used = NameValue[1].strip()
- if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE':
- FreeFound = True
- Free = NameValue[1].strip()
-
- if TotalFound and UsedFound and FreeFound:
- FvSpaceInfoList.append((FvName, Total, Used, Free))
-
- GenFdsGlobalVariable.InfLogger('\nFV Space Information')
- for FvSpaceInfo in FvSpaceInfoList:
- Name = FvSpaceInfo[0]
- TotalSizeValue = int(FvSpaceInfo[1], 0)
- UsedSizeValue = int(FvSpaceInfo[2], 0)
- FreeSizeValue = int(FvSpaceInfo[3], 0)
- if UsedSizeValue == TotalSizeValue:
- Percentage = '100'
- else:
- Percentage = str((UsedSizeValue + 0.0) / TotalSizeValue)[0:4].lstrip('0.')
-
- GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + Percentage + '%Full] '\
- + str(TotalSizeValue) + ' (' + hex(TotalSizeValue) + ')' + ' total, '\
- + str(UsedSizeValue) + ' (' + hex(UsedSizeValue) + ')' + ' used, '\
- + str(FreeSizeValue) + ' (' + hex(FreeSizeValue) + ')' + ' free')
-
- ## PreprocessImage()
- #
- # @param BuildDb Database from build meta data files
- # @param DscFile modules from dsc file will be preprocessed
- # @retval None
- #
- @staticmethod
- def PreprocessImage(BuildDb, DscFile):
- PcdDict = BuildDb.BuildObject[DscFile, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds
- PcdValue = ''
- for Key in PcdDict:
- PcdObj = PcdDict[Key]
- if PcdObj.TokenCName == 'PcdBsBaseAddress':
- PcdValue = PcdObj.DefaultValue
- break
-
- if PcdValue == '':
- return
-
- Int64PcdValue = int(PcdValue, 0)
- if Int64PcdValue == 0 or Int64PcdValue < -1:
- return
-
- TopAddress = 0
- if Int64PcdValue > 0:
- TopAddress = Int64PcdValue
-
- ModuleDict = BuildDb.BuildObject[DscFile, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Modules
- for Key in ModuleDict:
- ModuleObj = BuildDb.BuildObject[Key, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
- print(ModuleObj.BaseName + ' ' + ModuleObj.ModuleType)
-
- @staticmethod
- def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj):
- GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")
- GuidXRefFile = []
- PkgGuidDict = {}
- GuidDict = {}
- ModuleList = []
- FileGuidList = []
- VariableGuidSet = set()
- for Arch in ArchList:
- PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
- PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag)
- for P in PkgList:
- PkgGuidDict.update(P.Guids)
- for Name, Guid in PlatformDataBase.Pcds:
- Pcd = PlatformDataBase.Pcds[Name, Guid]
- if Pcd.Type in [TAB_PCDS_DYNAMIC_HII, TAB_PCDS_DYNAMIC_EX_HII]:
- for SkuId in Pcd.SkuInfoList:
- Sku = Pcd.SkuInfoList[SkuId]
- if Sku.VariableGuid in VariableGuidSet:continue
- VariableGuidSet.add(Sku.VariableGuid)
- if Sku.VariableGuid and Sku.VariableGuid in PkgGuidDict.keys():
- GuidDict[Sku.VariableGuid] = PkgGuidDict[Sku.VariableGuid]
- for ModuleFile in PlatformDataBase.Modules:
- Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
- if Module in ModuleList:
- continue
- else:
- ModuleList.append(Module)
- if GlobalData.gGuidPattern.match(ModuleFile.BaseName):
- GuidXRefFile.append("%s %s\n" % (ModuleFile.BaseName, Module.BaseName))
- else:
- GuidXRefFile.append("%s %s\n" % (Module.Guid, Module.BaseName))
- GuidDict.update(Module.Protocols)
- GuidDict.update(Module.Guids)
- GuidDict.update(Module.Ppis)
- for FvName in FdfParserObj.Profile.FvDict:
- for FfsObj in FdfParserObj.Profile.FvDict[FvName].FfsList:
- if not isinstance(FfsObj, FileStatement):
- InfPath = PathClass(NormPath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, FfsObj.InfFileName)))
- FdfModule = BuildDb.BuildObject[InfPath, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
- if FdfModule in ModuleList:
- continue
- else:
- ModuleList.append(FdfModule)
- GuidXRefFile.append("%s %s\n" % (FdfModule.Guid, FdfModule.BaseName))
- GuidDict.update(FdfModule.Protocols)
- GuidDict.update(FdfModule.Guids)
- GuidDict.update(FdfModule.Ppis)
- else:
- FileStatementGuid = FfsObj.NameGuid
- if FileStatementGuid in FileGuidList:
- continue
- else:
- FileGuidList.append(FileStatementGuid)
- Name = []
- FfsPath = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')
- FfsPath = glob(os.path.join(FfsPath, FileStatementGuid) + TAB_STAR)
- if not FfsPath:
- continue
- if not os.path.exists(FfsPath[0]):
- continue
- MatchDict = {}
- ReFileEnds = compile(r'\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.te.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$')
- FileList = os.listdir(FfsPath[0])
- for File in FileList:
- Match = ReFileEnds.search(File)
- if Match:
- for Index in range(1, 8):
- if Match.group(Index) and Match.group(Index) in MatchDict:
- MatchDict[Match.group(Index)].append(File)
- elif Match.group(Index):
- MatchDict[Match.group(Index)] = [File]
- if not MatchDict:
- continue
- if '.ui' in MatchDict:
- for File in MatchDict['.ui']:
- with open(os.path.join(FfsPath[0], File), 'rb') as F:
- F.read()
- length = F.tell()
- F.seek(4)
- TmpStr = unpack('%dh' % ((length - 4) // 2), F.read())
- Name = ''.join(chr(c) for c in TmpStr[:-1])
- else:
- FileList = []
- if 'fv.sec.txt' in MatchDict:
- FileList = MatchDict['fv.sec.txt']
- elif '.pe32.txt' in MatchDict:
- FileList = MatchDict['.pe32.txt']
- elif '.te.txt' in MatchDict:
- FileList = MatchDict['.te.txt']
- elif '.pic.txt' in MatchDict:
- FileList = MatchDict['.pic.txt']
- elif '.raw.txt' in MatchDict:
- FileList = MatchDict['.raw.txt']
- elif '.ffs.txt' in MatchDict:
- FileList = MatchDict['.ffs.txt']
- else:
- pass
- for File in FileList:
- with open(os.path.join(FfsPath[0], File), 'r') as F:
- Name.append((F.read().split()[-1]))
- if not Name:
- continue
-
- Name = ' '.join(Name) if isinstance(Name, type([])) else Name
- GuidXRefFile.append("%s %s\n" %(FileStatementGuid, Name))
-
- # Append GUIDs, Protocols, and PPIs to the Xref file
- GuidXRefFile.append("\n")
- for key, item in GuidDict.items():
- GuidXRefFile.append("%s %s\n" % (GuidStructureStringToGuidString(item).upper(), key))
-
- if GuidXRefFile:
- GuidXRefFile = ''.join(GuidXRefFile)
- SaveFileOnChange(GuidXRefFileName, GuidXRefFile, False)
- GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)
- elif os.path.exists(GuidXRefFileName):
- os.remove(GuidXRefFileName)
-
-
-if __name__ == '__main__':
- r = main()
- ## 0-127 is a safe return range, and 1 is a standard default error
- if r < 0 or r > 127:
- r = 1
- exit(r)
-
+## @file +# generate flash image +# +# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import print_function +from __future__ import absolute_import +from re import compile +from optparse import OptionParser +from sys import exit +from glob import glob +from struct import unpack +from linecache import getlines +from io import BytesIO + +import Common.LongFilePathOs as os +from Common.TargetTxtClassObject import TargetTxtDict,gDefaultTargetTxtFile +from Common.DataType import * +import Common.GlobalData as GlobalData +from Common import EdkLogger +from Common.StringUtils import NormPath +from Common.Misc import DirCache, PathClass, GuidStructureStringToGuidString +from Common.Misc import SaveFileOnChange, ClearDuplicatedInf +from Common.BuildVersion import gBUILD_VERSION +from Common.MultipleWorkspace import MultipleWorkspace as mws +from Common.BuildToolError import FatalError, GENFDS_ERROR, CODE_ERROR, FORMAT_INVALID, RESOURCE_NOT_AVAILABLE, FILE_NOT_FOUND, OPTION_MISSING, FORMAT_NOT_SUPPORTED, OPTION_VALUE_INVALID, PARAMETER_INVALID +from Workspace.WorkspaceDatabase import WorkspaceDatabase + +from .FdfParser import FdfParser, Warning +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from .FfsFileStatement import FileStatement +import Common.DataType as DataType +from struct import Struct + +## Version and Copyright +versionNumber = "1.0" + ' ' + gBUILD_VERSION +__version__ = "%prog Version " + versionNumber +__copyright__ = "Copyright (c) 2007 - 2018, Intel Corporation All rights reserved." + +## Tool entrance method +# +# This method mainly dispatch specific methods per the command line options. +# If no error found, return zero value so the caller of this tool can know +# if it's executed successfully or not. +# +# @retval 0 Tool was successful +# @retval 1 Tool failed +# +def main(): + global Options + Options = myOptionParser() + EdkLogger.Initialize() + return GenFdsApi(OptionsToCommandDict(Options)) + +def resetFdsGlobalVariable(): + GenFdsGlobalVariable.FvDir = '' + GenFdsGlobalVariable.OutputDirDict = {} + GenFdsGlobalVariable.BinDir = '' + # will be FvDir + os.sep + 'Ffs' + GenFdsGlobalVariable.FfsDir = '' + GenFdsGlobalVariable.FdfParser = None + GenFdsGlobalVariable.LibDir = '' + GenFdsGlobalVariable.WorkSpace = None + GenFdsGlobalVariable.WorkSpaceDir = '' + GenFdsGlobalVariable.ConfDir = '' + GenFdsGlobalVariable.OutputDirFromDscDict = {} + GenFdsGlobalVariable.TargetName = '' + GenFdsGlobalVariable.ToolChainTag = '' + GenFdsGlobalVariable.RuleDict = {} + GenFdsGlobalVariable.ArchList = None + GenFdsGlobalVariable.ActivePlatform = None + GenFdsGlobalVariable.FvAddressFileName = '' + GenFdsGlobalVariable.VerboseMode = False + GenFdsGlobalVariable.DebugLevel = -1 + GenFdsGlobalVariable.SharpCounter = 0 + GenFdsGlobalVariable.SharpNumberPerLine = 40 + GenFdsGlobalVariable.FdfFile = '' + GenFdsGlobalVariable.FdfFileTimeStamp = 0 + GenFdsGlobalVariable.FixedLoadAddress = False + GenFdsGlobalVariable.PlatformName = '' + + GenFdsGlobalVariable.BuildRuleFamily = DataType.TAB_COMPILER_MSFT + GenFdsGlobalVariable.ToolChainFamily = DataType.TAB_COMPILER_MSFT + GenFdsGlobalVariable.__BuildRuleDatabase = None + GenFdsGlobalVariable.GuidToolDefinition = {} + GenFdsGlobalVariable.FfsCmdDict = {} + GenFdsGlobalVariable.SecCmdList = [] + GenFdsGlobalVariable.CopyList = [] + GenFdsGlobalVariable.ModuleFile = '' + GenFdsGlobalVariable.EnableGenfdsMultiThread = True + + GenFdsGlobalVariable.LargeFileInFvFlags = [] + GenFdsGlobalVariable.EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A' + GenFdsGlobalVariable.LARGE_FILE_SIZE = 0x1000000 + + GenFdsGlobalVariable.SectionHeader = Struct("3B 1B") + + # FvName, FdName, CapName in FDF, Image file name + GenFdsGlobalVariable.ImageBinDict = {} + +def GenFdsApi(FdsCommandDict, WorkSpaceDataBase=None): + global Workspace + Workspace = "" + ArchList = None + ReturnCode = 0 + resetFdsGlobalVariable() + + try: + if FdsCommandDict.get("verbose"): + EdkLogger.SetLevel(EdkLogger.VERBOSE) + GenFdsGlobalVariable.VerboseMode = True + + if FdsCommandDict.get("FixedAddress"): + GenFdsGlobalVariable.FixedLoadAddress = True + + if FdsCommandDict.get("quiet"): + EdkLogger.SetLevel(EdkLogger.QUIET) + if FdsCommandDict.get("debug"): + EdkLogger.SetLevel(FdsCommandDict.get("debug") + 1) + GenFdsGlobalVariable.DebugLevel = FdsCommandDict.get("debug") + else: + EdkLogger.SetLevel(EdkLogger.INFO) + + if not FdsCommandDict.get("Workspace",os.environ.get('WORKSPACE')): + EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined", + ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.") + elif not os.path.exists(FdsCommandDict.get("Workspace",os.environ.get('WORKSPACE'))): + EdkLogger.error("GenFds", PARAMETER_INVALID, "WORKSPACE is invalid", + ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.") + else: + Workspace = os.path.normcase(FdsCommandDict.get("Workspace",os.environ.get('WORKSPACE'))) + GenFdsGlobalVariable.WorkSpaceDir = Workspace + if FdsCommandDict.get("debug"): + GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace) + if FdsCommandDict.get("GenfdsMultiThread"): + GenFdsGlobalVariable.EnableGenfdsMultiThread = True + else: + GenFdsGlobalVariable.EnableGenfdsMultiThread = False + os.chdir(GenFdsGlobalVariable.WorkSpaceDir) + + # set multiple workspace + PackagesPath = os.getenv("PACKAGES_PATH") + mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath) + + if FdsCommandDict.get("fdf_file"): + FdfFilename = FdsCommandDict.get("fdf_file")[0].Path + FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename) + + if FdfFilename[0:2] == '..': + FdfFilename = os.path.abspath(FdfFilename) + if not os.path.isabs(FdfFilename): + FdfFilename = mws.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename) + if not os.path.exists(FdfFilename): + EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=FdfFilename) + + GenFdsGlobalVariable.FdfFile = FdfFilename + GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename) + else: + EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF filename") + + if FdsCommandDict.get("build_target"): + GenFdsGlobalVariable.TargetName = FdsCommandDict.get("build_target") + + if FdsCommandDict.get("toolchain_tag"): + GenFdsGlobalVariable.ToolChainTag = FdsCommandDict.get("toolchain_tag") + + if FdsCommandDict.get("active_platform"): + ActivePlatform = FdsCommandDict.get("active_platform") + ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform) + + if ActivePlatform[0:2] == '..': + ActivePlatform = os.path.abspath(ActivePlatform) + + if not os.path.isabs (ActivePlatform): + ActivePlatform = mws.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform) + + if not os.path.exists(ActivePlatform): + EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!") + else: + EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform") + + GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform)) + + if FdsCommandDict.get("conf_directory"): + # Get alternate Conf location, if it is absolute, then just use the absolute directory name + ConfDirectoryPath = os.path.normpath(FdsCommandDict.get("conf_directory")) + if ConfDirectoryPath.startswith('"'): + ConfDirectoryPath = ConfDirectoryPath[1:] + if ConfDirectoryPath.endswith('"'): + ConfDirectoryPath = ConfDirectoryPath[:-1] + if not os.path.isabs(ConfDirectoryPath): + # Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE + # This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf + ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ConfDirectoryPath) + else: + if "CONF_PATH" in os.environ: + ConfDirectoryPath = os.path.normcase(os.environ["CONF_PATH"]) + else: + # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf + ConfDirectoryPath = mws.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf') + GenFdsGlobalVariable.ConfDir = ConfDirectoryPath + if not GlobalData.gConfDirectory: + GlobalData.gConfDirectory = GenFdsGlobalVariable.ConfDir + BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, gDefaultTargetTxtFile)) + if os.path.isfile(BuildConfigurationFile) == True: + # if no build target given in command line, get it from target.txt + TargetObj = TargetTxtDict() + TargetTxt = TargetObj.Target + if not GenFdsGlobalVariable.TargetName: + BuildTargetList = TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_TARGET] + if len(BuildTargetList) != 1: + EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for Target.") + GenFdsGlobalVariable.TargetName = BuildTargetList[0] + + # if no tool chain given in command line, get it from target.txt + if not GenFdsGlobalVariable.ToolChainTag: + ToolChainList = TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_TOOL_CHAIN_TAG] + if ToolChainList is None or len(ToolChainList) == 0: + EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.") + if len(ToolChainList) != 1: + EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for ToolChain.") + GenFdsGlobalVariable.ToolChainTag = ToolChainList[0] + else: + EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile) + + #Set global flag for build mode + GlobalData.gIgnoreSource = FdsCommandDict.get("IgnoreSources") + + if FdsCommandDict.get("macro"): + for Pair in FdsCommandDict.get("macro"): + if Pair.startswith('"'): + Pair = Pair[1:] + if Pair.endswith('"'): + Pair = Pair[:-1] + List = Pair.split('=') + if len(List) == 2: + if not List[1].strip(): + EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="No Value given for Macro %s" %List[0]) + if List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]: + GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip() + else: + GlobalData.gCommandLineDefines[List[0].strip()] = List[1].strip() + else: + GlobalData.gCommandLineDefines[List[0].strip()] = "TRUE" + os.environ["WORKSPACE"] = Workspace + + # Use the -t and -b option as gGlobalDefines's TOOLCHAIN and TARGET if they are not defined + if "TARGET" not in GlobalData.gGlobalDefines: + GlobalData.gGlobalDefines["TARGET"] = GenFdsGlobalVariable.TargetName + if "TOOLCHAIN" not in GlobalData.gGlobalDefines: + GlobalData.gGlobalDefines["TOOLCHAIN"] = GenFdsGlobalVariable.ToolChainTag + if "TOOL_CHAIN_TAG" not in GlobalData.gGlobalDefines: + GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = GenFdsGlobalVariable.ToolChainTag + + """call Workspace build create database""" + GlobalData.gDatabasePath = os.path.normpath(os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath)) + + if WorkSpaceDataBase: + BuildWorkSpace = WorkSpaceDataBase + else: + BuildWorkSpace = WorkspaceDatabase() + # + # Get files real name in workspace dir + # + GlobalData.gAllFiles = DirCache(Workspace) + GlobalData.gWorkspace = Workspace + + if FdsCommandDict.get("build_architecture_list"): + ArchList = FdsCommandDict.get("build_architecture_list").split(',') + else: + ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].SupArchList + + TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].SupArchList) & set(ArchList) + if len(TargetArchList) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON].SupArchList))) + + for Arch in ArchList: + GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].OutputDirectory) + + # assign platform name based on last entry in ArchList + GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, ArchList[-1], FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].PlatformName + + if FdsCommandDict.get("platform_build_directory"): + OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdsCommandDict.get("platform_build_directory")) + if not os.path.isabs (OutputDirFromCommandLine): + OutputDirFromCommandLine = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, OutputDirFromCommandLine) + for Arch in ArchList: + GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine + else: + for Arch in ArchList: + GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag) + + for Key in GenFdsGlobalVariable.OutputDirDict: + OutputDir = GenFdsGlobalVariable.OutputDirDict[Key] + if OutputDir[0:2] == '..': + OutputDir = os.path.abspath(OutputDir) + + if OutputDir[1] != ':': + OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir) + + if not os.path.exists(OutputDir): + EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=OutputDir) + GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir + + """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """ + if WorkSpaceDataBase: + FdfParserObj = GlobalData.gFdfParser + else: + FdfParserObj = FdfParser(FdfFilename) + FdfParserObj.ParseFile() + + if FdfParserObj.CycleReferenceCheck(): + EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file") + + if FdsCommandDict.get("fd"): + if FdsCommandDict.get("fd")[0].upper() in FdfParserObj.Profile.FdDict: + GenFds.OnlyGenerateThisFd = FdsCommandDict.get("fd")[0] + else: + EdkLogger.error("GenFds", OPTION_VALUE_INVALID, + "No such an FD in FDF file: %s" % FdsCommandDict.get("fd")[0]) + + if FdsCommandDict.get("fv"): + if FdsCommandDict.get("fv")[0].upper() in FdfParserObj.Profile.FvDict: + GenFds.OnlyGenerateThisFv = FdsCommandDict.get("fv")[0] + else: + EdkLogger.error("GenFds", OPTION_VALUE_INVALID, + "No such an FV in FDF file: %s" % FdsCommandDict.get("fv")[0]) + + if FdsCommandDict.get("cap"): + if FdsCommandDict.get("cap")[0].upper() in FdfParserObj.Profile.CapsuleDict: + GenFds.OnlyGenerateThisCap = FdsCommandDict.get("cap")[0] + else: + EdkLogger.error("GenFds", OPTION_VALUE_INVALID, + "No such a Capsule in FDF file: %s" % FdsCommandDict.get("cap")[0]) + + GenFdsGlobalVariable.WorkSpace = BuildWorkSpace + if ArchList: + GenFdsGlobalVariable.ArchList = ArchList + + # Dsc Build Data will handle Pcd Settings from CommandLine. + + """Modify images from build output if the feature of loading driver at fixed address is on.""" + if GenFdsGlobalVariable.FixedLoadAddress: + GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform) + + # Record the FV Region info that may specific in the FD + if FdfParserObj.Profile.FvDict and FdfParserObj.Profile.FdDict: + for FvObj in FdfParserObj.Profile.FvDict.values(): + for FdObj in FdfParserObj.Profile.FdDict.values(): + for RegionObj in FdObj.RegionList: + if RegionObj.RegionType != BINARY_FILE_TYPE_FV: + continue + for RegionData in RegionObj.RegionDataList: + if FvObj.UiFvName.upper() == RegionData.upper(): + if not FvObj.BaseAddress: + FvObj.BaseAddress = '0x%x' % (int(FdObj.BaseAddress, 0) + RegionObj.Offset) + if FvObj.FvRegionInFD: + if FvObj.FvRegionInFD != RegionObj.Size: + EdkLogger.error("GenFds", FORMAT_INVALID, "The FV %s's region is specified in multiple FD with different value." %FvObj.UiFvName) + else: + FvObj.FvRegionInFD = RegionObj.Size + RegionObj.BlockInfoOfRegion(FdObj.BlockSizeList, FvObj) + + """Call GenFds""" + GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList) + + """Generate GUID cross reference file""" + GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList, FdfParserObj) + + """Display FV space info.""" + GenFds.DisplayFvSpaceInfo(FdfParserObj) + + except Warning as X: + EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False) + ReturnCode = FORMAT_INVALID + except FatalError as X: + if FdsCommandDict.get("debug") is not None: + import traceback + EdkLogger.quiet(traceback.format_exc()) + ReturnCode = X.args[0] + except: + import traceback + EdkLogger.error( + "\nPython", + CODE_ERROR, + "Tools code failure", + ExtraData="Please send email to %s for help, attaching following call stack trace!\n" % MSG_EDKII_MAIL_ADDR, + RaiseError=False + ) + EdkLogger.quiet(traceback.format_exc()) + ReturnCode = CODE_ERROR + finally: + ClearDuplicatedInf() + return ReturnCode + +def OptionsToCommandDict(Options): + FdsCommandDict = {} + FdsCommandDict["verbose"] = Options.verbose + FdsCommandDict["FixedAddress"] = Options.FixedAddress + FdsCommandDict["quiet"] = Options.quiet + FdsCommandDict["debug"] = Options.debug + FdsCommandDict["Workspace"] = Options.Workspace + FdsCommandDict["GenfdsMultiThread"] = not Options.NoGenfdsMultiThread + FdsCommandDict["fdf_file"] = [PathClass(Options.filename)] if Options.filename else [] + FdsCommandDict["build_target"] = Options.BuildTarget + FdsCommandDict["toolchain_tag"] = Options.ToolChain + FdsCommandDict["active_platform"] = Options.activePlatform + FdsCommandDict["OptionPcd"] = Options.OptionPcd + FdsCommandDict["conf_directory"] = Options.ConfDirectory + FdsCommandDict["IgnoreSources"] = Options.IgnoreSources + FdsCommandDict["macro"] = Options.Macros + FdsCommandDict["build_architecture_list"] = Options.archList + FdsCommandDict["platform_build_directory"] = Options.outputDir + FdsCommandDict["fd"] = [Options.uiFdName] if Options.uiFdName else [] + FdsCommandDict["fv"] = [Options.uiFvName] if Options.uiFvName else [] + FdsCommandDict["cap"] = [Options.uiCapName] if Options.uiCapName else [] + return FdsCommandDict + + +gParamCheck = [] +def SingleCheckCallback(option, opt_str, value, parser): + if option not in gParamCheck: + setattr(parser.values, option.dest, value) + gParamCheck.append(option) + else: + parser.error("Option %s only allows one instance in command line!" % option) + +## Parse command line options +# +# Using standard Python module optparse to parse command line option of this tool. +# +# @retval Opt A optparse.Values object containing the parsed options +# +def myOptionParser(): + usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\"" + Parser = OptionParser(usage=usage, description=__copyright__, version="%prog " + str(versionNumber)) + Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback) + Parser.add_option("-a", "--arch", dest="archList", help="comma separated list containing one or more of: IA32, X64, IPF, ARM, AARCH64 or EBC which should be built, overrides target.txt?s TARGET_ARCH") + Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.") + Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.") + Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.") + Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.", + action="callback", callback=SingleCheckCallback) + Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE", + action="callback", callback=SingleCheckCallback) + Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory", + action="callback", callback=SingleCheckCallback) + Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.") + Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Build the FV image using the [FV] section named by UiFvName") + Parser.add_option("-C", "--CapsuleImage", dest="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName") + Parser.add_option("-b", "--buildtarget", type="string", dest="BuildTarget", help="Set the build TARGET, overrides target.txt TARGET setting.", + action="callback", callback=SingleCheckCallback) + Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.", + action="callback", callback=SingleCheckCallback) + Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".") + Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.") + Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.") + Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files") + Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ") + Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=True, help="Enable GenFds multi thread to generate ffs file.") + Parser.add_option("--no-genfds-multi-thread", action="store_true", dest="NoGenfdsMultiThread", default=False, help="Disable GenFds multi thread to generate ffs file.") + + Options, _ = Parser.parse_args() + return Options + +## The class implementing the EDK2 flash image generation process +# +# This process includes: +# 1. Collect workspace information, includes platform and module information +# 2. Call methods of Fd class to generate FD +# 3. Call methods of Fv class to generate FV that not belong to FD +# +class GenFds(object): + FdfParsef = None + OnlyGenerateThisFd = None + OnlyGenerateThisFv = None + OnlyGenerateThisCap = None + + ## GenFd() + # + # @param OutputDir Output directory + # @param FdfParserObject FDF contents parser + # @param Workspace The directory of workspace + # @param ArchList The Arch list of platform + # + @staticmethod + def GenFd (OutputDir, FdfParserObject, WorkSpace, ArchList): + GenFdsGlobalVariable.SetDir ('', FdfParserObject, WorkSpace, ArchList) + + GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!") + if GenFds.OnlyGenerateThisCap is not None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict: + CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[GenFds.OnlyGenerateThisCap.upper()] + if CapsuleObj is not None: + CapsuleObj.GenCapsule() + return + + if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict: + FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()] + if FdObj is not None: + FdObj.GenFd() + return + elif GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisFv is None: + for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values(): + FdObj.GenFd() + + GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ") + if GenFds.OnlyGenerateThisFv is not None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict: + FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[GenFds.OnlyGenerateThisFv.upper()] + if FvObj is not None: + Buffer = BytesIO() + FvObj.AddToBuffer(Buffer) + Buffer.close() + return + elif GenFds.OnlyGenerateThisFv is None: + for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict.values(): + Buffer = BytesIO() + FvObj.AddToBuffer(Buffer) + Buffer.close() + + if GenFds.OnlyGenerateThisFv is None and GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisCap is None: + if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}: + GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!") + for CapsuleObj in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.values(): + CapsuleObj.GenCapsule() + + if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}: + GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!") + for OptRomObj in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.values(): + OptRomObj.AddToBuffer(None) + + @staticmethod + def GenFfsMakefile(OutputDir, FdfParserObject, WorkSpace, ArchList, GlobalData): + GenFdsGlobalVariable.SetEnv(FdfParserObject, WorkSpace, ArchList, GlobalData) + for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values(): + FdObj.GenFd(Flag=True) + + for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict.values(): + FvObj.AddToBuffer(Buffer=None, Flag=True) + + if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}: + for OptRomObj in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.values(): + OptRomObj.AddToBuffer(Buffer=None, Flag=True) + + return GenFdsGlobalVariable.FfsCmdDict + + ## GetFvBlockSize() + # + # @param FvObj Whose block size to get + # @retval int Block size value + # + @staticmethod + def GetFvBlockSize(FvObj): + DefaultBlockSize = 0x1 + FdObj = None + if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict: + FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()] + if FdObj is None: + for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values(): + for ElementRegion in ElementFd.RegionList: + if ElementRegion.RegionType == BINARY_FILE_TYPE_FV: + for ElementRegionData in ElementRegion.RegionDataList: + if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName: + if FvObj.BlockSizeList != []: + return FvObj.BlockSizeList[0][0] + else: + return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList) + if FvObj.BlockSizeList != []: + return FvObj.BlockSizeList[0][0] + return DefaultBlockSize + else: + for ElementRegion in FdObj.RegionList: + if ElementRegion.RegionType == BINARY_FILE_TYPE_FV: + for ElementRegionData in ElementRegion.RegionDataList: + if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName: + if FvObj.BlockSizeList != []: + return FvObj.BlockSizeList[0][0] + else: + return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList) + return DefaultBlockSize + + ## DisplayFvSpaceInfo() + # + # @param FvObj Whose block size to get + # @retval None + # + @staticmethod + def DisplayFvSpaceInfo(FdfParserObject): + + FvSpaceInfoList = [] + MaxFvNameLength = 0 + for FvName in FdfParserObject.Profile.FvDict: + if len(FvName) > MaxFvNameLength: + MaxFvNameLength = len(FvName) + FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map') + if os.path.exists(FvSpaceInfoFileName): + FileLinesList = getlines(FvSpaceInfoFileName) + TotalFound = False + Total = '' + UsedFound = False + Used = '' + FreeFound = False + Free = '' + for Line in FileLinesList: + NameValue = Line.split('=') + if len(NameValue) == 2: + if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE': + TotalFound = True + Total = NameValue[1].strip() + if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE': + UsedFound = True + Used = NameValue[1].strip() + if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE': + FreeFound = True + Free = NameValue[1].strip() + + if TotalFound and UsedFound and FreeFound: + FvSpaceInfoList.append((FvName, Total, Used, Free)) + + GenFdsGlobalVariable.InfLogger('\nFV Space Information') + for FvSpaceInfo in FvSpaceInfoList: + Name = FvSpaceInfo[0] + TotalSizeValue = int(FvSpaceInfo[1], 0) + UsedSizeValue = int(FvSpaceInfo[2], 0) + FreeSizeValue = int(FvSpaceInfo[3], 0) + if UsedSizeValue == TotalSizeValue: + Percentage = '100' + else: + Percentage = str((UsedSizeValue + 0.0) / TotalSizeValue)[0:4].lstrip('0.') + + GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + Percentage + '%Full] '\ + + str(TotalSizeValue) + ' (' + hex(TotalSizeValue) + ')' + ' total, '\ + + str(UsedSizeValue) + ' (' + hex(UsedSizeValue) + ')' + ' used, '\ + + str(FreeSizeValue) + ' (' + hex(FreeSizeValue) + ')' + ' free') + + ## PreprocessImage() + # + # @param BuildDb Database from build meta data files + # @param DscFile modules from dsc file will be preprocessed + # @retval None + # + @staticmethod + def PreprocessImage(BuildDb, DscFile): + PcdDict = BuildDb.BuildObject[DscFile, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds + PcdValue = '' + for Key in PcdDict: + PcdObj = PcdDict[Key] + if PcdObj.TokenCName == 'PcdBsBaseAddress': + PcdValue = PcdObj.DefaultValue + break + + if PcdValue == '': + return + + Int64PcdValue = int(PcdValue, 0) + if Int64PcdValue == 0 or Int64PcdValue < -1: + return + + TopAddress = 0 + if Int64PcdValue > 0: + TopAddress = Int64PcdValue + + ModuleDict = BuildDb.BuildObject[DscFile, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Modules + for Key in ModuleDict: + ModuleObj = BuildDb.BuildObject[Key, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] + print(ModuleObj.BaseName + ' ' + ModuleObj.ModuleType) + + @staticmethod + def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj): + GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref") + GuidXRefFile = [] + PkgGuidDict = {} + GuidDict = {} + ModuleList = [] + FileGuidList = [] + VariableGuidSet = set() + for Arch in ArchList: + PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] + PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag) + for P in PkgList: + PkgGuidDict.update(P.Guids) + for Name, Guid in PlatformDataBase.Pcds: + Pcd = PlatformDataBase.Pcds[Name, Guid] + if Pcd.Type in [TAB_PCDS_DYNAMIC_HII, TAB_PCDS_DYNAMIC_EX_HII]: + for SkuId in Pcd.SkuInfoList: + Sku = Pcd.SkuInfoList[SkuId] + if Sku.VariableGuid in VariableGuidSet:continue + VariableGuidSet.add(Sku.VariableGuid) + if Sku.VariableGuid and Sku.VariableGuid in PkgGuidDict.keys(): + GuidDict[Sku.VariableGuid] = PkgGuidDict[Sku.VariableGuid] + for ModuleFile in PlatformDataBase.Modules: + Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] + if Module in ModuleList: + continue + else: + ModuleList.append(Module) + if GlobalData.gGuidPattern.match(ModuleFile.BaseName): + GuidXRefFile.append("%s %s\n" % (ModuleFile.BaseName, Module.BaseName)) + else: + GuidXRefFile.append("%s %s\n" % (Module.Guid, Module.BaseName)) + GuidDict.update(Module.Protocols) + GuidDict.update(Module.Guids) + GuidDict.update(Module.Ppis) + for FvName in FdfParserObj.Profile.FvDict: + for FfsObj in FdfParserObj.Profile.FvDict[FvName].FfsList: + if not isinstance(FfsObj, FileStatement): + InfPath = PathClass(NormPath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, FfsObj.InfFileName))) + FdfModule = BuildDb.BuildObject[InfPath, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] + if FdfModule in ModuleList: + continue + else: + ModuleList.append(FdfModule) + GuidXRefFile.append("%s %s\n" % (FdfModule.Guid, FdfModule.BaseName)) + GuidDict.update(FdfModule.Protocols) + GuidDict.update(FdfModule.Guids) + GuidDict.update(FdfModule.Ppis) + else: + FileStatementGuid = FfsObj.NameGuid + if FileStatementGuid in FileGuidList: + continue + else: + FileGuidList.append(FileStatementGuid) + Name = [] + FfsPath = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs') + FfsPath = glob(os.path.join(FfsPath, FileStatementGuid) + TAB_STAR) + if not FfsPath: + continue + if not os.path.exists(FfsPath[0]): + continue + MatchDict = {} + ReFileEnds = compile(r'\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.te.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$') + FileList = os.listdir(FfsPath[0]) + for File in FileList: + Match = ReFileEnds.search(File) + if Match: + for Index in range(1, 8): + if Match.group(Index) and Match.group(Index) in MatchDict: + MatchDict[Match.group(Index)].append(File) + elif Match.group(Index): + MatchDict[Match.group(Index)] = [File] + if not MatchDict: + continue + if '.ui' in MatchDict: + for File in MatchDict['.ui']: + with open(os.path.join(FfsPath[0], File), 'rb') as F: + F.read() + length = F.tell() + F.seek(4) + TmpStr = unpack('%dh' % ((length - 4) // 2), F.read()) + Name = ''.join(chr(c) for c in TmpStr[:-1]) + else: + FileList = [] + if 'fv.sec.txt' in MatchDict: + FileList = MatchDict['fv.sec.txt'] + elif '.pe32.txt' in MatchDict: + FileList = MatchDict['.pe32.txt'] + elif '.te.txt' in MatchDict: + FileList = MatchDict['.te.txt'] + elif '.pic.txt' in MatchDict: + FileList = MatchDict['.pic.txt'] + elif '.raw.txt' in MatchDict: + FileList = MatchDict['.raw.txt'] + elif '.ffs.txt' in MatchDict: + FileList = MatchDict['.ffs.txt'] + else: + pass + for File in FileList: + with open(os.path.join(FfsPath[0], File), 'r') as F: + Name.append((F.read().split()[-1])) + if not Name: + continue + + Name = ' '.join(Name) if isinstance(Name, type([])) else Name + GuidXRefFile.append("%s %s\n" %(FileStatementGuid, Name)) + + # Append GUIDs, Protocols, and PPIs to the Xref file + GuidXRefFile.append("\n") + for key, item in GuidDict.items(): + GuidXRefFile.append("%s %s\n" % (GuidStructureStringToGuidString(item).upper(), key)) + + if GuidXRefFile: + GuidXRefFile = ''.join(GuidXRefFile) + SaveFileOnChange(GuidXRefFileName, GuidXRefFile, False) + GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName) + elif os.path.exists(GuidXRefFileName): + os.remove(GuidXRefFileName) + + +if __name__ == '__main__': + r = main() + ## 0-127 is a safe return range, and 1 is a standard default error + if r < 0 or r > 127: + r = 1 + exit(r) + diff --git a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py index d7668ba681..a8830556aa 100644 --- a/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py +++ b/BaseTools/Source/Python/GenFds/GenFdsGlobalVariable.py @@ -1,1027 +1,1027 @@ -## @file
-# Global variables for GenFds
-#
-# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import print_function
-from __future__ import absolute_import
-
-import Common.LongFilePathOs as os
-import sys
-from sys import stdout
-from subprocess import PIPE,Popen
-from struct import Struct
-from array import array
-
-from Common.BuildToolError import COMMAND_FAILURE,GENFDS_ERROR
-from Common import EdkLogger
-from Common.Misc import SaveFileOnChange
-
-from Common.TargetTxtClassObject import TargetTxtDict
-from Common.ToolDefClassObject import ToolDefDict,gDefaultToolsDefFile
-from AutoGen.BuildEngine import ToolBuildRule
-import Common.DataType as DataType
-from Common.Misc import PathClass,CreateDirectory
-from Common.LongFilePathSupport import OpenLongFilePath as open
-from Common.MultipleWorkspace import MultipleWorkspace as mws
-import Common.GlobalData as GlobalData
-from Common.BuildToolError import *
-from AutoGen.AutoGen import CalculatePriorityValue
-
-## Global variables
-#
-#
-class GenFdsGlobalVariable:
- FvDir = ''
- OutputDirDict = {}
- BinDir = ''
- # will be FvDir + os.sep + 'Ffs'
- FfsDir = ''
- FdfParser = None
- LibDir = ''
- WorkSpace = None
- WorkSpaceDir = ''
- ConfDir = ''
- OutputDirFromDscDict = {}
- TargetName = ''
- ToolChainTag = ''
- RuleDict = {}
- ArchList = None
- ActivePlatform = None
- FvAddressFileName = ''
- VerboseMode = False
- DebugLevel = -1
- SharpCounter = 0
- SharpNumberPerLine = 40
- FdfFile = ''
- FdfFileTimeStamp = 0
- FixedLoadAddress = False
- PlatformName = ''
-
- BuildRuleFamily = DataType.TAB_COMPILER_MSFT
- ToolChainFamily = DataType.TAB_COMPILER_MSFT
- __BuildRuleDatabase = None
- GuidToolDefinition = {}
- FfsCmdDict = {}
- SecCmdList = []
- CopyList = []
- ModuleFile = ''
- EnableGenfdsMultiThread = True
-
- #
- # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.
- # At the beginning of each generation of FV, false flag is appended to the list,
- # after the call to GenerateSection returns, check the size of the output file,
- # if it is greater than 0xFFFFFF, the tail flag in list is set to true,
- # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv.
- # At the end of generation of FV, pop the flag.
- # List is used as a stack to handle nested FV generation.
- #
- LargeFileInFvFlags = []
- EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'
- LARGE_FILE_SIZE = 0x1000000
-
- SectionHeader = Struct("3B 1B")
-
- # FvName, FdName, CapName in FDF, Image file name
- ImageBinDict = {}
-
- ## LoadBuildRule
- #
- @staticmethod
- def _LoadBuildRule():
- if GenFdsGlobalVariable.__BuildRuleDatabase:
- return GenFdsGlobalVariable.__BuildRuleDatabase
- BuildRule = ToolBuildRule()
- GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule.ToolBuildRule
- TargetObj = TargetTxtDict()
- ToolDefinitionFile = TargetObj.Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
- if ToolDefinitionFile == '':
- ToolDefinitionFile = os.path.join('Conf', gDefaultToolsDefFile)
- if os.path.isfile(ToolDefinitionFile):
- ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf")))
- ToolDefinition = ToolDefObj.ToolDef.ToolsDefTxtDatabase
- if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \
- and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \
- and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]:
- GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]
-
- if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \
- and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \
- and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]:
- GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]
- return GenFdsGlobalVariable.__BuildRuleDatabase
-
- ## GetBuildRules
- # @param Inf: object of InfBuildData
- # @param Arch: current arch
- #
- @staticmethod
- def GetBuildRules(Inf, Arch):
- if not Arch:
- Arch = DataType.TAB_COMMON
-
- if not Arch in GenFdsGlobalVariable.OutputDirDict:
- return {}
-
- BuildRuleDatabase = GenFdsGlobalVariable._LoadBuildRule()
- if not BuildRuleDatabase:
- return {}
-
- PathClassObj = PathClass(Inf.MetaFile.File,
- GenFdsGlobalVariable.WorkSpaceDir)
- BuildDir = os.path.join(
- GenFdsGlobalVariable.OutputDirDict[Arch],
- Arch,
- PathClassObj.SubDir,
- PathClassObj.BaseName
- )
- BinDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)
- Macro = {
- "WORKSPACE":GenFdsGlobalVariable.WorkSpaceDir,
- "MODULE_NAME":Inf.BaseName,
- "MODULE_GUID":Inf.Guid,
- "MODULE_VERSION":Inf.Version,
- "MODULE_TYPE":Inf.ModuleType,
- "MODULE_FILE":str(PathClassObj),
- "MODULE_FILE_BASE_NAME":PathClassObj.BaseName,
- "MODULE_RELATIVE_DIR":PathClassObj.SubDir,
- "MODULE_DIR":PathClassObj.SubDir,
- "BASE_NAME":Inf.BaseName,
- "ARCH":Arch,
- "TOOLCHAIN":GenFdsGlobalVariable.ToolChainTag,
- "TOOLCHAIN_TAG":GenFdsGlobalVariable.ToolChainTag,
- "TOOL_CHAIN_TAG":GenFdsGlobalVariable.ToolChainTag,
- "TARGET":GenFdsGlobalVariable.TargetName,
- "BUILD_DIR":GenFdsGlobalVariable.OutputDirDict[Arch],
- "BIN_DIR":BinDir,
- "LIB_DIR":BinDir,
- "MODULE_BUILD_DIR":BuildDir,
- "OUTPUT_DIR":os.path.join(BuildDir, "OUTPUT"),
- "DEBUG_DIR":os.path.join(BuildDir, "DEBUG")
- }
-
- BuildRules = {}
- for Type in BuildRuleDatabase.FileTypeList:
- #first try getting build rule by BuildRuleFamily
- RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily]
- if not RuleObject:
- # build type is always module type, but ...
- if Inf.ModuleType != Inf.BuildType:
- RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.BuildRuleFamily]
- #second try getting build rule by ToolChainFamily
- if not RuleObject:
- RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily]
- if not RuleObject:
- # build type is always module type, but ...
- if Inf.ModuleType != Inf.BuildType:
- RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily]
- if not RuleObject:
- continue
- RuleObject = RuleObject.Instantiate(Macro)
- BuildRules[Type] = RuleObject
- for Ext in RuleObject.SourceFileExtList:
- BuildRules[Ext] = RuleObject
- return BuildRules
-
- ## GetModuleCodaTargetList
- #
- # @param Inf: object of InfBuildData
- # @param Arch: current arch
- #
- @staticmethod
- def GetModuleCodaTargetList(Inf, Arch):
- BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch)
- if not BuildRules:
- return []
-
- TargetList = set()
- FileList = []
-
- if not Inf.IsBinaryModule:
- for File in Inf.Sources:
- if File.TagName in {"", DataType.TAB_STAR, GenFdsGlobalVariable.ToolChainTag} and \
- File.ToolChainFamily in {"", DataType.TAB_STAR, GenFdsGlobalVariable.ToolChainFamily}:
- FileList.append((File, DataType.TAB_UNKNOWN_FILE))
-
- for File in Inf.Binaries:
- if File.Target in {DataType.TAB_COMMON, DataType.TAB_STAR, GenFdsGlobalVariable.TargetName}:
- FileList.append((File, File.Type))
-
- for File, FileType in FileList:
- LastTarget = None
- RuleChain = []
- SourceList = [File]
- Index = 0
- while Index < len(SourceList):
- Source = SourceList[Index]
- Index = Index + 1
-
- if File.IsBinary and File == Source and Inf.Binaries and File in Inf.Binaries:
- # Skip all files that are not binary libraries
- if not Inf.LibraryClass:
- continue
- RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE]
- elif FileType in BuildRules:
- RuleObject = BuildRules[FileType]
- elif Source.Ext in BuildRules:
- RuleObject = BuildRules[Source.Ext]
- else:
- # stop at no more rules
- if LastTarget:
- TargetList.add(str(LastTarget))
- break
-
- FileType = RuleObject.SourceFileType
-
- # stop at STATIC_LIBRARY for library
- if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY:
- if LastTarget:
- TargetList.add(str(LastTarget))
- break
-
- Target = RuleObject.Apply(Source)
- if not Target:
- if LastTarget:
- TargetList.add(str(LastTarget))
- break
- elif not Target.Outputs:
- # Only do build for target with outputs
- TargetList.add(str(Target))
-
- # to avoid cyclic rule
- if FileType in RuleChain:
- break
-
- RuleChain.append(FileType)
- SourceList.extend(Target.Outputs)
- LastTarget = Target
- FileType = DataType.TAB_UNKNOWN_FILE
- for Cmd in Target.Commands:
- if "$(CP)" == Cmd.split()[0]:
- CpTarget = Cmd.split()[2]
- TargetList.add(CpTarget)
-
- return list(TargetList)
-
- ## SetDir()
- #
- # @param OutputDir Output directory
- # @param FdfParser FDF contents parser
- # @param Workspace The directory of workspace
- # @param ArchList The Arch list of platform
- #
- @staticmethod
- def SetDir (OutputDir, FdfParser, WorkSpace, ArchList):
- GenFdsGlobalVariable.VerboseLogger("GenFdsGlobalVariable.OutputDir:%s" % OutputDir)
- GenFdsGlobalVariable.FdfParser = FdfParser
- GenFdsGlobalVariable.WorkSpace = WorkSpace
- GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY)
- if not os.path.exists(GenFdsGlobalVariable.FvDir):
- os.makedirs(GenFdsGlobalVariable.FvDir)
- GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')
- if not os.path.exists(GenFdsGlobalVariable.FfsDir):
- os.makedirs(GenFdsGlobalVariable.FfsDir)
-
- #
- # Create FV Address inf file
- #
- GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')
- FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')
- #
- # Add [Options]
- #
- FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK)
- BsAddress = '0'
- for Arch in ArchList:
- if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress:
- BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress
- break
-
- FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
- BsAddress + \
- DataType.TAB_LINE_BREAK)
-
- RtAddress = '0'
- for Arch in reversed(ArchList):
- temp = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress
- if temp:
- RtAddress = temp
- break
-
- FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
- RtAddress + \
- DataType.TAB_LINE_BREAK)
-
- FvAddressFile.close()
-
- @staticmethod
- def SetEnv(FdfParser, WorkSpace, ArchList, GlobalData):
- GenFdsGlobalVariable.ModuleFile = WorkSpace.ModuleFile
- GenFdsGlobalVariable.FdfParser = FdfParser
- GenFdsGlobalVariable.WorkSpace = WorkSpace.Db
- GenFdsGlobalVariable.ArchList = ArchList
- GenFdsGlobalVariable.ToolChainTag = GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]
- GenFdsGlobalVariable.TargetName = GlobalData.gGlobalDefines["TARGET"]
- GenFdsGlobalVariable.ActivePlatform = GlobalData.gActivePlatform
- GenFdsGlobalVariable.ConfDir = GlobalData.gConfDirectory
- GenFdsGlobalVariable.EnableGenfdsMultiThread = GlobalData.gEnableGenfdsMultiThread
- for Arch in ArchList:
- GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.normpath(
- os.path.join(GlobalData.gWorkspace,
- WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],
- GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory,
- GlobalData.gGlobalDefines['TARGET'] +'_' + GlobalData.gGlobalDefines['TOOLCHAIN']))
- GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = os.path.normpath(
- WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,
- GlobalData.gGlobalDefines['TARGET'], GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory)
- GenFdsGlobalVariable.PlatformName = WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,
- GlobalData.gGlobalDefines['TARGET'],
- GlobalData.gGlobalDefines['TOOLCHAIN']].PlatformName
- GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY)
- if not os.path.exists(GenFdsGlobalVariable.FvDir):
- os.makedirs(GenFdsGlobalVariable.FvDir)
- GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')
- if not os.path.exists(GenFdsGlobalVariable.FfsDir):
- os.makedirs(GenFdsGlobalVariable.FfsDir)
-
- #
- # Create FV Address inf file
- #
- GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')
- FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')
- #
- # Add [Options]
- #
- FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK)
- BsAddress = '0'
- for Arch in ArchList:
- BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,
- GlobalData.gGlobalDefines['TARGET'],
- GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].BsBaseAddress
- if BsAddress:
- break
-
- FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
- BsAddress + \
- DataType.TAB_LINE_BREAK)
-
- RtAddress = '0'
- for Arch in reversed(ArchList):
- temp = GenFdsGlobalVariable.WorkSpace.BuildObject[
- GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],
- GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress
- if temp:
- RtAddress = temp
- break
-
- FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
- RtAddress + \
- DataType.TAB_LINE_BREAK)
-
- FvAddressFile.close()
-
- ## ReplaceWorkspaceMacro()
- #
- # @param String String that may contain macro
- #
- @staticmethod
- def ReplaceWorkspaceMacro(String):
- String = mws.handleWsMacro(String)
- Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir)
- if os.path.exists(Str):
- if not os.path.isabs(Str):
- Str = os.path.abspath(Str)
- else:
- Str = mws.join(GenFdsGlobalVariable.WorkSpaceDir, String)
- return os.path.normpath(Str)
-
- ## Check if the input files are newer than output files
- #
- # @param Output Path of output file
- # @param Input Path list of input files
- #
- # @retval True if Output doesn't exist, or any Input is newer
- # @retval False if all Input is older than Output
- #
- @staticmethod
- def NeedsUpdate(Output, Input):
- if not os.path.exists(Output):
- return True
- # always update "Output" if no "Input" given
- if not Input:
- return True
-
- # if fdf file is changed after the 'Output" is generated, update the 'Output'
- OutputTime = os.path.getmtime(Output)
- if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime:
- return True
-
- for F in Input:
- # always update "Output" if any "Input" doesn't exist
- if not os.path.exists(F):
- return True
- # always update "Output" if any "Input" is newer than "Output"
- if os.path.getmtime(F) > OutputTime:
- return True
- return False
-
- @staticmethod
- def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,
- GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=[], BuildNumber=None, DummyFile=None, IsMakefile=False):
- Cmd = ["GenSec"]
- if Type:
- Cmd += ("-s", Type)
- if CompressionType:
- Cmd += ("-c", CompressionType)
- if Guid:
- Cmd += ("-g", Guid)
- if DummyFile:
- Cmd += ("--dummy", DummyFile)
- if GuidHdrLen:
- Cmd += ("-l", GuidHdrLen)
- #Add each guided attribute
- for Attr in GuidAttr:
- Cmd += ("-r", Attr)
- #Section Align is only for dummy section without section type
- for SecAlign in InputAlign:
- Cmd += ("--sectionalign", SecAlign)
-
- CommandFile = Output + '.txt'
- if Ui:
- if IsMakefile:
- if Ui == "$(MODULE_NAME)":
- Cmd += ('-n', Ui)
- else:
- Cmd += ("-n", '"' + Ui + '"')
- Cmd += ("-o", Output)
- if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
- GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
- else:
- SectionData = array('B', [0, 0, 0, 0])
- SectionData.fromlist(array('B',Ui.encode('utf-16-le')).tolist())
- SectionData.append(0)
- SectionData.append(0)
- Len = len(SectionData)
- GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)
-
-
- DirName = os.path.dirname(Output)
- if not CreateDirectory(DirName):
- EdkLogger.error(None, FILE_CREATE_FAILURE, "Could not create directory %s" % DirName)
- else:
- if DirName == '':
- DirName = os.getcwd()
- if not os.access(DirName, os.W_OK):
- EdkLogger.error(None, PERMISSION_FAILURE, "Do not have write permission on directory %s" % DirName)
-
- try:
- with open(Output, "wb") as Fd:
- SectionData.tofile(Fd)
- Fd.flush()
- except IOError as X:
- EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData='IOError %s' % X)
-
- elif Ver:
- Cmd += ("-n", Ver)
- if BuildNumber:
- Cmd += ("-j", BuildNumber)
- Cmd += ("-o", Output)
-
- SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
- if IsMakefile:
- if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
- GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
- else:
- if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
- return
- GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
- else:
- Cmd += ("-o", Output)
- Cmd += Input
-
- SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
- if IsMakefile:
- if sys.platform == "win32":
- Cmd = ['if', 'exist', Input[0]] + Cmd
- else:
- Cmd = ['-test', '-e', Input[0], "&&"] + Cmd
- if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
- GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
- elif GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
- GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
- GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
- if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and
- GenFdsGlobalVariable.LargeFileInFvFlags):
- GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True
-
- @staticmethod
- def GetAlignment (AlignString):
- if not AlignString:
- return 0
- if AlignString.endswith('K'):
- return int (AlignString.rstrip('K')) * 1024
- if AlignString.endswith('M'):
- return int (AlignString.rstrip('M')) * 1024 * 1024
- if AlignString.endswith('G'):
- return int (AlignString.rstrip('G')) * 1024 * 1024 * 1024
- return int (AlignString)
-
- @staticmethod
- def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
- SectionAlign=None, MakefilePath=None):
- Cmd = ["GenFfs", "-t", Type, "-g", Guid]
- mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"]
- if Fixed == True:
- Cmd.append("-x")
- if CheckSum:
- Cmd.append("-s")
- if Align:
- if Align not in mFfsValidAlign:
- Align = GenFdsGlobalVariable.GetAlignment (Align)
- for index in range(0, len(mFfsValidAlign) - 1):
- if ((Align > GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index])) and (Align <= GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index + 1]))):
- break
- Align = mFfsValidAlign[index + 1]
- Cmd += ("-a", Align)
-
- Cmd += ("-o", Output)
- for I in range(0, len(Input)):
- if MakefilePath:
- Cmd += ("-oi", Input[I])
- else:
- Cmd += ("-i", Input[I])
- if SectionAlign and SectionAlign[I]:
- Cmd += ("-n", SectionAlign[I])
-
- CommandFile = Output + '.txt'
- SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
-
- GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
- if MakefilePath:
- if (tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)) not in GenFdsGlobalVariable.FfsCmdDict:
- GenFdsGlobalVariable.FfsCmdDict[tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)] = MakefilePath
- GenFdsGlobalVariable.SecCmdList = []
- GenFdsGlobalVariable.CopyList = []
- else:
- if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
- return
- GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")
-
- @staticmethod
- def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False,
- AddressFile=None, MapFile=None, FfsList=[], FileSystemGuid=None):
- if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList):
- return
- GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
-
- Cmd = ["GenFv"]
- if BaseAddress:
- Cmd += ("-r", BaseAddress)
-
- if ForceRebase == False:
- Cmd += ("-F", "FALSE")
- elif ForceRebase == True:
- Cmd += ("-F", "TRUE")
-
- if Capsule:
- Cmd.append("-c")
- if Dump:
- Cmd.append("-p")
- if AddressFile:
- Cmd += ("-a", AddressFile)
- if MapFile:
- Cmd += ("-m", MapFile)
- if FileSystemGuid:
- Cmd += ("-g", FileSystemGuid)
- Cmd += ("-o", Output)
- for I in Input:
- Cmd += ("-i", I)
-
- GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")
-
- @staticmethod
- def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False,
- Strip=False, Replace=False, TimeStamp=None, Join=False,
- Align=None, Padding=None, Convert=False, IsMakefile=False):
- if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:
- return
- GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
-
- Cmd = ["GenFw"]
- if Type.lower() == "te":
- Cmd.append("-t")
- if SubType:
- Cmd += ("-e", SubType)
- if TimeStamp:
- Cmd += ("-s", TimeStamp)
- if Align:
- Cmd += ("-a", Align)
- if Padding:
- Cmd += ("-p", Padding)
- if Zero:
- Cmd.append("-z")
- if Strip:
- Cmd.append("-l")
- if Replace:
- Cmd.append("-r")
- if Join:
- Cmd.append("-j")
- if Convert:
- Cmd.append("-m")
- Cmd += ("-o", Output)
- Cmd += Input
- if IsMakefile:
- if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
- GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())
- else:
- GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")
-
- @staticmethod
- def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None,
- Revision=None, DeviceId=None, VendorId=None, IsMakefile=False):
- InputList = []
- Cmd = ["EfiRom"]
- if EfiInput:
-
- if Compress:
- Cmd.append("-ec")
- else:
- Cmd.append("-e")
-
- for EfiFile in EfiInput:
- Cmd.append(EfiFile)
- InputList.append (EfiFile)
-
- if BinaryInput:
- Cmd.append("-b")
- for BinFile in BinaryInput:
- Cmd.append(BinFile)
- InputList.append (BinFile)
-
- # Check List
- if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList) and not IsMakefile:
- return
- GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList))
-
- if ClassCode:
- Cmd += ("-l", ClassCode)
- if Revision:
- Cmd += ("-r", Revision)
- if DeviceId:
- Cmd += ("-i", DeviceId)
- if VendorId:
- Cmd += ("-f", VendorId)
-
- Cmd += ("-o", Output)
- if IsMakefile:
- if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
- GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())
- else:
- GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")
-
- @staticmethod
- def GuidTool(Output, Input, ToolPath, Options='', returnValue=[], IsMakefile=False):
- if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:
- return
- GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
-
- Cmd = [ToolPath, ]
- Cmd += Options.split(' ')
- Cmd += ("-o", Output)
- Cmd += Input
- if IsMakefile:
- if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
- GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())
- else:
- GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)
-
- @staticmethod
- def CallExternalTool (cmd, errorMess, returnValue=[]):
-
- if type(cmd) not in (tuple, list):
- GenFdsGlobalVariable.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool")
-
- if GenFdsGlobalVariable.DebugLevel != -1:
- cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel))
- GenFdsGlobalVariable.InfLogger (cmd)
-
- if GenFdsGlobalVariable.VerboseMode:
- cmd += ('-v',)
- GenFdsGlobalVariable.InfLogger (cmd)
- else:
- stdout.write ('#')
- stdout.flush()
- GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1
- if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0:
- stdout.write('\n')
-
- try:
- PopenObject = Popen(' '.join(cmd), stdout=PIPE, stderr=PIPE, shell=True)
- except Exception as X:
- EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))
- (out, error) = PopenObject.communicate()
-
- while PopenObject.returncode is None:
- PopenObject.wait()
- if returnValue != [] and returnValue[0] != 0:
- #get command return value
- returnValue[0] = PopenObject.returncode
- return
- if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1:
- GenFdsGlobalVariable.InfLogger ("Return Value = %d" % PopenObject.returncode)
- GenFdsGlobalVariable.InfLogger(out.decode(encoding='utf-8', errors='ignore'))
- GenFdsGlobalVariable.InfLogger(error.decode(encoding='utf-8', errors='ignore'))
- if PopenObject.returncode != 0:
- print("###", cmd)
- EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess)
-
- @staticmethod
- def VerboseLogger (msg):
- EdkLogger.verbose(msg)
-
- @staticmethod
- def InfLogger (msg):
- EdkLogger.info(msg)
-
- @staticmethod
- def ErrorLogger (msg, File=None, Line=None, ExtraData=None):
- EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)
-
- @staticmethod
- def DebugLogger (Level, msg):
- EdkLogger.debug(Level, msg)
-
- ## MacroExtend()
- #
- # @param Str String that may contain macro
- # @param MacroDict Dictionary that contains macro value pair
- #
- @staticmethod
- def MacroExtend (Str, MacroDict=None, Arch=DataType.TAB_COMMON):
- if Str is None:
- return None
-
- Dict = {'$(WORKSPACE)': GenFdsGlobalVariable.WorkSpaceDir,
-# '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
- '$(TARGET)': GenFdsGlobalVariable.TargetName,
- '$(TOOL_CHAIN_TAG)': GenFdsGlobalVariable.ToolChainTag,
- '$(SPACE)': ' '
- }
-
- if Arch != DataType.TAB_COMMON and Arch in GenFdsGlobalVariable.ArchList:
- OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]
- else:
- OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]
-
- Dict['$(OUTPUT_DIRECTORY)'] = OutputDir
-
- if MacroDict:
- Dict.update(MacroDict)
-
- for key in Dict:
- if Str.find(key) >= 0:
- Str = Str.replace (key, Dict[key])
-
- if Str.find('$(ARCH)') >= 0:
- if len(GenFdsGlobalVariable.ArchList) == 1:
- Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0])
- else:
- EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str)
-
- return Str
-
- ## GetPcdValue()
- #
- # @param PcdPattern pattern that labels a PCD.
- #
- @staticmethod
- def GetPcdValue (PcdPattern):
- if PcdPattern is None:
- return None
- if PcdPattern.startswith('PCD('):
- PcdPair = PcdPattern[4:].rstrip(')').strip().split('.')
- else:
- PcdPair = PcdPattern.strip().split('.')
- TokenSpace = PcdPair[0]
- TokenCName = PcdPair[1]
-
- for Arch in GenFdsGlobalVariable.ArchList:
- Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
- PcdDict = Platform.Pcds
- for Key in PcdDict:
- PcdObj = PcdDict[Key]
- if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
- if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD:
- EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
- if PcdObj.DatumType != DataType.TAB_VOID:
- EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
-
- return PcdObj.DefaultValue
-
- for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,
- Arch,
- GenFdsGlobalVariable.TargetName,
- GenFdsGlobalVariable.ToolChainTag):
- PcdDict = Package.Pcds
- for Key in PcdDict:
- PcdObj = PcdDict[Key]
- if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
- if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD:
- EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
- if PcdObj.DatumType != DataType.TAB_VOID:
- EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)
-
- return PcdObj.DefaultValue
-
- return ''
-
-## FindExtendTool()
-#
-# Find location of tools to process data
-#
-# @param KeyStringList Filter for inputs of section generation
-# @param CurrentArchList Arch list
-# @param NameGuid The Guid name
-#
-def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
- if GenFdsGlobalVariable.GuidToolDefinition:
- if NameGuid in GenFdsGlobalVariable.GuidToolDefinition:
- return GenFdsGlobalVariable.GuidToolDefinition[NameGuid]
-
- ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf")))
- ToolDef = ToolDefObj.ToolDef
- ToolDb = ToolDef.ToolsDefTxtDatabase
- # if user not specify filter, try to deduce it from global data.
- if KeyStringList is None or KeyStringList == []:
- Target = GenFdsGlobalVariable.TargetName
- ToolChain = GenFdsGlobalVariable.ToolChainTag
- if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:
- EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain)
- KeyStringList = [Target + '_' + ToolChain + '_' + CurrentArchList[0]]
- for Arch in CurrentArchList:
- if Target + '_' + ToolChain + '_' + Arch not in KeyStringList:
- KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)
-
- ToolPathTmp = None
- ToolOption = None
- for Arch in CurrentArchList:
- MatchItem = None
- MatchPathItem = None
- MatchOptionsItem = None
- for KeyString in KeyStringList:
- KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_')
- if KeyStringArch != Arch:
- continue
- for Item in ToolDef.ToolsDefTxtDictionary:
- if len(Item.split('_')) < 5:
- continue
- ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item.split('_')
- if ItemTarget == DataType.TAB_STAR:
- ItemTarget = KeyStringBuildTarget
- if ItemToolChain == DataType.TAB_STAR:
- ItemToolChain = KeyStringToolChain
- if ItemArch == DataType.TAB_STAR:
- ItemArch = KeyStringArch
- if ItemTarget != KeyStringBuildTarget:
- continue
- if ItemToolChain != KeyStringToolChain:
- continue
- if ItemArch != KeyStringArch:
- continue
- if ItemAttr != DataType.TAB_GUID:
- # Not GUID attribute
- continue
- if ToolDef.ToolsDefTxtDictionary[Item].lower() != NameGuid.lower():
- # No GUID value match
- continue
- if MatchItem:
- if MatchItem.split('_')[3] == ItemTool:
- # Tool name is the same
- continue
- if CalculatePriorityValue(MatchItem) > CalculatePriorityValue(Item):
- # Current MatchItem is higher priority than new match item
- continue
- MatchItem = Item
- if not MatchItem:
- continue
- ToolName = MatchItem.split('_')[3]
- for Item in ToolDef.ToolsDefTxtDictionary:
- if len(Item.split('_')) < 5:
- continue
- ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item.split('_')
- if ItemTarget == DataType.TAB_STAR:
- ItemTarget = KeyStringBuildTarget
- if ItemToolChain == DataType.TAB_STAR:
- ItemToolChain = KeyStringToolChain
- if ItemArch == DataType.TAB_STAR:
- ItemArch = KeyStringArch
- if ItemTarget != KeyStringBuildTarget:
- continue
- if ItemToolChain != KeyStringToolChain:
- continue
- if ItemArch != KeyStringArch:
- continue
- if ItemTool != ToolName:
- continue
- if ItemAttr == 'PATH':
- if MatchPathItem:
- if CalculatePriorityValue(MatchPathItem) <= CalculatePriorityValue(Item):
- MatchPathItem = Item
- else:
- MatchPathItem = Item
- if ItemAttr == 'FLAGS':
- if MatchOptionsItem:
- if CalculatePriorityValue(MatchOptionsItem) <= CalculatePriorityValue(Item):
- MatchOptionsItem = Item
- else:
- MatchOptionsItem = Item
- if MatchPathItem:
- ToolPathTmp = ToolDef.ToolsDefTxtDictionary[MatchPathItem]
- if MatchOptionsItem:
- ToolOption = ToolDef.ToolsDefTxtDictionary[MatchOptionsItem]
-
- for Arch in CurrentArchList:
- MatchItem = None
- MatchPathItem = None
- MatchOptionsItem = None
- for KeyString in KeyStringList:
- KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_')
- if KeyStringArch != Arch:
- continue
- Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, KeyStringBuildTarget, KeyStringToolChain]
- for Item in Platform.BuildOptions:
- if len(Item[1].split('_')) < 5:
- continue
- ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item[1].split('_')
- if ItemTarget == DataType.TAB_STAR:
- ItemTarget = KeyStringBuildTarget
- if ItemToolChain == DataType.TAB_STAR:
- ItemToolChain = KeyStringToolChain
- if ItemArch == DataType.TAB_STAR:
- ItemArch = KeyStringArch
- if ItemTarget != KeyStringBuildTarget:
- continue
- if ItemToolChain != KeyStringToolChain:
- continue
- if ItemArch != KeyStringArch:
- continue
- if ItemAttr != DataType.TAB_GUID:
- # Not GUID attribute match
- continue
- if Platform.BuildOptions[Item].lower() != NameGuid.lower():
- # No GUID value match
- continue
- if MatchItem:
- if MatchItem[1].split('_')[3] == ItemTool:
- # Tool name is the same
- continue
- if CalculatePriorityValue(MatchItem[1]) > CalculatePriorityValue(Item[1]):
- # Current MatchItem is higher priority than new match item
- continue
- MatchItem = Item
- if not MatchItem:
- continue
- ToolName = MatchItem[1].split('_')[3]
- for Item in Platform.BuildOptions:
- if len(Item[1].split('_')) < 5:
- continue
- ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item[1].split('_')
- if ItemTarget == DataType.TAB_STAR:
- ItemTarget = KeyStringBuildTarget
- if ItemToolChain == DataType.TAB_STAR:
- ItemToolChain = KeyStringToolChain
- if ItemArch == DataType.TAB_STAR:
- ItemArch = KeyStringArch
- if ItemTarget != KeyStringBuildTarget:
- continue
- if ItemToolChain != KeyStringToolChain:
- continue
- if ItemArch != KeyStringArch:
- continue
- if ItemTool != ToolName:
- continue
- if ItemAttr == 'PATH':
- if MatchPathItem:
- if CalculatePriorityValue(MatchPathItem[1]) <= CalculatePriorityValue(Item[1]):
- MatchPathItem = Item
- else:
- MatchPathItem = Item
- if ItemAttr == 'FLAGS':
- if MatchOptionsItem:
- if CalculatePriorityValue(MatchOptionsItem[1]) <= CalculatePriorityValue(Item[1]):
- MatchOptionsItem = Item
- else:
- MatchOptionsItem = Item
- if MatchPathItem:
- ToolPathTmp = Platform.BuildOptions[MatchPathItem]
- if MatchOptionsItem:
- ToolOption = Platform.BuildOptions[MatchOptionsItem]
- GenFdsGlobalVariable.GuidToolDefinition[NameGuid] = (ToolPathTmp, ToolOption)
- return ToolPathTmp, ToolOption
+## @file +# Global variables for GenFds +# +# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import print_function +from __future__ import absolute_import + +import Common.LongFilePathOs as os +import sys +from sys import stdout +from subprocess import PIPE,Popen +from struct import Struct +from array import array + +from Common.BuildToolError import COMMAND_FAILURE,GENFDS_ERROR +from Common import EdkLogger +from Common.Misc import SaveFileOnChange + +from Common.TargetTxtClassObject import TargetTxtDict +from Common.ToolDefClassObject import ToolDefDict,gDefaultToolsDefFile +from AutoGen.BuildEngine import ToolBuildRule +import Common.DataType as DataType +from Common.Misc import PathClass,CreateDirectory +from Common.LongFilePathSupport import OpenLongFilePath as open +from Common.MultipleWorkspace import MultipleWorkspace as mws +import Common.GlobalData as GlobalData +from Common.BuildToolError import * +from AutoGen.AutoGen import CalculatePriorityValue + +## Global variables +# +# +class GenFdsGlobalVariable: + FvDir = '' + OutputDirDict = {} + BinDir = '' + # will be FvDir + os.sep + 'Ffs' + FfsDir = '' + FdfParser = None + LibDir = '' + WorkSpace = None + WorkSpaceDir = '' + ConfDir = '' + OutputDirFromDscDict = {} + TargetName = '' + ToolChainTag = '' + RuleDict = {} + ArchList = None + ActivePlatform = None + FvAddressFileName = '' + VerboseMode = False + DebugLevel = -1 + SharpCounter = 0 + SharpNumberPerLine = 40 + FdfFile = '' + FdfFileTimeStamp = 0 + FixedLoadAddress = False + PlatformName = '' + + BuildRuleFamily = DataType.TAB_COMPILER_MSFT + ToolChainFamily = DataType.TAB_COMPILER_MSFT + __BuildRuleDatabase = None + GuidToolDefinition = {} + FfsCmdDict = {} + SecCmdList = [] + CopyList = [] + ModuleFile = '' + EnableGenfdsMultiThread = True + + # + # The list whose element are flags to indicate if large FFS or SECTION files exist in FV. + # At the beginning of each generation of FV, false flag is appended to the list, + # after the call to GenerateSection returns, check the size of the output file, + # if it is greater than 0xFFFFFF, the tail flag in list is set to true, + # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv. + # At the end of generation of FV, pop the flag. + # List is used as a stack to handle nested FV generation. + # + LargeFileInFvFlags = [] + EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A' + LARGE_FILE_SIZE = 0x1000000 + + SectionHeader = Struct("3B 1B") + + # FvName, FdName, CapName in FDF, Image file name + ImageBinDict = {} + + ## LoadBuildRule + # + @staticmethod + def _LoadBuildRule(): + if GenFdsGlobalVariable.__BuildRuleDatabase: + return GenFdsGlobalVariable.__BuildRuleDatabase + BuildRule = ToolBuildRule() + GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule.ToolBuildRule + TargetObj = TargetTxtDict() + ToolDefinitionFile = TargetObj.Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF] + if ToolDefinitionFile == '': + ToolDefinitionFile = os.path.join('Conf', gDefaultToolsDefFile) + if os.path.isfile(ToolDefinitionFile): + ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf"))) + ToolDefinition = ToolDefObj.ToolDef.ToolsDefTxtDatabase + if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \ + and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \ + and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]: + GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag] + + if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \ + and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \ + and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]: + GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag] + return GenFdsGlobalVariable.__BuildRuleDatabase + + ## GetBuildRules + # @param Inf: object of InfBuildData + # @param Arch: current arch + # + @staticmethod + def GetBuildRules(Inf, Arch): + if not Arch: + Arch = DataType.TAB_COMMON + + if not Arch in GenFdsGlobalVariable.OutputDirDict: + return {} + + BuildRuleDatabase = GenFdsGlobalVariable._LoadBuildRule() + if not BuildRuleDatabase: + return {} + + PathClassObj = PathClass(Inf.MetaFile.File, + GenFdsGlobalVariable.WorkSpaceDir) + BuildDir = os.path.join( + GenFdsGlobalVariable.OutputDirDict[Arch], + Arch, + PathClassObj.SubDir, + PathClassObj.BaseName + ) + BinDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch) + Macro = { + "WORKSPACE":GenFdsGlobalVariable.WorkSpaceDir, + "MODULE_NAME":Inf.BaseName, + "MODULE_GUID":Inf.Guid, + "MODULE_VERSION":Inf.Version, + "MODULE_TYPE":Inf.ModuleType, + "MODULE_FILE":str(PathClassObj), + "MODULE_FILE_BASE_NAME":PathClassObj.BaseName, + "MODULE_RELATIVE_DIR":PathClassObj.SubDir, + "MODULE_DIR":PathClassObj.SubDir, + "BASE_NAME":Inf.BaseName, + "ARCH":Arch, + "TOOLCHAIN":GenFdsGlobalVariable.ToolChainTag, + "TOOLCHAIN_TAG":GenFdsGlobalVariable.ToolChainTag, + "TOOL_CHAIN_TAG":GenFdsGlobalVariable.ToolChainTag, + "TARGET":GenFdsGlobalVariable.TargetName, + "BUILD_DIR":GenFdsGlobalVariable.OutputDirDict[Arch], + "BIN_DIR":BinDir, + "LIB_DIR":BinDir, + "MODULE_BUILD_DIR":BuildDir, + "OUTPUT_DIR":os.path.join(BuildDir, "OUTPUT"), + "DEBUG_DIR":os.path.join(BuildDir, "DEBUG") + } + + BuildRules = {} + for Type in BuildRuleDatabase.FileTypeList: + #first try getting build rule by BuildRuleFamily + RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily] + if not RuleObject: + # build type is always module type, but ... + if Inf.ModuleType != Inf.BuildType: + RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.BuildRuleFamily] + #second try getting build rule by ToolChainFamily + if not RuleObject: + RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily] + if not RuleObject: + # build type is always module type, but ... + if Inf.ModuleType != Inf.BuildType: + RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily] + if not RuleObject: + continue + RuleObject = RuleObject.Instantiate(Macro) + BuildRules[Type] = RuleObject + for Ext in RuleObject.SourceFileExtList: + BuildRules[Ext] = RuleObject + return BuildRules + + ## GetModuleCodaTargetList + # + # @param Inf: object of InfBuildData + # @param Arch: current arch + # + @staticmethod + def GetModuleCodaTargetList(Inf, Arch): + BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch) + if not BuildRules: + return [] + + TargetList = set() + FileList = [] + + if not Inf.IsBinaryModule: + for File in Inf.Sources: + if File.TagName in {"", DataType.TAB_STAR, GenFdsGlobalVariable.ToolChainTag} and \ + File.ToolChainFamily in {"", DataType.TAB_STAR, GenFdsGlobalVariable.ToolChainFamily}: + FileList.append((File, DataType.TAB_UNKNOWN_FILE)) + + for File in Inf.Binaries: + if File.Target in {DataType.TAB_COMMON, DataType.TAB_STAR, GenFdsGlobalVariable.TargetName}: + FileList.append((File, File.Type)) + + for File, FileType in FileList: + LastTarget = None + RuleChain = [] + SourceList = [File] + Index = 0 + while Index < len(SourceList): + Source = SourceList[Index] + Index = Index + 1 + + if File.IsBinary and File == Source and Inf.Binaries and File in Inf.Binaries: + # Skip all files that are not binary libraries + if not Inf.LibraryClass: + continue + RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE] + elif FileType in BuildRules: + RuleObject = BuildRules[FileType] + elif Source.Ext in BuildRules: + RuleObject = BuildRules[Source.Ext] + else: + # stop at no more rules + if LastTarget: + TargetList.add(str(LastTarget)) + break + + FileType = RuleObject.SourceFileType + + # stop at STATIC_LIBRARY for library + if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY: + if LastTarget: + TargetList.add(str(LastTarget)) + break + + Target = RuleObject.Apply(Source) + if not Target: + if LastTarget: + TargetList.add(str(LastTarget)) + break + elif not Target.Outputs: + # Only do build for target with outputs + TargetList.add(str(Target)) + + # to avoid cyclic rule + if FileType in RuleChain: + break + + RuleChain.append(FileType) + SourceList.extend(Target.Outputs) + LastTarget = Target + FileType = DataType.TAB_UNKNOWN_FILE + for Cmd in Target.Commands: + if "$(CP)" == Cmd.split()[0]: + CpTarget = Cmd.split()[2] + TargetList.add(CpTarget) + + return list(TargetList) + + ## SetDir() + # + # @param OutputDir Output directory + # @param FdfParser FDF contents parser + # @param Workspace The directory of workspace + # @param ArchList The Arch list of platform + # + @staticmethod + def SetDir (OutputDir, FdfParser, WorkSpace, ArchList): + GenFdsGlobalVariable.VerboseLogger("GenFdsGlobalVariable.OutputDir:%s" % OutputDir) + GenFdsGlobalVariable.FdfParser = FdfParser + GenFdsGlobalVariable.WorkSpace = WorkSpace + GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY) + if not os.path.exists(GenFdsGlobalVariable.FvDir): + os.makedirs(GenFdsGlobalVariable.FvDir) + GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs') + if not os.path.exists(GenFdsGlobalVariable.FfsDir): + os.makedirs(GenFdsGlobalVariable.FfsDir) + + # + # Create FV Address inf file + # + GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf') + FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w') + # + # Add [Options] + # + FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK) + BsAddress = '0' + for Arch in ArchList: + if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress: + BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress + break + + FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \ + BsAddress + \ + DataType.TAB_LINE_BREAK) + + RtAddress = '0' + for Arch in reversed(ArchList): + temp = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress + if temp: + RtAddress = temp + break + + FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \ + RtAddress + \ + DataType.TAB_LINE_BREAK) + + FvAddressFile.close() + + @staticmethod + def SetEnv(FdfParser, WorkSpace, ArchList, GlobalData): + GenFdsGlobalVariable.ModuleFile = WorkSpace.ModuleFile + GenFdsGlobalVariable.FdfParser = FdfParser + GenFdsGlobalVariable.WorkSpace = WorkSpace.Db + GenFdsGlobalVariable.ArchList = ArchList + GenFdsGlobalVariable.ToolChainTag = GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"] + GenFdsGlobalVariable.TargetName = GlobalData.gGlobalDefines["TARGET"] + GenFdsGlobalVariable.ActivePlatform = GlobalData.gActivePlatform + GenFdsGlobalVariable.ConfDir = GlobalData.gConfDirectory + GenFdsGlobalVariable.EnableGenfdsMultiThread = GlobalData.gEnableGenfdsMultiThread + for Arch in ArchList: + GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.normpath( + os.path.join(GlobalData.gWorkspace, + WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'], + GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory, + GlobalData.gGlobalDefines['TARGET'] +'_' + GlobalData.gGlobalDefines['TOOLCHAIN'])) + GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = os.path.normpath( + WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, + GlobalData.gGlobalDefines['TARGET'], GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory) + GenFdsGlobalVariable.PlatformName = WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, + GlobalData.gGlobalDefines['TARGET'], + GlobalData.gGlobalDefines['TOOLCHAIN']].PlatformName + GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY) + if not os.path.exists(GenFdsGlobalVariable.FvDir): + os.makedirs(GenFdsGlobalVariable.FvDir) + GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs') + if not os.path.exists(GenFdsGlobalVariable.FfsDir): + os.makedirs(GenFdsGlobalVariable.FfsDir) + + # + # Create FV Address inf file + # + GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf') + FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w') + # + # Add [Options] + # + FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK) + BsAddress = '0' + for Arch in ArchList: + BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, + GlobalData.gGlobalDefines['TARGET'], + GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].BsBaseAddress + if BsAddress: + break + + FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \ + BsAddress + \ + DataType.TAB_LINE_BREAK) + + RtAddress = '0' + for Arch in reversed(ArchList): + temp = GenFdsGlobalVariable.WorkSpace.BuildObject[ + GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'], + GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress + if temp: + RtAddress = temp + break + + FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \ + RtAddress + \ + DataType.TAB_LINE_BREAK) + + FvAddressFile.close() + + ## ReplaceWorkspaceMacro() + # + # @param String String that may contain macro + # + @staticmethod + def ReplaceWorkspaceMacro(String): + String = mws.handleWsMacro(String) + Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir) + if os.path.exists(Str): + if not os.path.isabs(Str): + Str = os.path.abspath(Str) + else: + Str = mws.join(GenFdsGlobalVariable.WorkSpaceDir, String) + return os.path.normpath(Str) + + ## Check if the input files are newer than output files + # + # @param Output Path of output file + # @param Input Path list of input files + # + # @retval True if Output doesn't exist, or any Input is newer + # @retval False if all Input is older than Output + # + @staticmethod + def NeedsUpdate(Output, Input): + if not os.path.exists(Output): + return True + # always update "Output" if no "Input" given + if not Input: + return True + + # if fdf file is changed after the 'Output" is generated, update the 'Output' + OutputTime = os.path.getmtime(Output) + if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime: + return True + + for F in Input: + # always update "Output" if any "Input" doesn't exist + if not os.path.exists(F): + return True + # always update "Output" if any "Input" is newer than "Output" + if os.path.getmtime(F) > OutputTime: + return True + return False + + @staticmethod + def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None, + GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=[], BuildNumber=None, DummyFile=None, IsMakefile=False): + Cmd = ["GenSec"] + if Type: + Cmd += ("-s", Type) + if CompressionType: + Cmd += ("-c", CompressionType) + if Guid: + Cmd += ("-g", Guid) + if DummyFile: + Cmd += ("--dummy", DummyFile) + if GuidHdrLen: + Cmd += ("-l", GuidHdrLen) + #Add each guided attribute + for Attr in GuidAttr: + Cmd += ("-r", Attr) + #Section Align is only for dummy section without section type + for SecAlign in InputAlign: + Cmd += ("--sectionalign", SecAlign) + + CommandFile = Output + '.txt' + if Ui: + if IsMakefile: + if Ui == "$(MODULE_NAME)": + Cmd += ('-n', Ui) + else: + Cmd += ("-n", '"' + Ui + '"') + Cmd += ("-o", Output) + if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: + GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip()) + else: + SectionData = array('B', [0, 0, 0, 0]) + SectionData.fromlist(array('B',Ui.encode('utf-16-le')).tolist()) + SectionData.append(0) + SectionData.append(0) + Len = len(SectionData) + GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15) + + + DirName = os.path.dirname(Output) + if not CreateDirectory(DirName): + EdkLogger.error(None, FILE_CREATE_FAILURE, "Could not create directory %s" % DirName) + else: + if DirName == '': + DirName = os.getcwd() + if not os.access(DirName, os.W_OK): + EdkLogger.error(None, PERMISSION_FAILURE, "Do not have write permission on directory %s" % DirName) + + try: + with open(Output, "wb") as Fd: + SectionData.tofile(Fd) + Fd.flush() + except IOError as X: + EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData='IOError %s' % X) + + elif Ver: + Cmd += ("-n", Ver) + if BuildNumber: + Cmd += ("-j", BuildNumber) + Cmd += ("-o", Output) + + SaveFileOnChange(CommandFile, ' '.join(Cmd), False) + if IsMakefile: + if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: + GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip()) + else: + if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]): + return + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section") + else: + Cmd += ("-o", Output) + Cmd += Input + + SaveFileOnChange(CommandFile, ' '.join(Cmd), False) + if IsMakefile: + if sys.platform == "win32": + Cmd = ['if', 'exist', Input[0]] + Cmd + else: + Cmd = ['-test', '-e', Input[0], "&&"] + Cmd + if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: + GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip()) + elif GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]): + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section") + if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and + GenFdsGlobalVariable.LargeFileInFvFlags): + GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True + + @staticmethod + def GetAlignment (AlignString): + if not AlignString: + return 0 + if AlignString.endswith('K'): + return int (AlignString.rstrip('K')) * 1024 + if AlignString.endswith('M'): + return int (AlignString.rstrip('M')) * 1024 * 1024 + if AlignString.endswith('G'): + return int (AlignString.rstrip('G')) * 1024 * 1024 * 1024 + return int (AlignString) + + @staticmethod + def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None, + SectionAlign=None, MakefilePath=None): + Cmd = ["GenFfs", "-t", Type, "-g", Guid] + mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"] + if Fixed == True: + Cmd.append("-x") + if CheckSum: + Cmd.append("-s") + if Align: + if Align not in mFfsValidAlign: + Align = GenFdsGlobalVariable.GetAlignment (Align) + for index in range(0, len(mFfsValidAlign) - 1): + if ((Align > GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index])) and (Align <= GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index + 1]))): + break + Align = mFfsValidAlign[index + 1] + Cmd += ("-a", Align) + + Cmd += ("-o", Output) + for I in range(0, len(Input)): + if MakefilePath: + Cmd += ("-oi", Input[I]) + else: + Cmd += ("-i", Input[I]) + if SectionAlign and SectionAlign[I]: + Cmd += ("-n", SectionAlign[I]) + + CommandFile = Output + '.txt' + SaveFileOnChange(CommandFile, ' '.join(Cmd), False) + + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + if MakefilePath: + if (tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)) not in GenFdsGlobalVariable.FfsCmdDict: + GenFdsGlobalVariable.FfsCmdDict[tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)] = MakefilePath + GenFdsGlobalVariable.SecCmdList = [] + GenFdsGlobalVariable.CopyList = [] + else: + if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]): + return + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS") + + @staticmethod + def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False, + AddressFile=None, MapFile=None, FfsList=[], FileSystemGuid=None): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList): + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = ["GenFv"] + if BaseAddress: + Cmd += ("-r", BaseAddress) + + if ForceRebase == False: + Cmd += ("-F", "FALSE") + elif ForceRebase == True: + Cmd += ("-F", "TRUE") + + if Capsule: + Cmd.append("-c") + if Dump: + Cmd.append("-p") + if AddressFile: + Cmd += ("-a", AddressFile) + if MapFile: + Cmd += ("-m", MapFile) + if FileSystemGuid: + Cmd += ("-g", FileSystemGuid) + Cmd += ("-o", Output) + for I in Input: + Cmd += ("-i", I) + + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV") + + @staticmethod + def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False, + Strip=False, Replace=False, TimeStamp=None, Join=False, + Align=None, Padding=None, Convert=False, IsMakefile=False): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile: + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = ["GenFw"] + if Type.lower() == "te": + Cmd.append("-t") + if SubType: + Cmd += ("-e", SubType) + if TimeStamp: + Cmd += ("-s", TimeStamp) + if Align: + Cmd += ("-a", Align) + if Padding: + Cmd += ("-p", Padding) + if Zero: + Cmd.append("-z") + if Strip: + Cmd.append("-l") + if Replace: + Cmd.append("-r") + if Join: + Cmd.append("-j") + if Convert: + Cmd.append("-m") + Cmd += ("-o", Output) + Cmd += Input + if IsMakefile: + if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: + GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip()) + else: + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image") + + @staticmethod + def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None, + Revision=None, DeviceId=None, VendorId=None, IsMakefile=False): + InputList = [] + Cmd = ["EfiRom"] + if EfiInput: + + if Compress: + Cmd.append("-ec") + else: + Cmd.append("-e") + + for EfiFile in EfiInput: + Cmd.append(EfiFile) + InputList.append (EfiFile) + + if BinaryInput: + Cmd.append("-b") + for BinFile in BinaryInput: + Cmd.append(BinFile) + InputList.append (BinFile) + + # Check List + if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList) and not IsMakefile: + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList)) + + if ClassCode: + Cmd += ("-l", ClassCode) + if Revision: + Cmd += ("-r", Revision) + if DeviceId: + Cmd += ("-i", DeviceId) + if VendorId: + Cmd += ("-f", VendorId) + + Cmd += ("-o", Output) + if IsMakefile: + if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: + GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip()) + else: + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom") + + @staticmethod + def GuidTool(Output, Input, ToolPath, Options='', returnValue=[], IsMakefile=False): + if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile: + return + GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input)) + + Cmd = [ToolPath, ] + Cmd += Options.split(' ') + Cmd += ("-o", Output) + Cmd += Input + if IsMakefile: + if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList: + GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip()) + else: + GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue) + + @staticmethod + def CallExternalTool (cmd, errorMess, returnValue=[]): + + if type(cmd) not in (tuple, list): + GenFdsGlobalVariable.ErrorLogger("ToolError! Invalid parameter type in call to CallExternalTool") + + if GenFdsGlobalVariable.DebugLevel != -1: + cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel)) + GenFdsGlobalVariable.InfLogger (cmd) + + if GenFdsGlobalVariable.VerboseMode: + cmd += ('-v',) + GenFdsGlobalVariable.InfLogger (cmd) + else: + stdout.write ('#') + stdout.flush() + GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1 + if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0: + stdout.write('\n') + + try: + PopenObject = Popen(' '.join(cmd), stdout=PIPE, stderr=PIPE, shell=True) + except Exception as X: + EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0])) + (out, error) = PopenObject.communicate() + + while PopenObject.returncode is None: + PopenObject.wait() + if returnValue != [] and returnValue[0] != 0: + #get command return value + returnValue[0] = PopenObject.returncode + return + if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1: + GenFdsGlobalVariable.InfLogger ("Return Value = %d" % PopenObject.returncode) + GenFdsGlobalVariable.InfLogger(out.decode(encoding='utf-8', errors='ignore')) + GenFdsGlobalVariable.InfLogger(error.decode(encoding='utf-8', errors='ignore')) + if PopenObject.returncode != 0: + print("###", cmd) + EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess) + + @staticmethod + def VerboseLogger (msg): + EdkLogger.verbose(msg) + + @staticmethod + def InfLogger (msg): + EdkLogger.info(msg) + + @staticmethod + def ErrorLogger (msg, File=None, Line=None, ExtraData=None): + EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData) + + @staticmethod + def DebugLogger (Level, msg): + EdkLogger.debug(Level, msg) + + ## MacroExtend() + # + # @param Str String that may contain macro + # @param MacroDict Dictionary that contains macro value pair + # + @staticmethod + def MacroExtend (Str, MacroDict=None, Arch=DataType.TAB_COMMON): + if Str is None: + return None + + Dict = {'$(WORKSPACE)': GenFdsGlobalVariable.WorkSpaceDir, +# '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc, + '$(TARGET)': GenFdsGlobalVariable.TargetName, + '$(TOOL_CHAIN_TAG)': GenFdsGlobalVariable.ToolChainTag, + '$(SPACE)': ' ' + } + + if Arch != DataType.TAB_COMMON and Arch in GenFdsGlobalVariable.ArchList: + OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch] + else: + OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]] + + Dict['$(OUTPUT_DIRECTORY)'] = OutputDir + + if MacroDict: + Dict.update(MacroDict) + + for key in Dict: + if Str.find(key) >= 0: + Str = Str.replace (key, Dict[key]) + + if Str.find('$(ARCH)') >= 0: + if len(GenFdsGlobalVariable.ArchList) == 1: + Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0]) + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str) + + return Str + + ## GetPcdValue() + # + # @param PcdPattern pattern that labels a PCD. + # + @staticmethod + def GetPcdValue (PcdPattern): + if PcdPattern is None: + return None + if PcdPattern.startswith('PCD('): + PcdPair = PcdPattern[4:].rstrip(')').strip().split('.') + else: + PcdPair = PcdPattern.strip().split('.') + TokenSpace = PcdPair[0] + TokenCName = PcdPair[1] + + for Arch in GenFdsGlobalVariable.ArchList: + Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] + PcdDict = Platform.Pcds + for Key in PcdDict: + PcdObj = PcdDict[Key] + if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace): + if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD: + EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern) + if PcdObj.DatumType != DataType.TAB_VOID: + EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern) + + return PcdObj.DefaultValue + + for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, + Arch, + GenFdsGlobalVariable.TargetName, + GenFdsGlobalVariable.ToolChainTag): + PcdDict = Package.Pcds + for Key in PcdDict: + PcdObj = PcdDict[Key] + if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace): + if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD: + EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern) + if PcdObj.DatumType != DataType.TAB_VOID: + EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern) + + return PcdObj.DefaultValue + + return '' + +## FindExtendTool() +# +# Find location of tools to process data +# +# @param KeyStringList Filter for inputs of section generation +# @param CurrentArchList Arch list +# @param NameGuid The Guid name +# +def FindExtendTool(KeyStringList, CurrentArchList, NameGuid): + if GenFdsGlobalVariable.GuidToolDefinition: + if NameGuid in GenFdsGlobalVariable.GuidToolDefinition: + return GenFdsGlobalVariable.GuidToolDefinition[NameGuid] + + ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf"))) + ToolDef = ToolDefObj.ToolDef + ToolDb = ToolDef.ToolsDefTxtDatabase + # if user not specify filter, try to deduce it from global data. + if KeyStringList is None or KeyStringList == []: + Target = GenFdsGlobalVariable.TargetName + ToolChain = GenFdsGlobalVariable.ToolChainTag + if ToolChain not in ToolDb['TOOL_CHAIN_TAG']: + EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain) + KeyStringList = [Target + '_' + ToolChain + '_' + CurrentArchList[0]] + for Arch in CurrentArchList: + if Target + '_' + ToolChain + '_' + Arch not in KeyStringList: + KeyStringList.append(Target + '_' + ToolChain + '_' + Arch) + + ToolPathTmp = None + ToolOption = None + for Arch in CurrentArchList: + MatchItem = None + MatchPathItem = None + MatchOptionsItem = None + for KeyString in KeyStringList: + KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_') + if KeyStringArch != Arch: + continue + for Item in ToolDef.ToolsDefTxtDictionary: + if len(Item.split('_')) < 5: + continue + ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item.split('_') + if ItemTarget == DataType.TAB_STAR: + ItemTarget = KeyStringBuildTarget + if ItemToolChain == DataType.TAB_STAR: + ItemToolChain = KeyStringToolChain + if ItemArch == DataType.TAB_STAR: + ItemArch = KeyStringArch + if ItemTarget != KeyStringBuildTarget: + continue + if ItemToolChain != KeyStringToolChain: + continue + if ItemArch != KeyStringArch: + continue + if ItemAttr != DataType.TAB_GUID: + # Not GUID attribute + continue + if ToolDef.ToolsDefTxtDictionary[Item].lower() != NameGuid.lower(): + # No GUID value match + continue + if MatchItem: + if MatchItem.split('_')[3] == ItemTool: + # Tool name is the same + continue + if CalculatePriorityValue(MatchItem) > CalculatePriorityValue(Item): + # Current MatchItem is higher priority than new match item + continue + MatchItem = Item + if not MatchItem: + continue + ToolName = MatchItem.split('_')[3] + for Item in ToolDef.ToolsDefTxtDictionary: + if len(Item.split('_')) < 5: + continue + ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item.split('_') + if ItemTarget == DataType.TAB_STAR: + ItemTarget = KeyStringBuildTarget + if ItemToolChain == DataType.TAB_STAR: + ItemToolChain = KeyStringToolChain + if ItemArch == DataType.TAB_STAR: + ItemArch = KeyStringArch + if ItemTarget != KeyStringBuildTarget: + continue + if ItemToolChain != KeyStringToolChain: + continue + if ItemArch != KeyStringArch: + continue + if ItemTool != ToolName: + continue + if ItemAttr == 'PATH': + if MatchPathItem: + if CalculatePriorityValue(MatchPathItem) <= CalculatePriorityValue(Item): + MatchPathItem = Item + else: + MatchPathItem = Item + if ItemAttr == 'FLAGS': + if MatchOptionsItem: + if CalculatePriorityValue(MatchOptionsItem) <= CalculatePriorityValue(Item): + MatchOptionsItem = Item + else: + MatchOptionsItem = Item + if MatchPathItem: + ToolPathTmp = ToolDef.ToolsDefTxtDictionary[MatchPathItem] + if MatchOptionsItem: + ToolOption = ToolDef.ToolsDefTxtDictionary[MatchOptionsItem] + + for Arch in CurrentArchList: + MatchItem = None + MatchPathItem = None + MatchOptionsItem = None + for KeyString in KeyStringList: + KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_') + if KeyStringArch != Arch: + continue + Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, KeyStringBuildTarget, KeyStringToolChain] + for Item in Platform.BuildOptions: + if len(Item[1].split('_')) < 5: + continue + ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item[1].split('_') + if ItemTarget == DataType.TAB_STAR: + ItemTarget = KeyStringBuildTarget + if ItemToolChain == DataType.TAB_STAR: + ItemToolChain = KeyStringToolChain + if ItemArch == DataType.TAB_STAR: + ItemArch = KeyStringArch + if ItemTarget != KeyStringBuildTarget: + continue + if ItemToolChain != KeyStringToolChain: + continue + if ItemArch != KeyStringArch: + continue + if ItemAttr != DataType.TAB_GUID: + # Not GUID attribute match + continue + if Platform.BuildOptions[Item].lower() != NameGuid.lower(): + # No GUID value match + continue + if MatchItem: + if MatchItem[1].split('_')[3] == ItemTool: + # Tool name is the same + continue + if CalculatePriorityValue(MatchItem[1]) > CalculatePriorityValue(Item[1]): + # Current MatchItem is higher priority than new match item + continue + MatchItem = Item + if not MatchItem: + continue + ToolName = MatchItem[1].split('_')[3] + for Item in Platform.BuildOptions: + if len(Item[1].split('_')) < 5: + continue + ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item[1].split('_') + if ItemTarget == DataType.TAB_STAR: + ItemTarget = KeyStringBuildTarget + if ItemToolChain == DataType.TAB_STAR: + ItemToolChain = KeyStringToolChain + if ItemArch == DataType.TAB_STAR: + ItemArch = KeyStringArch + if ItemTarget != KeyStringBuildTarget: + continue + if ItemToolChain != KeyStringToolChain: + continue + if ItemArch != KeyStringArch: + continue + if ItemTool != ToolName: + continue + if ItemAttr == 'PATH': + if MatchPathItem: + if CalculatePriorityValue(MatchPathItem[1]) <= CalculatePriorityValue(Item[1]): + MatchPathItem = Item + else: + MatchPathItem = Item + if ItemAttr == 'FLAGS': + if MatchOptionsItem: + if CalculatePriorityValue(MatchOptionsItem[1]) <= CalculatePriorityValue(Item[1]): + MatchOptionsItem = Item + else: + MatchOptionsItem = Item + if MatchPathItem: + ToolPathTmp = Platform.BuildOptions[MatchPathItem] + if MatchOptionsItem: + ToolOption = Platform.BuildOptions[MatchOptionsItem] + GenFdsGlobalVariable.GuidToolDefinition[NameGuid] = (ToolPathTmp, ToolOption) + return ToolPathTmp, ToolOption diff --git a/BaseTools/Source/Python/GenFds/GuidSection.py b/BaseTools/Source/Python/GenFds/GuidSection.py index 8db6e2feb3..3e7d967345 100644 --- a/BaseTools/Source/Python/GenFds/GuidSection.py +++ b/BaseTools/Source/Python/GenFds/GuidSection.py @@ -1,278 +1,278 @@ -## @file
-# process GUIDed section generation
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-# Copyright (c) 2018, Hewlett Packard Enterprise Development, L.P.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from . import Section
-import subprocess
-from .Ffs import SectionSuffix
-import Common.LongFilePathOs as os
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-from .GenFdsGlobalVariable import FindExtendTool
-from CommonDataClass.FdfClass import GuidSectionClassObject
-import sys
-from Common import EdkLogger
-from Common.BuildToolError import *
-from .FvImageSection import FvImageSection
-from Common.LongFilePathSupport import OpenLongFilePath as open
-from Common.DataType import *
-
-## generate GUIDed section
-#
-#
-class GuidSection(GuidSectionClassObject) :
-
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- GuidSectionClassObject.__init__(self)
-
- ## GenSection() method
- #
- # Generate GUIDed section
- #
- # @param self The object pointer
- # @param OutputPath Where to place output file
- # @param ModuleName Which module this section belongs to
- # @param SecNum Index of section
- # @param KeyStringList Filter for inputs of section generation
- # @param FfsInf FfsInfStatement object that contains this section data
- # @param Dict dictionary contains macro and its value
- # @retval tuple (Generated file name, section alignment)
- #
- def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict=None, IsMakefile=False):
- #
- # Generate all section
- #
- self.KeyStringList = KeyStringList
- self.CurrentArchList = GenFdsGlobalVariable.ArchList
- if FfsInf is not None:
- self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
- self.NameGuid = FfsInf.__ExtendMacro__(self.NameGuid)
- self.SectionType = FfsInf.__ExtendMacro__(self.SectionType)
- self.CurrentArchList = [FfsInf.CurrentArch]
-
- SectFile = tuple()
- SectAlign = []
- Index = 0
- MaxAlign = None
- if Dict is None:
- Dict = {}
- if self.FvAddr != []:
- FvAddrIsSet = True
- else:
- FvAddrIsSet = False
-
- if self.ProcessRequired in ("TRUE", "1"):
- if self.FvAddr != []:
- #no use FvAddr when the image is processed.
- self.FvAddr = []
- if self.FvParentAddr is not None:
- #no use Parent Addr when the image is processed.
- self.FvParentAddr = None
-
- for Sect in self.SectionList:
- Index = Index + 1
- SecIndex = '%s.%d' % (SecNum, Index)
- # set base address for inside FvImage
- if isinstance(Sect, FvImageSection):
- if self.FvAddr != []:
- Sect.FvAddr = self.FvAddr.pop(0)
- self.IncludeFvSection = True
- elif isinstance(Sect, GuidSection):
- Sect.FvAddr = self.FvAddr
- Sect.FvParentAddr = self.FvParentAddr
- ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict, IsMakefile=IsMakefile)
- if isinstance(Sect, GuidSection):
- if Sect.IncludeFvSection:
- self.IncludeFvSection = Sect.IncludeFvSection
-
- if align is not None:
- if MaxAlign is None:
- MaxAlign = align
- if GenFdsGlobalVariable.GetAlignment (align) > GenFdsGlobalVariable.GetAlignment (MaxAlign):
- MaxAlign = align
- if ReturnSectList != []:
- if align is None:
- align = "1"
- for file in ReturnSectList:
- SectFile += (file,)
- SectAlign.append(align)
-
- if MaxAlign is not None:
- if self.Alignment is None:
- self.Alignment = MaxAlign
- else:
- if GenFdsGlobalVariable.GetAlignment (MaxAlign) > GenFdsGlobalVariable.GetAlignment (self.Alignment):
- self.Alignment = MaxAlign
-
- OutputFile = OutputPath + \
- os.sep + \
- ModuleName + \
- SUP_MODULE_SEC + \
- SecNum + \
- SectionSuffix['GUIDED']
- OutputFile = os.path.normpath(OutputFile)
-
- ExternalTool = None
- ExternalOption = None
- if self.NameGuid is not None:
- ExternalTool, ExternalOption = FindExtendTool(self.KeyStringList, self.CurrentArchList, self.NameGuid)
-
- #
- # If not have GUID , call default
- # GENCRC32 section
- #
- if self.NameGuid is None :
- GenFdsGlobalVariable.VerboseLogger("Use GenSection function Generate CRC32 Section")
- GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign, IsMakefile=IsMakefile)
- OutputFileList = []
- OutputFileList.append(OutputFile)
- return OutputFileList, self.Alignment
- #or GUID not in External Tool List
- elif ExternalTool is None:
- EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % self.NameGuid)
- else:
- DummyFile = OutputFile + ".dummy"
- #
- # Call GenSection with DUMMY section type.
- #
- GenFdsGlobalVariable.GenerateSection(DummyFile, SectFile, InputAlign=SectAlign, IsMakefile=IsMakefile)
- #
- # Use external tool process the Output
- #
- TempFile = OutputPath + \
- os.sep + \
- ModuleName + \
- SUP_MODULE_SEC + \
- SecNum + \
- '.tmp'
- TempFile = os.path.normpath(TempFile)
- #
- # Remove temp file if its time stamp is older than dummy file
- # Just in case the external tool fails at this time but succeeded before
- # Error should be reported if the external tool does not generate a new output based on new input
- #
- if os.path.exists(TempFile) and os.path.exists(DummyFile) and os.path.getmtime(TempFile) < os.path.getmtime(DummyFile):
- os.remove(TempFile)
-
- FirstCall = False
- CmdOption = '-e'
- if ExternalOption is not None:
- CmdOption = CmdOption + ' ' + ExternalOption
- if not GenFdsGlobalVariable.EnableGenfdsMultiThread:
- if self.ProcessRequired not in ("TRUE", "1") and self.IncludeFvSection and not FvAddrIsSet and self.FvParentAddr is not None:
- #FirstCall is only set for the encapsulated flash FV image without process required attribute.
- FirstCall = True
- #
- # Call external tool
- #
- ReturnValue = [1]
- if FirstCall:
- #first try to call the guided tool with -z option and CmdOption for the no process required guided tool.
- GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, '-z' + ' ' + CmdOption, ReturnValue)
-
- #
- # when no call or first call failed, ReturnValue are not 1.
- # Call the guided tool with CmdOption
- #
- if ReturnValue[0] != 0:
- FirstCall = False
- ReturnValue[0] = 0
- GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
- #
- # There is external tool which does not follow standard rule which return nonzero if tool fails
- # The output file has to be checked
- #
-
- if not os.path.exists(TempFile) :
- EdkLogger.error("GenFds", COMMAND_FAILURE, 'Fail to call %s, no output file was generated' % ExternalTool)
-
- FileHandleIn = open(DummyFile, 'rb')
- FileHandleIn.seek(0, 2)
- InputFileSize = FileHandleIn.tell()
-
- FileHandleOut = open(TempFile, 'rb')
- FileHandleOut.seek(0, 2)
- TempFileSize = FileHandleOut.tell()
-
- Attribute = []
- HeaderLength = None
- if self.ExtraHeaderSize != -1:
- HeaderLength = str(self.ExtraHeaderSize)
-
- if self.ProcessRequired == "NONE" and HeaderLength is None:
- if TempFileSize > InputFileSize:
- FileHandleIn.seek(0)
- BufferIn = FileHandleIn.read()
- FileHandleOut.seek(0)
- BufferOut = FileHandleOut.read()
- if BufferIn == BufferOut[TempFileSize - InputFileSize:]:
- HeaderLength = str(TempFileSize - InputFileSize)
- #auto sec guided attribute with process required
- if HeaderLength is None:
- Attribute.append('PROCESSING_REQUIRED')
-
- FileHandleIn.close()
- FileHandleOut.close()
-
- if FirstCall and 'PROCESSING_REQUIRED' in Attribute:
- # Guided data by -z option on first call is the process required data. Call the guided tool with the real option.
- GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
-
- #
- # Call Gensection Add Section Header
- #
- if self.ProcessRequired in ("TRUE", "1"):
- if 'PROCESSING_REQUIRED' not in Attribute:
- Attribute.append('PROCESSING_REQUIRED')
-
- if self.AuthStatusValid in ("TRUE", "1"):
- Attribute.append('AUTH_STATUS_VALID')
- GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
- Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength)
-
- else:
- #add input file for GenSec get PROCESSING_REQUIRED
- GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption, IsMakefile=IsMakefile)
- Attribute = []
- HeaderLength = None
- if self.ExtraHeaderSize != -1:
- HeaderLength = str(self.ExtraHeaderSize)
- if self.AuthStatusValid in ("TRUE", "1"):
- Attribute.append('AUTH_STATUS_VALID')
- if self.ProcessRequired == "NONE" and HeaderLength is None:
- GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
- Guid=self.NameGuid, GuidAttr=Attribute,
- GuidHdrLen=HeaderLength, DummyFile=DummyFile, IsMakefile=IsMakefile)
- else:
- if self.ProcessRequired in ("TRUE", "1"):
- if 'PROCESSING_REQUIRED' not in Attribute:
- Attribute.append('PROCESSING_REQUIRED')
- GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
- Guid=self.NameGuid, GuidAttr=Attribute,
- GuidHdrLen=HeaderLength, IsMakefile=IsMakefile)
-
- OutputFileList = []
- OutputFileList.append(OutputFile)
- if 'PROCESSING_REQUIRED' in Attribute:
- # reset guided section alignment to none for the processed required guided data
- self.Alignment = None
- self.IncludeFvSection = False
- self.ProcessRequired = "TRUE"
- if IsMakefile and self.Alignment is not None and self.Alignment.strip() == '0':
- self.Alignment = '1'
- return OutputFileList, self.Alignment
-
-
-
+## @file +# process GUIDed section generation +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# Copyright (c) 2018, Hewlett Packard Enterprise Development, L.P.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from . import Section +import subprocess +from .Ffs import SectionSuffix +import Common.LongFilePathOs as os +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from .GenFdsGlobalVariable import FindExtendTool +from CommonDataClass.FdfClass import GuidSectionClassObject +import sys +from Common import EdkLogger +from Common.BuildToolError import * +from .FvImageSection import FvImageSection +from Common.LongFilePathSupport import OpenLongFilePath as open +from Common.DataType import * + +## generate GUIDed section +# +# +class GuidSection(GuidSectionClassObject) : + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + GuidSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate GUIDed section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict=None, IsMakefile=False): + # + # Generate all section + # + self.KeyStringList = KeyStringList + self.CurrentArchList = GenFdsGlobalVariable.ArchList + if FfsInf is not None: + self.Alignment = FfsInf.__ExtendMacro__(self.Alignment) + self.NameGuid = FfsInf.__ExtendMacro__(self.NameGuid) + self.SectionType = FfsInf.__ExtendMacro__(self.SectionType) + self.CurrentArchList = [FfsInf.CurrentArch] + + SectFile = tuple() + SectAlign = [] + Index = 0 + MaxAlign = None + if Dict is None: + Dict = {} + if self.FvAddr != []: + FvAddrIsSet = True + else: + FvAddrIsSet = False + + if self.ProcessRequired in ("TRUE", "1"): + if self.FvAddr != []: + #no use FvAddr when the image is processed. + self.FvAddr = [] + if self.FvParentAddr is not None: + #no use Parent Addr when the image is processed. + self.FvParentAddr = None + + for Sect in self.SectionList: + Index = Index + 1 + SecIndex = '%s.%d' % (SecNum, Index) + # set base address for inside FvImage + if isinstance(Sect, FvImageSection): + if self.FvAddr != []: + Sect.FvAddr = self.FvAddr.pop(0) + self.IncludeFvSection = True + elif isinstance(Sect, GuidSection): + Sect.FvAddr = self.FvAddr + Sect.FvParentAddr = self.FvParentAddr + ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict, IsMakefile=IsMakefile) + if isinstance(Sect, GuidSection): + if Sect.IncludeFvSection: + self.IncludeFvSection = Sect.IncludeFvSection + + if align is not None: + if MaxAlign is None: + MaxAlign = align + if GenFdsGlobalVariable.GetAlignment (align) > GenFdsGlobalVariable.GetAlignment (MaxAlign): + MaxAlign = align + if ReturnSectList != []: + if align is None: + align = "1" + for file in ReturnSectList: + SectFile += (file,) + SectAlign.append(align) + + if MaxAlign is not None: + if self.Alignment is None: + self.Alignment = MaxAlign + else: + if GenFdsGlobalVariable.GetAlignment (MaxAlign) > GenFdsGlobalVariable.GetAlignment (self.Alignment): + self.Alignment = MaxAlign + + OutputFile = OutputPath + \ + os.sep + \ + ModuleName + \ + SUP_MODULE_SEC + \ + SecNum + \ + SectionSuffix['GUIDED'] + OutputFile = os.path.normpath(OutputFile) + + ExternalTool = None + ExternalOption = None + if self.NameGuid is not None: + ExternalTool, ExternalOption = FindExtendTool(self.KeyStringList, self.CurrentArchList, self.NameGuid) + + # + # If not have GUID , call default + # GENCRC32 section + # + if self.NameGuid is None : + GenFdsGlobalVariable.VerboseLogger("Use GenSection function Generate CRC32 Section") + GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign, IsMakefile=IsMakefile) + OutputFileList = [] + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment + #or GUID not in External Tool List + elif ExternalTool is None: + EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % self.NameGuid) + else: + DummyFile = OutputFile + ".dummy" + # + # Call GenSection with DUMMY section type. + # + GenFdsGlobalVariable.GenerateSection(DummyFile, SectFile, InputAlign=SectAlign, IsMakefile=IsMakefile) + # + # Use external tool process the Output + # + TempFile = OutputPath + \ + os.sep + \ + ModuleName + \ + SUP_MODULE_SEC + \ + SecNum + \ + '.tmp' + TempFile = os.path.normpath(TempFile) + # + # Remove temp file if its time stamp is older than dummy file + # Just in case the external tool fails at this time but succeeded before + # Error should be reported if the external tool does not generate a new output based on new input + # + if os.path.exists(TempFile) and os.path.exists(DummyFile) and os.path.getmtime(TempFile) < os.path.getmtime(DummyFile): + os.remove(TempFile) + + FirstCall = False + CmdOption = '-e' + if ExternalOption is not None: + CmdOption = CmdOption + ' ' + ExternalOption + if not GenFdsGlobalVariable.EnableGenfdsMultiThread: + if self.ProcessRequired not in ("TRUE", "1") and self.IncludeFvSection and not FvAddrIsSet and self.FvParentAddr is not None: + #FirstCall is only set for the encapsulated flash FV image without process required attribute. + FirstCall = True + # + # Call external tool + # + ReturnValue = [1] + if FirstCall: + #first try to call the guided tool with -z option and CmdOption for the no process required guided tool. + GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, '-z' + ' ' + CmdOption, ReturnValue) + + # + # when no call or first call failed, ReturnValue are not 1. + # Call the guided tool with CmdOption + # + if ReturnValue[0] != 0: + FirstCall = False + ReturnValue[0] = 0 + GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption) + # + # There is external tool which does not follow standard rule which return nonzero if tool fails + # The output file has to be checked + # + + if not os.path.exists(TempFile) : + EdkLogger.error("GenFds", COMMAND_FAILURE, 'Fail to call %s, no output file was generated' % ExternalTool) + + FileHandleIn = open(DummyFile, 'rb') + FileHandleIn.seek(0, 2) + InputFileSize = FileHandleIn.tell() + + FileHandleOut = open(TempFile, 'rb') + FileHandleOut.seek(0, 2) + TempFileSize = FileHandleOut.tell() + + Attribute = [] + HeaderLength = None + if self.ExtraHeaderSize != -1: + HeaderLength = str(self.ExtraHeaderSize) + + if self.ProcessRequired == "NONE" and HeaderLength is None: + if TempFileSize > InputFileSize: + FileHandleIn.seek(0) + BufferIn = FileHandleIn.read() + FileHandleOut.seek(0) + BufferOut = FileHandleOut.read() + if BufferIn == BufferOut[TempFileSize - InputFileSize:]: + HeaderLength = str(TempFileSize - InputFileSize) + #auto sec guided attribute with process required + if HeaderLength is None: + Attribute.append('PROCESSING_REQUIRED') + + FileHandleIn.close() + FileHandleOut.close() + + if FirstCall and 'PROCESSING_REQUIRED' in Attribute: + # Guided data by -z option on first call is the process required data. Call the guided tool with the real option. + GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption) + + # + # Call Gensection Add Section Header + # + if self.ProcessRequired in ("TRUE", "1"): + if 'PROCESSING_REQUIRED' not in Attribute: + Attribute.append('PROCESSING_REQUIRED') + + if self.AuthStatusValid in ("TRUE", "1"): + Attribute.append('AUTH_STATUS_VALID') + GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'], + Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength) + + else: + #add input file for GenSec get PROCESSING_REQUIRED + GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption, IsMakefile=IsMakefile) + Attribute = [] + HeaderLength = None + if self.ExtraHeaderSize != -1: + HeaderLength = str(self.ExtraHeaderSize) + if self.AuthStatusValid in ("TRUE", "1"): + Attribute.append('AUTH_STATUS_VALID') + if self.ProcessRequired == "NONE" and HeaderLength is None: + GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'], + Guid=self.NameGuid, GuidAttr=Attribute, + GuidHdrLen=HeaderLength, DummyFile=DummyFile, IsMakefile=IsMakefile) + else: + if self.ProcessRequired in ("TRUE", "1"): + if 'PROCESSING_REQUIRED' not in Attribute: + Attribute.append('PROCESSING_REQUIRED') + GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'], + Guid=self.NameGuid, GuidAttr=Attribute, + GuidHdrLen=HeaderLength, IsMakefile=IsMakefile) + + OutputFileList = [] + OutputFileList.append(OutputFile) + if 'PROCESSING_REQUIRED' in Attribute: + # reset guided section alignment to none for the processed required guided data + self.Alignment = None + self.IncludeFvSection = False + self.ProcessRequired = "TRUE" + if IsMakefile and self.Alignment is not None and self.Alignment.strip() == '0': + self.Alignment = '1' + return OutputFileList, self.Alignment + + + diff --git a/BaseTools/Source/Python/GenFds/OptRomFileStatement.py b/BaseTools/Source/Python/GenFds/OptRomFileStatement.py index 1bd4d4572a..f6d8a529ac 100644 --- a/BaseTools/Source/Python/GenFds/OptRomFileStatement.py +++ b/BaseTools/Source/Python/GenFds/OptRomFileStatement.py @@ -1,48 +1,48 @@ -## @file
-# process OptionROM generation from FILE statement
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-import Common.LongFilePathOs as os
-
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-##
-#
-#
-class OptRomFileStatement:
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- self.FileName = None
- self.FileType = None
- self.OverrideAttribs = None
-
- ## GenFfs() method
- #
- # Generate FFS
- #
- # @param self The object pointer
- # @param Dict dictionary contains macro and value pair
- # @retval string Generated FFS file name
- #
- def GenFfs(self, Dict = None, IsMakefile=False):
-
- if Dict is None:
- Dict = {}
-
- if self.FileName is not None:
- self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
-
- return self.FileName
-
-
-
+## @file +# process OptionROM generation from FILE statement +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +import Common.LongFilePathOs as os + +from .GenFdsGlobalVariable import GenFdsGlobalVariable +## +# +# +class OptRomFileStatement: + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.FileName = None + self.FileType = None + self.OverrideAttribs = None + + ## GenFfs() method + # + # Generate FFS + # + # @param self The object pointer + # @param Dict dictionary contains macro and value pair + # @retval string Generated FFS file name + # + def GenFfs(self, Dict = None, IsMakefile=False): + + if Dict is None: + Dict = {} + + if self.FileName is not None: + self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName) + + return self.FileName + + + diff --git a/BaseTools/Source/Python/GenFds/OptRomInfStatement.py b/BaseTools/Source/Python/GenFds/OptRomInfStatement.py index 8b570ed6bc..43fd46ad99 100644 --- a/BaseTools/Source/Python/GenFds/OptRomInfStatement.py +++ b/BaseTools/Source/Python/GenFds/OptRomInfStatement.py @@ -1,159 +1,159 @@ -## @file
-# process OptionROM generation from INF statement
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from . import RuleSimpleFile
-from . import RuleComplexFile
-from . import Section
-import Common.GlobalData as GlobalData
-
-from Common.DataType import *
-from Common.StringUtils import *
-from .FfsInfStatement import FfsInfStatement
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-
-##
-#
-#
-class OptRomInfStatement (FfsInfStatement):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- FfsInfStatement.__init__(self)
- self.OverrideAttribs = None
-
- ## __GetOptRomParams() method
- #
- # Parse inf file to get option ROM related parameters
- #
- # @param self The object pointer
- #
- def __GetOptRomParams(self):
- if self.OverrideAttribs is None:
- self.OverrideAttribs = OverrideAttribs()
-
- if self.OverrideAttribs.NeedCompress is None:
- self.OverrideAttribs.NeedCompress = self.OptRomDefs.get ('PCI_COMPRESS')
- if self.OverrideAttribs.NeedCompress is not None:
- if self.OverrideAttribs.NeedCompress.upper() not in ('TRUE', 'FALSE'):
- GenFdsGlobalVariable.ErrorLogger( "Expected TRUE/FALSE for PCI_COMPRESS: %s" %self.InfFileName)
- self.OverrideAttribs.NeedCompress = \
- self.OverrideAttribs.NeedCompress.upper() == 'TRUE'
-
- if self.OverrideAttribs.PciVendorId is None:
- self.OverrideAttribs.PciVendorId = self.OptRomDefs.get ('PCI_VENDOR_ID')
-
- if self.OverrideAttribs.PciClassCode is None:
- self.OverrideAttribs.PciClassCode = self.OptRomDefs.get ('PCI_CLASS_CODE')
-
- if self.OverrideAttribs.PciDeviceId is None:
- self.OverrideAttribs.PciDeviceId = self.OptRomDefs.get ('PCI_DEVICE_ID')
-
- if self.OverrideAttribs.PciRevision is None:
- self.OverrideAttribs.PciRevision = self.OptRomDefs.get ('PCI_REVISION')
-
-# InfObj = GenFdsGlobalVariable.WorkSpace.BuildObject[self.PathClassObj, self.CurrentArch]
-# RecordList = InfObj._RawData[MODEL_META_DATA_HEADER, InfObj._Arch, InfObj._Platform]
-# for Record in RecordList:
-# Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
-# Name = Record[0]
- ## GenFfs() method
- #
- # Generate FFS
- #
- # @param self The object pointer
- # @retval string Generated .efi file name
- #
- def GenFfs(self, IsMakefile=False):
- #
- # Parse Inf file get Module related information
- #
-
- self.__InfParse__()
- self.__GetOptRomParams()
- #
- # Get the rule of how to generate Ffs file
- #
- Rule = self.__GetRule__()
- GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName)
- #
- # For the rule only has simpleFile
- #
- if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) :
- EfiOutputList = self.__GenSimpleFileSection__(Rule, IsMakefile=IsMakefile)
- return EfiOutputList
- #
- # For Rule has ComplexFile
- #
- elif isinstance(Rule, RuleComplexFile.RuleComplexFile):
- EfiOutputList = self.__GenComplexFileSection__(Rule, IsMakefile=IsMakefile)
- return EfiOutputList
-
- ## __GenSimpleFileSection__() method
- #
- # Get .efi files according to simple rule.
- #
- # @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
- #
-
- OutputFileList = []
- if Rule.FileName is not None:
- GenSecInputFile = self.__ExtendMacro__(Rule.FileName)
- OutputFileList.append(GenSecInputFile)
- else:
- OutputFileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension)
-
- return OutputFileList
-
-
- ## __GenComplexFileSection__() method
- #
- # Get .efi by sections in complex Rule
- #
- # @param self The object pointer
- # @param Rule The rule object used to generate section
- # @retval string File name of the generated section file
- #
- def __GenComplexFileSection__(self, Rule, IsMakefile=False):
-
- OutputFileList = []
- for Sect in Rule.SectionList:
- if Sect.SectionType == BINARY_FILE_TYPE_PE32:
- if Sect.FileName is not None:
- GenSecInputFile = self.__ExtendMacro__(Sect.FileName)
- OutputFileList.append(GenSecInputFile)
- else:
- FileList, IsSect = Section.Section.GetFileList(self, '', Sect.FileExtension)
- OutputFileList.extend(FileList)
-
- return OutputFileList
-
-class OverrideAttribs:
-
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
-
- self.PciVendorId = None
- self.PciClassCode = None
- self.PciDeviceId = None
- self.PciRevision = None
- self.NeedCompress = None
+## @file +# process OptionROM generation from INF statement +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from . import RuleSimpleFile +from . import RuleComplexFile +from . import Section +import Common.GlobalData as GlobalData + +from Common.DataType import * +from Common.StringUtils import * +from .FfsInfStatement import FfsInfStatement +from .GenFdsGlobalVariable import GenFdsGlobalVariable + +## +# +# +class OptRomInfStatement (FfsInfStatement): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + FfsInfStatement.__init__(self) + self.OverrideAttribs = None + + ## __GetOptRomParams() method + # + # Parse inf file to get option ROM related parameters + # + # @param self The object pointer + # + def __GetOptRomParams(self): + if self.OverrideAttribs is None: + self.OverrideAttribs = OverrideAttribs() + + if self.OverrideAttribs.NeedCompress is None: + self.OverrideAttribs.NeedCompress = self.OptRomDefs.get ('PCI_COMPRESS') + if self.OverrideAttribs.NeedCompress is not None: + if self.OverrideAttribs.NeedCompress.upper() not in ('TRUE', 'FALSE'): + GenFdsGlobalVariable.ErrorLogger( "Expected TRUE/FALSE for PCI_COMPRESS: %s" %self.InfFileName) + self.OverrideAttribs.NeedCompress = \ + self.OverrideAttribs.NeedCompress.upper() == 'TRUE' + + if self.OverrideAttribs.PciVendorId is None: + self.OverrideAttribs.PciVendorId = self.OptRomDefs.get ('PCI_VENDOR_ID') + + if self.OverrideAttribs.PciClassCode is None: + self.OverrideAttribs.PciClassCode = self.OptRomDefs.get ('PCI_CLASS_CODE') + + if self.OverrideAttribs.PciDeviceId is None: + self.OverrideAttribs.PciDeviceId = self.OptRomDefs.get ('PCI_DEVICE_ID') + + if self.OverrideAttribs.PciRevision is None: + self.OverrideAttribs.PciRevision = self.OptRomDefs.get ('PCI_REVISION') + +# InfObj = GenFdsGlobalVariable.WorkSpace.BuildObject[self.PathClassObj, self.CurrentArch] +# RecordList = InfObj._RawData[MODEL_META_DATA_HEADER, InfObj._Arch, InfObj._Platform] +# for Record in RecordList: +# Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False) +# Name = Record[0] + ## GenFfs() method + # + # Generate FFS + # + # @param self The object pointer + # @retval string Generated .efi file name + # + def GenFfs(self, IsMakefile=False): + # + # Parse Inf file get Module related information + # + + self.__InfParse__() + self.__GetOptRomParams() + # + # Get the rule of how to generate Ffs file + # + Rule = self.__GetRule__() + GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName) + # + # For the rule only has simpleFile + # + if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) : + EfiOutputList = self.__GenSimpleFileSection__(Rule, IsMakefile=IsMakefile) + return EfiOutputList + # + # For Rule has ComplexFile + # + elif isinstance(Rule, RuleComplexFile.RuleComplexFile): + EfiOutputList = self.__GenComplexFileSection__(Rule, IsMakefile=IsMakefile) + return EfiOutputList + + ## __GenSimpleFileSection__() method + # + # Get .efi files according to simple rule. + # + # @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 + # + + OutputFileList = [] + if Rule.FileName is not None: + GenSecInputFile = self.__ExtendMacro__(Rule.FileName) + OutputFileList.append(GenSecInputFile) + else: + OutputFileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension) + + return OutputFileList + + + ## __GenComplexFileSection__() method + # + # Get .efi by sections in complex Rule + # + # @param self The object pointer + # @param Rule The rule object used to generate section + # @retval string File name of the generated section file + # + def __GenComplexFileSection__(self, Rule, IsMakefile=False): + + OutputFileList = [] + for Sect in Rule.SectionList: + if Sect.SectionType == BINARY_FILE_TYPE_PE32: + if Sect.FileName is not None: + GenSecInputFile = self.__ExtendMacro__(Sect.FileName) + OutputFileList.append(GenSecInputFile) + else: + FileList, IsSect = Section.Section.GetFileList(self, '', Sect.FileExtension) + OutputFileList.extend(FileList) + + return OutputFileList + +class OverrideAttribs: + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + + self.PciVendorId = None + self.PciClassCode = None + self.PciDeviceId = None + self.PciRevision = None + self.NeedCompress = None diff --git a/BaseTools/Source/Python/GenFds/OptionRom.py b/BaseTools/Source/Python/GenFds/OptionRom.py index 61d669de8d..b609c15bbd 100644 --- a/BaseTools/Source/Python/GenFds/OptionRom.py +++ b/BaseTools/Source/Python/GenFds/OptionRom.py @@ -1,131 +1,131 @@ -## @file
-# process OptionROM generation
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-import Common.LongFilePathOs as os
-import subprocess
-
-from . import OptRomInfStatement
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-from CommonDataClass.FdfClass import OptionRomClassObject
-from Common.Misc import SaveFileOnChange
-from Common import EdkLogger
-from Common.BuildToolError import *
-
-##
-#
-#
-class OPTIONROM (OptionRomClassObject):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self, Name = ""):
- OptionRomClassObject.__init__(self)
- self.DriverName = Name
-
- ## AddToBuffer()
- #
- # Generate Option ROM
- #
- # @param self The object pointer
- # @param Buffer The buffer generated OptROM data will be put
- # @retval string Generated OptROM file path
- #
- def AddToBuffer (self, Buffer, Flag=False) :
- if not Flag:
- GenFdsGlobalVariable.InfLogger( "\nGenerating %s Option ROM ..." %self.DriverName)
-
- EfiFileList = []
- BinFileList = []
-
- # Process Modules in FfsList
- for FfsFile in self.FfsList :
-
- if isinstance(FfsFile, OptRomInfStatement.OptRomInfStatement):
- FilePathNameList = FfsFile.GenFfs(IsMakefile=Flag)
- if len(FilePathNameList) == 0:
- EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s not produce .efi files, so NO file could be put into option ROM." % (FfsFile.InfFileName))
- if FfsFile.OverrideAttribs is None:
- EfiFileList.extend(FilePathNameList)
- else:
- FileName = os.path.basename(FilePathNameList[0])
- TmpOutputDir = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName, FfsFile.CurrentArch)
- if not os.path.exists(TmpOutputDir) :
- os.makedirs(TmpOutputDir)
- TmpOutputFile = os.path.join(TmpOutputDir, FileName+'.tmp')
-
- GenFdsGlobalVariable.GenerateOptionRom(TmpOutputFile,
- FilePathNameList,
- [],
- FfsFile.OverrideAttribs.NeedCompress,
- FfsFile.OverrideAttribs.PciClassCode,
- FfsFile.OverrideAttribs.PciRevision,
- FfsFile.OverrideAttribs.PciDeviceId,
- FfsFile.OverrideAttribs.PciVendorId,
- IsMakefile = Flag)
- BinFileList.append(TmpOutputFile)
- else:
- FilePathName = FfsFile.GenFfs(IsMakefile=Flag)
- if FfsFile.OverrideAttribs is not None:
- FileName = os.path.basename(FilePathName)
- TmpOutputDir = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName, FfsFile.CurrentArch)
- if not os.path.exists(TmpOutputDir) :
- os.makedirs(TmpOutputDir)
- TmpOutputFile = os.path.join(TmpOutputDir, FileName+'.tmp')
-
- GenFdsGlobalVariable.GenerateOptionRom(TmpOutputFile,
- [FilePathName],
- [],
- FfsFile.OverrideAttribs.NeedCompress,
- FfsFile.OverrideAttribs.PciClassCode,
- FfsFile.OverrideAttribs.PciRevision,
- FfsFile.OverrideAttribs.PciDeviceId,
- FfsFile.OverrideAttribs.PciVendorId,
- IsMakefile=Flag)
- BinFileList.append(TmpOutputFile)
- else:
- if FfsFile.FileType == 'EFI':
- EfiFileList.append(FilePathName)
- else:
- BinFileList.append(FilePathName)
-
- #
- # Call EfiRom tool
- #
- OutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName)
- OutputFile = OutputFile + '.rom'
-
- GenFdsGlobalVariable.GenerateOptionRom(
- OutputFile,
- EfiFileList,
- BinFileList,
- IsMakefile=Flag)
-
- if not Flag:
- GenFdsGlobalVariable.InfLogger( "\nGenerate %s Option ROM Successfully" %self.DriverName)
- GenFdsGlobalVariable.SharpCounter = 0
-
- return OutputFile
-
-class OverrideAttribs:
-
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
-
- self.PciVendorId = None
- self.PciClassCode = None
- self.PciDeviceId = None
- self.PciRevision = None
- self.NeedCompress = None
+## @file +# process OptionROM generation +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +import Common.LongFilePathOs as os +import subprocess + +from . import OptRomInfStatement +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import OptionRomClassObject +from Common.Misc import SaveFileOnChange +from Common import EdkLogger +from Common.BuildToolError import * + +## +# +# +class OPTIONROM (OptionRomClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self, Name = ""): + OptionRomClassObject.__init__(self) + self.DriverName = Name + + ## AddToBuffer() + # + # Generate Option ROM + # + # @param self The object pointer + # @param Buffer The buffer generated OptROM data will be put + # @retval string Generated OptROM file path + # + def AddToBuffer (self, Buffer, Flag=False) : + if not Flag: + GenFdsGlobalVariable.InfLogger( "\nGenerating %s Option ROM ..." %self.DriverName) + + EfiFileList = [] + BinFileList = [] + + # Process Modules in FfsList + for FfsFile in self.FfsList : + + if isinstance(FfsFile, OptRomInfStatement.OptRomInfStatement): + FilePathNameList = FfsFile.GenFfs(IsMakefile=Flag) + if len(FilePathNameList) == 0: + EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s not produce .efi files, so NO file could be put into option ROM." % (FfsFile.InfFileName)) + if FfsFile.OverrideAttribs is None: + EfiFileList.extend(FilePathNameList) + else: + FileName = os.path.basename(FilePathNameList[0]) + TmpOutputDir = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName, FfsFile.CurrentArch) + if not os.path.exists(TmpOutputDir) : + os.makedirs(TmpOutputDir) + TmpOutputFile = os.path.join(TmpOutputDir, FileName+'.tmp') + + GenFdsGlobalVariable.GenerateOptionRom(TmpOutputFile, + FilePathNameList, + [], + FfsFile.OverrideAttribs.NeedCompress, + FfsFile.OverrideAttribs.PciClassCode, + FfsFile.OverrideAttribs.PciRevision, + FfsFile.OverrideAttribs.PciDeviceId, + FfsFile.OverrideAttribs.PciVendorId, + IsMakefile = Flag) + BinFileList.append(TmpOutputFile) + else: + FilePathName = FfsFile.GenFfs(IsMakefile=Flag) + if FfsFile.OverrideAttribs is not None: + FileName = os.path.basename(FilePathName) + TmpOutputDir = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName, FfsFile.CurrentArch) + if not os.path.exists(TmpOutputDir) : + os.makedirs(TmpOutputDir) + TmpOutputFile = os.path.join(TmpOutputDir, FileName+'.tmp') + + GenFdsGlobalVariable.GenerateOptionRom(TmpOutputFile, + [FilePathName], + [], + FfsFile.OverrideAttribs.NeedCompress, + FfsFile.OverrideAttribs.PciClassCode, + FfsFile.OverrideAttribs.PciRevision, + FfsFile.OverrideAttribs.PciDeviceId, + FfsFile.OverrideAttribs.PciVendorId, + IsMakefile=Flag) + BinFileList.append(TmpOutputFile) + else: + if FfsFile.FileType == 'EFI': + EfiFileList.append(FilePathName) + else: + BinFileList.append(FilePathName) + + # + # Call EfiRom tool + # + OutputFile = os.path.join(GenFdsGlobalVariable.FvDir, self.DriverName) + OutputFile = OutputFile + '.rom' + + GenFdsGlobalVariable.GenerateOptionRom( + OutputFile, + EfiFileList, + BinFileList, + IsMakefile=Flag) + + if not Flag: + GenFdsGlobalVariable.InfLogger( "\nGenerate %s Option ROM Successfully" %self.DriverName) + GenFdsGlobalVariable.SharpCounter = 0 + + return OutputFile + +class OverrideAttribs: + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + + self.PciVendorId = None + self.PciClassCode = None + self.PciDeviceId = None + self.PciRevision = None + self.NeedCompress = None diff --git a/BaseTools/Source/Python/GenFds/Region.py b/BaseTools/Source/Python/GenFds/Region.py index e95cfcf965..7590909622 100644 --- a/BaseTools/Source/Python/GenFds/Region.py +++ b/BaseTools/Source/Python/GenFds/Region.py @@ -1,348 +1,348 @@ -## @file
-# process FD Region generation
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from struct import *
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-from io import BytesIO
-import string
-import Common.LongFilePathOs as os
-from stat import *
-from Common import EdkLogger
-from Common.BuildToolError import *
-from Common.LongFilePathSupport import OpenLongFilePath as open
-from Common.MultipleWorkspace import MultipleWorkspace as mws
-from Common.DataType import BINARY_FILE_TYPE_FV
-
-## generate Region
-#
-#
-class Region(object):
-
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- self.Offset = None # The begin position of the Region
- self.Size = None # The Size of the Region
- self.PcdOffset = None
- self.PcdSize = None
- self.SetVarDict = {}
- self.RegionType = None
- self.RegionDataList = []
-
- ## PadBuffer()
- #
- # Add padding bytes to the Buffer
- #
- # @param Buffer The buffer the generated region data will be put
- # in
- # @param ErasePolarity Flash erase polarity
- # @param Size Number of padding bytes requested
- #
-
- def PadBuffer(self, Buffer, ErasePolarity, Size):
- if Size > 0:
- if (ErasePolarity == '1') :
- PadByte = pack('B', 0xFF)
- else:
- PadByte = pack('B', 0)
- for i in range(0, Size):
- Buffer.write(PadByte)
-
- ## AddToBuffer()
- #
- # Add region data to the Buffer
- #
- # @param self The object pointer
- # @param Buffer The buffer generated region data will be put
- # @param BaseAddress base address of region
- # @param BlockSize block size of region
- # @param BlockNum How many blocks in region
- # @param ErasePolarity Flash erase polarity
- # @param MacroDict macro value pair
- # @retval string Generated FV file path
- #
-
- def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, ImageBinDict, MacroDict=None, Flag=False):
- Size = self.Size
- if MacroDict is None:
- MacroDict = {}
- if not Flag:
- GenFdsGlobalVariable.InfLogger('\nGenerate Region at Offset 0x%X' % self.Offset)
- GenFdsGlobalVariable.InfLogger(" Region Size = 0x%X" % Size)
- GenFdsGlobalVariable.SharpCounter = 0
- if Flag and (self.RegionType != BINARY_FILE_TYPE_FV):
- return
-
- if self.RegionType == BINARY_FILE_TYPE_FV:
- #
- # Get Fv from FvDict
- #
- self.FvAddress = int(BaseAddress, 16) + self.Offset
- FvBaseAddress = '0x%X' % self.FvAddress
- FvOffset = 0
- for RegionData in self.RegionDataList:
- FileName = None
- if RegionData.endswith(".fv"):
- RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)
- if not Flag:
- GenFdsGlobalVariable.InfLogger(' Region FV File Name = .fv : %s' % RegionData)
- if RegionData[1] != ':' :
- RegionData = mws.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)
- if not os.path.exists(RegionData):
- EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)
-
- FileName = RegionData
- elif RegionData.upper() + 'fv' in ImageBinDict:
- if not Flag:
- GenFdsGlobalVariable.InfLogger(' Region Name = FV')
- FileName = ImageBinDict[RegionData.upper() + 'fv']
- else:
- #
- # Generate FvImage.
- #
- FvObj = None
- if RegionData.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict:
- FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[RegionData.upper()]
-
- if FvObj is not None :
- if not Flag:
- GenFdsGlobalVariable.InfLogger(' Region Name = FV')
- #
- # Call GenFv tool
- #
- self.BlockInfoOfRegion(BlockSizeList, FvObj)
- self.FvAddress = self.FvAddress + FvOffset
- FvAlignValue = GenFdsGlobalVariable.GetAlignment(FvObj.FvAlignment)
- if self.FvAddress % FvAlignValue != 0:
- EdkLogger.error("GenFds", GENFDS_ERROR,
- "FV (%s) is NOT %s Aligned!" % (FvObj.UiFvName, FvObj.FvAlignment))
- FvBuffer = BytesIO()
- FvBaseAddress = '0x%X' % self.FvAddress
- BlockSize = None
- BlockNum = None
- FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, Flag=Flag)
- if Flag:
- continue
-
- FvBufferLen = len(FvBuffer.getvalue())
- if FvBufferLen > Size:
- FvBuffer.close()
- EdkLogger.error("GenFds", GENFDS_ERROR,
- "Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData, Size))
- #
- # Put the generated image into FD buffer.
- #
- Buffer.write(FvBuffer.getvalue())
- FvBuffer.close()
- FvOffset = FvOffset + FvBufferLen
- Size = Size - FvBufferLen
- continue
- else:
- EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (RegionData))
- #
- # Add the exist Fv image into FD buffer
- #
- if not Flag:
- if FileName is not None:
- FileLength = os.stat(FileName)[ST_SIZE]
- if FileLength > Size:
- EdkLogger.error("GenFds", GENFDS_ERROR,
- "Size of FV File (%s) is larger than Region Size 0x%X specified." \
- % (RegionData, Size))
- BinFile = open(FileName, 'rb')
- Buffer.write(BinFile.read())
- BinFile.close()
- Size = Size - FileLength
- #
- # Pad the left buffer
- #
- if not Flag:
- self.PadBuffer(Buffer, ErasePolarity, Size)
-
- if self.RegionType == 'CAPSULE':
- #
- # Get Capsule from Capsule Dict
- #
- for RegionData in self.RegionDataList:
- if RegionData.endswith(".cap"):
- RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)
- GenFdsGlobalVariable.InfLogger(' Region CAPSULE Image Name = .cap : %s' % RegionData)
- if RegionData[1] != ':' :
- RegionData = mws.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)
- if not os.path.exists(RegionData):
- EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)
-
- FileName = RegionData
- elif RegionData.upper() + 'cap' in ImageBinDict:
- GenFdsGlobalVariable.InfLogger(' Region Name = CAPSULE')
- FileName = ImageBinDict[RegionData.upper() + 'cap']
- else:
- #
- # Generate Capsule image and Put it into FD buffer
- #
- CapsuleObj = None
- if RegionData.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict:
- CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[RegionData.upper()]
-
- if CapsuleObj is not None :
- CapsuleObj.CapsuleName = RegionData.upper()
- GenFdsGlobalVariable.InfLogger(' Region Name = CAPSULE')
- #
- # Call GenFv tool to generate Capsule Image
- #
- FileName = CapsuleObj.GenCapsule()
- CapsuleObj.CapsuleName = None
- else:
- EdkLogger.error("GenFds", GENFDS_ERROR, "Capsule (%s) is NOT described in FDF file!" % (RegionData))
-
- #
- # Add the capsule image into FD buffer
- #
- FileLength = os.stat(FileName)[ST_SIZE]
- if FileLength > Size:
- EdkLogger.error("GenFds", GENFDS_ERROR,
- "Size 0x%X of Capsule File (%s) is larger than Region Size 0x%X specified." \
- % (FileLength, RegionData, Size))
- BinFile = open(FileName, 'rb')
- Buffer.write(BinFile.read())
- BinFile.close()
- Size = Size - FileLength
- #
- # Pad the left buffer
- #
- self.PadBuffer(Buffer, ErasePolarity, Size)
-
- if self.RegionType in ('FILE', 'INF'):
- for RegionData in self.RegionDataList:
- if self.RegionType == 'INF':
- RegionData.__InfParse__(None)
- if len(RegionData.BinFileList) != 1:
- EdkLogger.error('GenFds', GENFDS_ERROR, 'INF in FD region can only contain one binary: %s' % RegionData)
- File = RegionData.BinFileList[0]
- RegionData = RegionData.PatchEfiFile(File.Path, File.Type)
- else:
- RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)
- if RegionData[1] != ':' :
- RegionData = mws.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)
- if not os.path.exists(RegionData):
- EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)
- #
- # Add the file image into FD buffer
- #
- FileLength = os.stat(RegionData)[ST_SIZE]
- if FileLength > Size:
- EdkLogger.error("GenFds", GENFDS_ERROR,
- "Size of File (%s) is larger than Region Size 0x%X specified." \
- % (RegionData, Size))
- GenFdsGlobalVariable.InfLogger(' Region File Name = %s' % RegionData)
- BinFile = open(RegionData, 'rb')
- Buffer.write(BinFile.read())
- BinFile.close()
- Size = Size - FileLength
- #
- # Pad the left buffer
- #
- self.PadBuffer(Buffer, ErasePolarity, Size)
-
- if self.RegionType == 'DATA' :
- GenFdsGlobalVariable.InfLogger(' Region Name = DATA')
- DataSize = 0
- for RegionData in self.RegionDataList:
- Data = RegionData.split(',')
- DataSize = DataSize + len(Data)
- if DataSize > Size:
- EdkLogger.error("GenFds", GENFDS_ERROR, "Size of DATA is larger than Region Size ")
- else:
- for item in Data :
- Buffer.write(pack('B', int(item, 16)))
- Size = Size - DataSize
- #
- # Pad the left buffer
- #
- self.PadBuffer(Buffer, ErasePolarity, Size)
-
- if self.RegionType is None:
- GenFdsGlobalVariable.InfLogger(' Region Name = None')
- self.PadBuffer(Buffer, ErasePolarity, Size)
-
- ## BlockSizeOfRegion()
- #
- # @param BlockSizeList List of block information
- # @param FvObj The object for FV
- #
- def BlockInfoOfRegion(self, BlockSizeList, FvObj):
- Start = 0
- End = 0
- RemindingSize = self.Size
- ExpectedList = []
- for (BlockSize, BlockNum, pcd) in BlockSizeList:
- End = Start + BlockSize * BlockNum
- # region not started yet
- if self.Offset >= End:
- Start = End
- continue
- # region located in current blocks
- else:
- # region ended within current blocks
- if self.Offset + self.Size <= End:
- ExpectedList.append((BlockSize, (RemindingSize + BlockSize - 1) // BlockSize))
- break
- # region not ended yet
- else:
- # region not started in middle of current blocks
- if self.Offset <= Start:
- UsedBlockNum = BlockNum
- # region started in middle of current blocks
- else:
- UsedBlockNum = (End - self.Offset) // BlockSize
- Start = End
- ExpectedList.append((BlockSize, UsedBlockNum))
- RemindingSize -= BlockSize * UsedBlockNum
-
- if FvObj.BlockSizeList == []:
- FvObj.BlockSizeList = ExpectedList
- else:
- # first check whether FvObj.BlockSizeList items have only "BlockSize" or "NumBlocks",
- # if so, use ExpectedList
- for Item in FvObj.BlockSizeList:
- if Item[0] is None or Item[1] is None:
- FvObj.BlockSizeList = ExpectedList
- break
- # make sure region size is no smaller than the summed block size in FV
- Sum = 0
- for Item in FvObj.BlockSizeList:
- Sum += Item[0] * Item[1]
- if self.Size < Sum:
- EdkLogger.error("GenFds", GENFDS_ERROR, "Total Size of FV %s 0x%x is larger than Region Size 0x%x "
- % (FvObj.UiFvName, Sum, self.Size))
- # check whether the BlockStatements in FV section is appropriate
- ExpectedListData = ''
- for Item in ExpectedList:
- ExpectedListData += "BlockSize = 0x%x\n\tNumBlocks = 0x%x\n\t" % Item
- Index = 0
- for Item in FvObj.BlockSizeList:
- if Item[0] != ExpectedList[Index][0]:
- EdkLogger.error("GenFds", GENFDS_ERROR, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement"
- % FvObj.UiFvName, ExtraData=ExpectedListData)
- elif Item[1] != ExpectedList[Index][1]:
- if (Item[1] < ExpectedList[Index][1]) and (Index == len(FvObj.BlockSizeList) - 1):
- break;
- else:
- EdkLogger.error("GenFds", GENFDS_ERROR, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement"
- % FvObj.UiFvName, ExtraData=ExpectedListData)
- else:
- Index += 1
-
-
-
+## @file +# process FD Region generation +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from struct import * +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from io import BytesIO +import string +import Common.LongFilePathOs as os +from stat import * +from Common import EdkLogger +from Common.BuildToolError import * +from Common.LongFilePathSupport import OpenLongFilePath as open +from Common.MultipleWorkspace import MultipleWorkspace as mws +from Common.DataType import BINARY_FILE_TYPE_FV + +## generate Region +# +# +class Region(object): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + self.Offset = None # The begin position of the Region + self.Size = None # The Size of the Region + self.PcdOffset = None + self.PcdSize = None + self.SetVarDict = {} + self.RegionType = None + self.RegionDataList = [] + + ## PadBuffer() + # + # Add padding bytes to the Buffer + # + # @param Buffer The buffer the generated region data will be put + # in + # @param ErasePolarity Flash erase polarity + # @param Size Number of padding bytes requested + # + + def PadBuffer(self, Buffer, ErasePolarity, Size): + if Size > 0: + if (ErasePolarity == '1') : + PadByte = pack('B', 0xFF) + else: + PadByte = pack('B', 0) + for i in range(0, Size): + Buffer.write(PadByte) + + ## AddToBuffer() + # + # Add region data to the Buffer + # + # @param self The object pointer + # @param Buffer The buffer generated region data will be put + # @param BaseAddress base address of region + # @param BlockSize block size of region + # @param BlockNum How many blocks in region + # @param ErasePolarity Flash erase polarity + # @param MacroDict macro value pair + # @retval string Generated FV file path + # + + def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, ImageBinDict, MacroDict=None, Flag=False): + Size = self.Size + if MacroDict is None: + MacroDict = {} + if not Flag: + GenFdsGlobalVariable.InfLogger('\nGenerate Region at Offset 0x%X' % self.Offset) + GenFdsGlobalVariable.InfLogger(" Region Size = 0x%X" % Size) + GenFdsGlobalVariable.SharpCounter = 0 + if Flag and (self.RegionType != BINARY_FILE_TYPE_FV): + return + + if self.RegionType == BINARY_FILE_TYPE_FV: + # + # Get Fv from FvDict + # + self.FvAddress = int(BaseAddress, 16) + self.Offset + FvBaseAddress = '0x%X' % self.FvAddress + FvOffset = 0 + for RegionData in self.RegionDataList: + FileName = None + if RegionData.endswith(".fv"): + RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict) + if not Flag: + GenFdsGlobalVariable.InfLogger(' Region FV File Name = .fv : %s' % RegionData) + if RegionData[1] != ':' : + RegionData = mws.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData) + if not os.path.exists(RegionData): + EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData) + + FileName = RegionData + elif RegionData.upper() + 'fv' in ImageBinDict: + if not Flag: + GenFdsGlobalVariable.InfLogger(' Region Name = FV') + FileName = ImageBinDict[RegionData.upper() + 'fv'] + else: + # + # Generate FvImage. + # + FvObj = None + if RegionData.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict: + FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[RegionData.upper()] + + if FvObj is not None : + if not Flag: + GenFdsGlobalVariable.InfLogger(' Region Name = FV') + # + # Call GenFv tool + # + self.BlockInfoOfRegion(BlockSizeList, FvObj) + self.FvAddress = self.FvAddress + FvOffset + FvAlignValue = GenFdsGlobalVariable.GetAlignment(FvObj.FvAlignment) + if self.FvAddress % FvAlignValue != 0: + EdkLogger.error("GenFds", GENFDS_ERROR, + "FV (%s) is NOT %s Aligned!" % (FvObj.UiFvName, FvObj.FvAlignment)) + FvBuffer = BytesIO() + FvBaseAddress = '0x%X' % self.FvAddress + BlockSize = None + BlockNum = None + FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, Flag=Flag) + if Flag: + continue + + FvBufferLen = len(FvBuffer.getvalue()) + if FvBufferLen > Size: + FvBuffer.close() + EdkLogger.error("GenFds", GENFDS_ERROR, + "Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData, Size)) + # + # Put the generated image into FD buffer. + # + Buffer.write(FvBuffer.getvalue()) + FvBuffer.close() + FvOffset = FvOffset + FvBufferLen + Size = Size - FvBufferLen + continue + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (RegionData)) + # + # Add the exist Fv image into FD buffer + # + if not Flag: + if FileName is not None: + FileLength = os.stat(FileName)[ST_SIZE] + if FileLength > Size: + EdkLogger.error("GenFds", GENFDS_ERROR, + "Size of FV File (%s) is larger than Region Size 0x%X specified." \ + % (RegionData, Size)) + BinFile = open(FileName, 'rb') + Buffer.write(BinFile.read()) + BinFile.close() + Size = Size - FileLength + # + # Pad the left buffer + # + if not Flag: + self.PadBuffer(Buffer, ErasePolarity, Size) + + if self.RegionType == 'CAPSULE': + # + # Get Capsule from Capsule Dict + # + for RegionData in self.RegionDataList: + if RegionData.endswith(".cap"): + RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict) + GenFdsGlobalVariable.InfLogger(' Region CAPSULE Image Name = .cap : %s' % RegionData) + if RegionData[1] != ':' : + RegionData = mws.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData) + if not os.path.exists(RegionData): + EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData) + + FileName = RegionData + elif RegionData.upper() + 'cap' in ImageBinDict: + GenFdsGlobalVariable.InfLogger(' Region Name = CAPSULE') + FileName = ImageBinDict[RegionData.upper() + 'cap'] + else: + # + # Generate Capsule image and Put it into FD buffer + # + CapsuleObj = None + if RegionData.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict: + CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[RegionData.upper()] + + if CapsuleObj is not None : + CapsuleObj.CapsuleName = RegionData.upper() + GenFdsGlobalVariable.InfLogger(' Region Name = CAPSULE') + # + # Call GenFv tool to generate Capsule Image + # + FileName = CapsuleObj.GenCapsule() + CapsuleObj.CapsuleName = None + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "Capsule (%s) is NOT described in FDF file!" % (RegionData)) + + # + # Add the capsule image into FD buffer + # + FileLength = os.stat(FileName)[ST_SIZE] + if FileLength > Size: + EdkLogger.error("GenFds", GENFDS_ERROR, + "Size 0x%X of Capsule File (%s) is larger than Region Size 0x%X specified." \ + % (FileLength, RegionData, Size)) + BinFile = open(FileName, 'rb') + Buffer.write(BinFile.read()) + BinFile.close() + Size = Size - FileLength + # + # Pad the left buffer + # + self.PadBuffer(Buffer, ErasePolarity, Size) + + if self.RegionType in ('FILE', 'INF'): + for RegionData in self.RegionDataList: + if self.RegionType == 'INF': + RegionData.__InfParse__(None) + if len(RegionData.BinFileList) != 1: + EdkLogger.error('GenFds', GENFDS_ERROR, 'INF in FD region can only contain one binary: %s' % RegionData) + File = RegionData.BinFileList[0] + RegionData = RegionData.PatchEfiFile(File.Path, File.Type) + else: + RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict) + if RegionData[1] != ':' : + RegionData = mws.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData) + if not os.path.exists(RegionData): + EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData) + # + # Add the file image into FD buffer + # + FileLength = os.stat(RegionData)[ST_SIZE] + if FileLength > Size: + EdkLogger.error("GenFds", GENFDS_ERROR, + "Size of File (%s) is larger than Region Size 0x%X specified." \ + % (RegionData, Size)) + GenFdsGlobalVariable.InfLogger(' Region File Name = %s' % RegionData) + BinFile = open(RegionData, 'rb') + Buffer.write(BinFile.read()) + BinFile.close() + Size = Size - FileLength + # + # Pad the left buffer + # + self.PadBuffer(Buffer, ErasePolarity, Size) + + if self.RegionType == 'DATA' : + GenFdsGlobalVariable.InfLogger(' Region Name = DATA') + DataSize = 0 + for RegionData in self.RegionDataList: + Data = RegionData.split(',') + DataSize = DataSize + len(Data) + if DataSize > Size: + EdkLogger.error("GenFds", GENFDS_ERROR, "Size of DATA is larger than Region Size ") + else: + for item in Data : + Buffer.write(pack('B', int(item, 16))) + Size = Size - DataSize + # + # Pad the left buffer + # + self.PadBuffer(Buffer, ErasePolarity, Size) + + if self.RegionType is None: + GenFdsGlobalVariable.InfLogger(' Region Name = None') + self.PadBuffer(Buffer, ErasePolarity, Size) + + ## BlockSizeOfRegion() + # + # @param BlockSizeList List of block information + # @param FvObj The object for FV + # + def BlockInfoOfRegion(self, BlockSizeList, FvObj): + Start = 0 + End = 0 + RemindingSize = self.Size + ExpectedList = [] + for (BlockSize, BlockNum, pcd) in BlockSizeList: + End = Start + BlockSize * BlockNum + # region not started yet + if self.Offset >= End: + Start = End + continue + # region located in current blocks + else: + # region ended within current blocks + if self.Offset + self.Size <= End: + ExpectedList.append((BlockSize, (RemindingSize + BlockSize - 1) // BlockSize)) + break + # region not ended yet + else: + # region not started in middle of current blocks + if self.Offset <= Start: + UsedBlockNum = BlockNum + # region started in middle of current blocks + else: + UsedBlockNum = (End - self.Offset) // BlockSize + Start = End + ExpectedList.append((BlockSize, UsedBlockNum)) + RemindingSize -= BlockSize * UsedBlockNum + + if FvObj.BlockSizeList == []: + FvObj.BlockSizeList = ExpectedList + else: + # first check whether FvObj.BlockSizeList items have only "BlockSize" or "NumBlocks", + # if so, use ExpectedList + for Item in FvObj.BlockSizeList: + if Item[0] is None or Item[1] is None: + FvObj.BlockSizeList = ExpectedList + break + # make sure region size is no smaller than the summed block size in FV + Sum = 0 + for Item in FvObj.BlockSizeList: + Sum += Item[0] * Item[1] + if self.Size < Sum: + EdkLogger.error("GenFds", GENFDS_ERROR, "Total Size of FV %s 0x%x is larger than Region Size 0x%x " + % (FvObj.UiFvName, Sum, self.Size)) + # check whether the BlockStatements in FV section is appropriate + ExpectedListData = '' + for Item in ExpectedList: + ExpectedListData += "BlockSize = 0x%x\n\tNumBlocks = 0x%x\n\t" % Item + Index = 0 + for Item in FvObj.BlockSizeList: + if Item[0] != ExpectedList[Index][0]: + EdkLogger.error("GenFds", GENFDS_ERROR, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement" + % FvObj.UiFvName, ExtraData=ExpectedListData) + elif Item[1] != ExpectedList[Index][1]: + if (Item[1] < ExpectedList[Index][1]) and (Index == len(FvObj.BlockSizeList) - 1): + break; + else: + EdkLogger.error("GenFds", GENFDS_ERROR, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement" + % FvObj.UiFvName, ExtraData=ExpectedListData) + else: + Index += 1 + + + diff --git a/BaseTools/Source/Python/GenFds/Rule.py b/BaseTools/Source/Python/GenFds/Rule.py index 6561c0efd8..b14114fc0f 100644 --- a/BaseTools/Source/Python/GenFds/Rule.py +++ b/BaseTools/Source/Python/GenFds/Rule.py @@ -1,23 +1,23 @@ -## @file
-# Rule object for generating FFS
-#
-# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from CommonDataClass.FdfClass import RuleClassObject
-
-## Rule base class
-#
-#
-class Rule(RuleClassObject):
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- RuleClassObject.__init__(self)
+## @file +# Rule object for generating FFS +# +# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from CommonDataClass.FdfClass import RuleClassObject + +## Rule base class +# +# +class Rule(RuleClassObject): + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + RuleClassObject.__init__(self) diff --git a/BaseTools/Source/Python/GenFds/RuleComplexFile.py b/BaseTools/Source/Python/GenFds/RuleComplexFile.py index 198f4f0a9a..35af9bc137 100644 --- a/BaseTools/Source/Python/GenFds/RuleComplexFile.py +++ b/BaseTools/Source/Python/GenFds/RuleComplexFile.py @@ -1,25 +1,25 @@ -## @file
-# Complex Rule object for generating FFS
-#
-# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from . import Rule
-from CommonDataClass.FdfClass import RuleComplexFileClassObject
-
-## complex rule
-#
-#
-class RuleComplexFile(RuleComplexFileClassObject) :
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- RuleComplexFileClassObject.__init__(self)
+## @file +# Complex Rule object for generating FFS +# +# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from . import Rule +from CommonDataClass.FdfClass import RuleComplexFileClassObject + +## complex rule +# +# +class RuleComplexFile(RuleComplexFileClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + RuleComplexFileClassObject.__init__(self) diff --git a/BaseTools/Source/Python/GenFds/RuleSimpleFile.py b/BaseTools/Source/Python/GenFds/RuleSimpleFile.py index 772c768cc9..4f4d75f0bd 100644 --- a/BaseTools/Source/Python/GenFds/RuleSimpleFile.py +++ b/BaseTools/Source/Python/GenFds/RuleSimpleFile.py @@ -1,25 +1,25 @@ -## @file
-# Simple Rule object for generating FFS
-#
-# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from . import Rule
-from CommonDataClass.FdfClass import RuleSimpleFileClassObject
-
-## simple rule
-#
-#
-class RuleSimpleFile (RuleSimpleFileClassObject) :
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- RuleSimpleFileClassObject.__init__(self)
+## @file +# Simple Rule object for generating FFS +# +# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from . import Rule +from CommonDataClass.FdfClass import RuleSimpleFileClassObject + +## simple rule +# +# +class RuleSimpleFile (RuleSimpleFileClassObject) : + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + RuleSimpleFileClassObject.__init__(self) diff --git a/BaseTools/Source/Python/GenFds/Section.py b/BaseTools/Source/Python/GenFds/Section.py index 859db7230a..01e92c0ba7 100644 --- a/BaseTools/Source/Python/GenFds/Section.py +++ b/BaseTools/Source/Python/GenFds/Section.py @@ -1,154 +1,154 @@ -## @file
-# section base class
-#
-# Copyright (c) 2007-2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from CommonDataClass.FdfClass import SectionClassObject
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-import Common.LongFilePathOs as os, glob
-from Common import EdkLogger
-from Common.BuildToolError import *
-from Common.DataType import *
-
-## section base class
-#
-#
-class Section (SectionClassObject):
- SectionType = {
- 'RAW' : 'EFI_SECTION_RAW',
- 'FREEFORM' : 'EFI_SECTION_FREEFORM_SUBTYPE_GUID',
- BINARY_FILE_TYPE_PE32 : 'EFI_SECTION_PE32',
- BINARY_FILE_TYPE_PIC : 'EFI_SECTION_PIC',
- BINARY_FILE_TYPE_TE : 'EFI_SECTION_TE',
- 'FV_IMAGE' : 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE',
- 'COMPAT16' : 'EFI_SECTION_COMPATIBILITY16',
- BINARY_FILE_TYPE_DXE_DEPEX : 'EFI_SECTION_DXE_DEPEX',
- BINARY_FILE_TYPE_PEI_DEPEX : 'EFI_SECTION_PEI_DEPEX',
- 'GUIDED' : 'EFI_SECTION_GUID_DEFINED',
- 'COMPRESS' : 'EFI_SECTION_COMPRESSION',
- BINARY_FILE_TYPE_UI : 'EFI_SECTION_USER_INTERFACE',
- BINARY_FILE_TYPE_SMM_DEPEX : 'EFI_SECTION_SMM_DEPEX'
- }
-
- BinFileType = {
- BINARY_FILE_TYPE_GUID : '.guid',
- 'ACPI' : '.acpi',
- 'ASL' : '.asl' ,
- BINARY_FILE_TYPE_UEFI_APP : '.app',
- BINARY_FILE_TYPE_LIB : '.lib',
- BINARY_FILE_TYPE_PE32 : '.pe32',
- BINARY_FILE_TYPE_PIC : '.pic',
- BINARY_FILE_TYPE_PEI_DEPEX : '.depex',
- 'SEC_PEI_DEPEX' : '.depex',
- BINARY_FILE_TYPE_TE : '.te',
- BINARY_FILE_TYPE_UNI_VER : '.ver',
- BINARY_FILE_TYPE_VER : '.ver',
- BINARY_FILE_TYPE_UNI_UI : '.ui',
- BINARY_FILE_TYPE_UI : '.ui',
- BINARY_FILE_TYPE_BIN : '.bin',
- 'RAW' : '.raw',
- 'COMPAT16' : '.comp16',
- BINARY_FILE_TYPE_FV : '.fv'
- }
-
- SectFileType = {
- 'SEC_GUID' : '.sec' ,
- 'SEC_PE32' : '.sec' ,
- 'SEC_PIC' : '.sec',
- 'SEC_TE' : '.sec',
- 'SEC_VER' : '.sec',
- 'SEC_UI' : '.sec',
- 'SEC_COMPAT16' : '.sec',
- 'SEC_BIN' : '.sec'
- }
-
- ToolGuid = {
- '0xa31280ad-0x481e-0x41b6-0x95e8-0x127f-0x4c984779' : 'TianoCompress',
- '0xee4e5898-0x3914-0x4259-0x9d6e-0xdc7b-0xd79403cf' : 'LzmaCompress'
- }
-
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- SectionClassObject.__init__(self)
-
- ## GenSection() method
- #
- # virtual function
- #
- # @param self The object pointer
- # @param OutputPath Where to place output file
- # @param ModuleName Which module this section belongs to
- # @param SecNum Index of section
- # @param KeyStringList Filter for inputs of section generation
- # @param FfsInf FfsInfStatement object that contains this section data
- # @param Dict dictionary contains macro and its value
- #
- def GenSection(self, OutputPath, GuidName, SecNum, keyStringList, FfsInf = None, Dict = None):
- pass
-
- ## GetFileList() method
- #
- # Generate compressed section
- #
- # @param self The object pointer
- # @param FfsInf FfsInfStatement object that contains file list
- # @param FileType File type to get
- # @param FileExtension File extension to get
- # @param Dict dictionary contains macro and its value
- # @retval tuple (File list, boolean)
- #
- def GetFileList(FfsInf, FileType, FileExtension, Dict = None, IsMakefile=False, SectionType=None):
- IsSect = FileType in Section.SectFileType
-
- if FileExtension is not None:
- Suffix = FileExtension
- elif IsSect :
- Suffix = Section.SectionType.get(FileType)
- else:
- Suffix = Section.BinFileType.get(FileType)
- if FfsInf is None:
- EdkLogger.error("GenFds", GENFDS_ERROR, 'Inf File does not exist!')
-
- FileList = []
- if FileType is not None:
- for File in FfsInf.BinFileList:
- if File.Arch == TAB_ARCH_COMMON or FfsInf.CurrentArch == File.Arch:
- if File.Type == FileType or (int(FfsInf.PiSpecVersion, 16) >= 0x0001000A \
- and FileType == 'DXE_DPEX' and File.Type == BINARY_FILE_TYPE_SMM_DEPEX) \
- or (FileType == BINARY_FILE_TYPE_TE and File.Type == BINARY_FILE_TYPE_PE32):
- if TAB_STAR in FfsInf.TargetOverrideList or File.Target == TAB_STAR or File.Target in FfsInf.TargetOverrideList or FfsInf.TargetOverrideList == []:
- FileList.append(FfsInf.PatchEfiFile(File.Path, File.Type))
- else:
- GenFdsGlobalVariable.InfLogger ("\nBuild Target \'%s\' of File %s is not in the Scope of %s specified by INF %s in FDF" %(File.Target, File.File, FfsInf.TargetOverrideList, FfsInf.InfFileName))
- else:
- GenFdsGlobalVariable.VerboseLogger ("\nFile Type \'%s\' of File %s in %s is not same with file type \'%s\' from Rule in FDF" %(File.Type, File.File, FfsInf.InfFileName, FileType))
- else:
- GenFdsGlobalVariable.InfLogger ("\nCurrent ARCH \'%s\' of File %s is not in the Support Arch Scope of %s specified by INF %s in FDF" %(FfsInf.CurrentArch, File.File, File.Arch, FfsInf.InfFileName))
-
- elif FileType is None and SectionType == BINARY_FILE_TYPE_RAW:
- for File in FfsInf.BinFileList:
- if File.Ext == Suffix:
- FileList.append(File.Path)
-
- if (not IsMakefile and Suffix is not None and os.path.exists(FfsInf.EfiOutputPath)) or (IsMakefile and Suffix is not None):
- if not FileList:
- SuffixMap = FfsInf.GetFinalTargetSuffixMap()
- if Suffix in SuffixMap:
- FileList.extend(SuffixMap[Suffix])
-
- #Process the file lists is alphabetical for a same section type
- if len (FileList) > 1:
- FileList.sort()
-
- return FileList, IsSect
- GetFileList = staticmethod(GetFileList)
+## @file +# section base class +# +# Copyright (c) 2007-2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from CommonDataClass.FdfClass import SectionClassObject +from .GenFdsGlobalVariable import GenFdsGlobalVariable +import Common.LongFilePathOs as os, glob +from Common import EdkLogger +from Common.BuildToolError import * +from Common.DataType import * + +## section base class +# +# +class Section (SectionClassObject): + SectionType = { + 'RAW' : 'EFI_SECTION_RAW', + 'FREEFORM' : 'EFI_SECTION_FREEFORM_SUBTYPE_GUID', + BINARY_FILE_TYPE_PE32 : 'EFI_SECTION_PE32', + BINARY_FILE_TYPE_PIC : 'EFI_SECTION_PIC', + BINARY_FILE_TYPE_TE : 'EFI_SECTION_TE', + 'FV_IMAGE' : 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', + 'COMPAT16' : 'EFI_SECTION_COMPATIBILITY16', + BINARY_FILE_TYPE_DXE_DEPEX : 'EFI_SECTION_DXE_DEPEX', + BINARY_FILE_TYPE_PEI_DEPEX : 'EFI_SECTION_PEI_DEPEX', + 'GUIDED' : 'EFI_SECTION_GUID_DEFINED', + 'COMPRESS' : 'EFI_SECTION_COMPRESSION', + BINARY_FILE_TYPE_UI : 'EFI_SECTION_USER_INTERFACE', + BINARY_FILE_TYPE_SMM_DEPEX : 'EFI_SECTION_SMM_DEPEX' + } + + BinFileType = { + BINARY_FILE_TYPE_GUID : '.guid', + 'ACPI' : '.acpi', + 'ASL' : '.asl' , + BINARY_FILE_TYPE_UEFI_APP : '.app', + BINARY_FILE_TYPE_LIB : '.lib', + BINARY_FILE_TYPE_PE32 : '.pe32', + BINARY_FILE_TYPE_PIC : '.pic', + BINARY_FILE_TYPE_PEI_DEPEX : '.depex', + 'SEC_PEI_DEPEX' : '.depex', + BINARY_FILE_TYPE_TE : '.te', + BINARY_FILE_TYPE_UNI_VER : '.ver', + BINARY_FILE_TYPE_VER : '.ver', + BINARY_FILE_TYPE_UNI_UI : '.ui', + BINARY_FILE_TYPE_UI : '.ui', + BINARY_FILE_TYPE_BIN : '.bin', + 'RAW' : '.raw', + 'COMPAT16' : '.comp16', + BINARY_FILE_TYPE_FV : '.fv' + } + + SectFileType = { + 'SEC_GUID' : '.sec' , + 'SEC_PE32' : '.sec' , + 'SEC_PIC' : '.sec', + 'SEC_TE' : '.sec', + 'SEC_VER' : '.sec', + 'SEC_UI' : '.sec', + 'SEC_COMPAT16' : '.sec', + 'SEC_BIN' : '.sec' + } + + ToolGuid = { + '0xa31280ad-0x481e-0x41b6-0x95e8-0x127f-0x4c984779' : 'TianoCompress', + '0xee4e5898-0x3914-0x4259-0x9d6e-0xdc7b-0xd79403cf' : 'LzmaCompress' + } + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + SectionClassObject.__init__(self) + + ## GenSection() method + # + # virtual function + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # + def GenSection(self, OutputPath, GuidName, SecNum, keyStringList, FfsInf = None, Dict = None): + pass + + ## GetFileList() method + # + # Generate compressed section + # + # @param self The object pointer + # @param FfsInf FfsInfStatement object that contains file list + # @param FileType File type to get + # @param FileExtension File extension to get + # @param Dict dictionary contains macro and its value + # @retval tuple (File list, boolean) + # + def GetFileList(FfsInf, FileType, FileExtension, Dict = None, IsMakefile=False, SectionType=None): + IsSect = FileType in Section.SectFileType + + if FileExtension is not None: + Suffix = FileExtension + elif IsSect : + Suffix = Section.SectionType.get(FileType) + else: + Suffix = Section.BinFileType.get(FileType) + if FfsInf is None: + EdkLogger.error("GenFds", GENFDS_ERROR, 'Inf File does not exist!') + + FileList = [] + if FileType is not None: + for File in FfsInf.BinFileList: + if File.Arch == TAB_ARCH_COMMON or FfsInf.CurrentArch == File.Arch: + if File.Type == FileType or (int(FfsInf.PiSpecVersion, 16) >= 0x0001000A \ + and FileType == 'DXE_DPEX' and File.Type == BINARY_FILE_TYPE_SMM_DEPEX) \ + or (FileType == BINARY_FILE_TYPE_TE and File.Type == BINARY_FILE_TYPE_PE32): + if TAB_STAR in FfsInf.TargetOverrideList or File.Target == TAB_STAR or File.Target in FfsInf.TargetOverrideList or FfsInf.TargetOverrideList == []: + FileList.append(FfsInf.PatchEfiFile(File.Path, File.Type)) + else: + GenFdsGlobalVariable.InfLogger ("\nBuild Target \'%s\' of File %s is not in the Scope of %s specified by INF %s in FDF" %(File.Target, File.File, FfsInf.TargetOverrideList, FfsInf.InfFileName)) + else: + GenFdsGlobalVariable.VerboseLogger ("\nFile Type \'%s\' of File %s in %s is not same with file type \'%s\' from Rule in FDF" %(File.Type, File.File, FfsInf.InfFileName, FileType)) + else: + GenFdsGlobalVariable.InfLogger ("\nCurrent ARCH \'%s\' of File %s is not in the Support Arch Scope of %s specified by INF %s in FDF" %(FfsInf.CurrentArch, File.File, File.Arch, FfsInf.InfFileName)) + + elif FileType is None and SectionType == BINARY_FILE_TYPE_RAW: + for File in FfsInf.BinFileList: + if File.Ext == Suffix: + FileList.append(File.Path) + + if (not IsMakefile and Suffix is not None and os.path.exists(FfsInf.EfiOutputPath)) or (IsMakefile and Suffix is not None): + if not FileList: + SuffixMap = FfsInf.GetFinalTargetSuffixMap() + if Suffix in SuffixMap: + FileList.extend(SuffixMap[Suffix]) + + #Process the file lists is alphabetical for a same section type + if len (FileList) > 1: + FileList.sort() + + return FileList, IsSect + GetFileList = staticmethod(GetFileList) diff --git a/BaseTools/Source/Python/GenFds/SubTypeGuidSection.py b/BaseTools/Source/Python/GenFds/SubTypeGuidSection.py index d522380117..56ef75a79e 100644 --- a/BaseTools/Source/Python/GenFds/SubTypeGuidSection.py +++ b/BaseTools/Source/Python/GenFds/SubTypeGuidSection.py @@ -1,76 +1,76 @@ -## @file
-# process Subtype GUIDed section generation
-#
-# Copyright (c) 2022, Konstantin Aladyshev <aladyshev22@gmail.com>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from . import Section
-import subprocess
-from .Ffs import SectionSuffix
-import Common.LongFilePathOs as os
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-from .GenFdsGlobalVariable import FindExtendTool
-from CommonDataClass.FdfClass import SubTypeGuidSectionClassObject
-import sys
-from Common import EdkLogger
-from Common.BuildToolError import *
-from .FvImageSection import FvImageSection
-from Common.LongFilePathSupport import OpenLongFilePath as open
-from Common.DataType import *
-
-## generate SubType GUIDed section
-#
-#
-class SubTypeGuidSection(SubTypeGuidSectionClassObject) :
-
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- SubTypeGuidSectionClassObject.__init__(self)
-
- ## GenSection() method
- #
- # Generate GUIDed section
- #
- # @param self The object pointer
- # @param OutputPath Where to place output file
- # @param ModuleName Which module this section belongs to
- # @param SecNum Index of section
- # @param KeyStringList Filter for inputs of section generation
- # @param FfsInf FfsInfStatement object that contains this section data
- # @param Dict dictionary contains macro and its value
- # @retval tuple (Generated file name, section alignment)
- #
- def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict=None, IsMakefile=False):
- #
- # Generate all section
- #
- self.KeyStringList = KeyStringList
- self.CurrentArchList = GenFdsGlobalVariable.ArchList
- if FfsInf is not None:
- self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
- self.SubTypeGuid = FfsInf.__ExtendMacro__(self.SubTypeGuid)
- self.SectionType = FfsInf.__ExtendMacro__(self.SectionType)
- self.CurrentArchList = [FfsInf.CurrentArch]
-
- if Dict is None:
- Dict = {}
-
- self.SectFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.SectFileName)
- self.SectFileName = GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict)
-
- OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + SectionSuffix.get("SUBTYPE_GUID"))
- GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], 'EFI_SECTION_FREEFORM_SUBTYPE_GUID', Guid=self.SubTypeGuid, IsMakefile=IsMakefile)
-
- OutputFileList = []
- OutputFileList.append(OutputFile)
- return OutputFileList, self.Alignment
-
+## @file +# process Subtype GUIDed section generation +# +# Copyright (c) 2022, Konstantin Aladyshev <aladyshev22@gmail.com> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from . import Section +import subprocess +from .Ffs import SectionSuffix +import Common.LongFilePathOs as os +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from .GenFdsGlobalVariable import FindExtendTool +from CommonDataClass.FdfClass import SubTypeGuidSectionClassObject +import sys +from Common import EdkLogger +from Common.BuildToolError import * +from .FvImageSection import FvImageSection +from Common.LongFilePathSupport import OpenLongFilePath as open +from Common.DataType import * + +## generate SubType GUIDed section +# +# +class SubTypeGuidSection(SubTypeGuidSectionClassObject) : + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + SubTypeGuidSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate GUIDed section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict=None, IsMakefile=False): + # + # Generate all section + # + self.KeyStringList = KeyStringList + self.CurrentArchList = GenFdsGlobalVariable.ArchList + if FfsInf is not None: + self.Alignment = FfsInf.__ExtendMacro__(self.Alignment) + self.SubTypeGuid = FfsInf.__ExtendMacro__(self.SubTypeGuid) + self.SectionType = FfsInf.__ExtendMacro__(self.SectionType) + self.CurrentArchList = [FfsInf.CurrentArch] + + if Dict is None: + Dict = {} + + self.SectFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.SectFileName) + self.SectFileName = GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict) + + OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + SectionSuffix.get("SUBTYPE_GUID")) + GenFdsGlobalVariable.GenerateSection(OutputFile, [self.SectFileName], 'EFI_SECTION_FREEFORM_SUBTYPE_GUID', Guid=self.SubTypeGuid, IsMakefile=IsMakefile) + + OutputFileList = [] + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment + diff --git a/BaseTools/Source/Python/GenFds/UiSection.py b/BaseTools/Source/Python/GenFds/UiSection.py index f643058bd6..a8aa94c075 100644 --- a/BaseTools/Source/Python/GenFds/UiSection.py +++ b/BaseTools/Source/Python/GenFds/UiSection.py @@ -1,74 +1,74 @@ -## @file
-# process UI section generation
-#
-# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from . import Section
-from .Ffs import SectionSuffix
-import subprocess
-import Common.LongFilePathOs as os
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-from CommonDataClass.FdfClass import UiSectionClassObject
-from Common.LongFilePathSupport import OpenLongFilePath as open
-from Common.DataType import *
-
-## generate UI section
-#
-#
-class UiSection (UiSectionClassObject):
-
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- UiSectionClassObject.__init__(self)
-
- ## GenSection() method
- #
- # Generate UI section
- #
- # @param self The object pointer
- # @param OutputPath Where to place output file
- # @param ModuleName Which module this section belongs to
- # @param SecNum Index of section
- # @param KeyStringList Filter for inputs of section generation
- # @param FfsInf FfsInfStatement object that contains this section data
- # @param Dict dictionary contains macro and its value
- # @retval tuple (Generated file name, section alignment)
- #
- def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict=None, IsMakefile = False):
- #
- # Prepare the parameter of GenSection
- #
- if FfsInf is not None:
- self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
- self.StringData = FfsInf.__ExtendMacro__(self.StringData)
- self.FileName = FfsInf.__ExtendMacro__(self.FileName)
-
- OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + SectionSuffix.get(BINARY_FILE_TYPE_UI))
-
- if self.StringData is not None :
- NameString = self.StringData
- elif self.FileName is not None:
- if Dict is None:
- Dict = {}
- FileNameStr = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
- FileNameStr = GenFdsGlobalVariable.MacroExtend(FileNameStr, Dict)
- FileObj = open(FileNameStr, 'r')
- NameString = FileObj.read()
- FileObj.close()
- else:
- NameString = ''
- GenFdsGlobalVariable.GenerateSection(OutputFile, None, 'EFI_SECTION_USER_INTERFACE', Ui=NameString, IsMakefile=IsMakefile)
-
- OutputFileList = []
- OutputFileList.append(OutputFile)
- return OutputFileList, self.Alignment
+## @file +# process UI section generation +# +# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from . import Section +from .Ffs import SectionSuffix +import subprocess +import Common.LongFilePathOs as os +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import UiSectionClassObject +from Common.LongFilePathSupport import OpenLongFilePath as open +from Common.DataType import * + +## generate UI section +# +# +class UiSection (UiSectionClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + UiSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate UI section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict=None, IsMakefile = False): + # + # Prepare the parameter of GenSection + # + if FfsInf is not None: + self.Alignment = FfsInf.__ExtendMacro__(self.Alignment) + self.StringData = FfsInf.__ExtendMacro__(self.StringData) + self.FileName = FfsInf.__ExtendMacro__(self.FileName) + + OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + SectionSuffix.get(BINARY_FILE_TYPE_UI)) + + if self.StringData is not None : + NameString = self.StringData + elif self.FileName is not None: + if Dict is None: + Dict = {} + FileNameStr = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName) + FileNameStr = GenFdsGlobalVariable.MacroExtend(FileNameStr, Dict) + FileObj = open(FileNameStr, 'r') + NameString = FileObj.read() + FileObj.close() + else: + NameString = '' + GenFdsGlobalVariable.GenerateSection(OutputFile, None, 'EFI_SECTION_USER_INTERFACE', Ui=NameString, IsMakefile=IsMakefile) + + OutputFileList = [] + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/VerSection.py b/BaseTools/Source/Python/GenFds/VerSection.py index 7280e80cb4..37ba96b941 100644 --- a/BaseTools/Source/Python/GenFds/VerSection.py +++ b/BaseTools/Source/Python/GenFds/VerSection.py @@ -1,76 +1,76 @@ -## @file
-# process Version section generation
-#
-# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-
-##
-# Import Modules
-#
-from __future__ import absolute_import
-from .Ffs import SectionSuffix
-import Common.LongFilePathOs as os
-from .GenFdsGlobalVariable import GenFdsGlobalVariable
-from CommonDataClass.FdfClass import VerSectionClassObject
-from Common.LongFilePathSupport import OpenLongFilePath as open
-from Common.DataType import SUP_MODULE_SEC
-
-## generate version section
-#
-#
-class VerSection (VerSectionClassObject):
-
- ## The constructor
- #
- # @param self The object pointer
- #
- def __init__(self):
- VerSectionClassObject.__init__(self)
-
- ## GenSection() method
- #
- # Generate version section
- #
- # @param self The object pointer
- # @param OutputPath Where to place output file
- # @param ModuleName Which module this section belongs to
- # @param SecNum Index of section
- # @param KeyStringList Filter for inputs of section generation
- # @param FfsInf FfsInfStatement object that contains this section data
- # @param Dict dictionary contains macro and its value
- # @retval tuple (Generated file name, section alignment)
- #
- def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict=None, IsMakefile = False):
- #
- # Prepare the parameter of GenSection
- #
- if FfsInf:
- self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
- self.BuildNum = FfsInf.__ExtendMacro__(self.BuildNum)
- self.StringData = FfsInf.__ExtendMacro__(self.StringData)
- self.FileName = FfsInf.__ExtendMacro__(self.FileName)
-
- OutputFile = os.path.join(OutputPath,
- ModuleName + SUP_MODULE_SEC + SecNum + SectionSuffix.get('VERSION'))
- OutputFile = os.path.normpath(OutputFile)
-
- # Get String Data
- StringData = ''
- if self.StringData:
- StringData = self.StringData
- elif self.FileName:
- if Dict is None:
- Dict = {}
- FileNameStr = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
- FileNameStr = GenFdsGlobalVariable.MacroExtend(FileNameStr, Dict)
- FileObj = open(FileNameStr, 'r')
- StringData = FileObj.read()
- StringData = '"' + StringData + '"'
- FileObj.close()
- GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
- Ver=StringData, BuildNumber=self.BuildNum, IsMakefile=IsMakefile)
- OutputFileList = []
- OutputFileList.append(OutputFile)
- return OutputFileList, self.Alignment
+## @file +# process Version section generation +# +# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# + +## +# Import Modules +# +from __future__ import absolute_import +from .Ffs import SectionSuffix +import Common.LongFilePathOs as os +from .GenFdsGlobalVariable import GenFdsGlobalVariable +from CommonDataClass.FdfClass import VerSectionClassObject +from Common.LongFilePathSupport import OpenLongFilePath as open +from Common.DataType import SUP_MODULE_SEC + +## generate version section +# +# +class VerSection (VerSectionClassObject): + + ## The constructor + # + # @param self The object pointer + # + def __init__(self): + VerSectionClassObject.__init__(self) + + ## GenSection() method + # + # Generate version section + # + # @param self The object pointer + # @param OutputPath Where to place output file + # @param ModuleName Which module this section belongs to + # @param SecNum Index of section + # @param KeyStringList Filter for inputs of section generation + # @param FfsInf FfsInfStatement object that contains this section data + # @param Dict dictionary contains macro and its value + # @retval tuple (Generated file name, section alignment) + # + def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict=None, IsMakefile = False): + # + # Prepare the parameter of GenSection + # + if FfsInf: + self.Alignment = FfsInf.__ExtendMacro__(self.Alignment) + self.BuildNum = FfsInf.__ExtendMacro__(self.BuildNum) + self.StringData = FfsInf.__ExtendMacro__(self.StringData) + self.FileName = FfsInf.__ExtendMacro__(self.FileName) + + OutputFile = os.path.join(OutputPath, + ModuleName + SUP_MODULE_SEC + SecNum + SectionSuffix.get('VERSION')) + OutputFile = os.path.normpath(OutputFile) + + # Get String Data + StringData = '' + if self.StringData: + StringData = self.StringData + elif self.FileName: + if Dict is None: + Dict = {} + FileNameStr = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName) + FileNameStr = GenFdsGlobalVariable.MacroExtend(FileNameStr, Dict) + FileObj = open(FileNameStr, 'r') + StringData = FileObj.read() + StringData = '"' + StringData + '"' + FileObj.close() + GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION', + Ver=StringData, BuildNumber=self.BuildNum, IsMakefile=IsMakefile) + OutputFileList = [] + OutputFileList.append(OutputFile) + return OutputFileList, self.Alignment diff --git a/BaseTools/Source/Python/GenFds/__init__.py b/BaseTools/Source/Python/GenFds/__init__.py index 09ea47ea57..017d26864f 100644 --- a/BaseTools/Source/Python/GenFds/__init__.py +++ b/BaseTools/Source/Python/GenFds/__init__.py @@ -1,9 +1,9 @@ -## @file
-# Python 'GenFds' package initialization file.
-#
-# This file is required to make Python interpreter treat the directory
-# as containing package.
-#
-# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
+## @file +# Python 'GenFds' package initialization file. +# +# This file is required to make Python interpreter treat the directory +# as containing package. +# +# Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# |
