X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FGenFds%2FFdfParser.py;h=662c232c86e427f97a7be79284644547ab8c1e31;hp=83d3e1935e371e179e5dc73d615f5910060b5668;hb=cdc9b0c2966a8681a2b4e14c2cf75bf1e37815a1;hpb=aaf8aa7b2cd6e5ee533aa622d72391226069e0c3 diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py index 83d3e1935e..662c232c86 100644 --- a/BaseTools/Source/Python/GenFds/FdfParser.py +++ b/BaseTools/Source/Python/GenFds/FdfParser.py @@ -1,7 +1,8 @@ ## @file # parse FDF file # -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -41,6 +42,7 @@ import ComponentStatement import OptionRom import OptRomInfStatement import OptRomFileStatement +import string from GenFdsGlobalVariable import GenFdsGlobalVariable from Common.BuildToolError import * @@ -51,12 +53,14 @@ import Common.GlobalData as GlobalData from Common.Expression import * from Common import GlobalData from Common.String import ReplaceMacro - +import uuid from Common.Misc import tdict - -import re +from Common.MultipleWorkspace import MultipleWorkspace as mws import Common.LongFilePathOs as os from Common.LongFilePathSupport import OpenLongFilePath as open +from Capsule import EFI_CERT_TYPE_PKCS7_GUID +from Capsule import EFI_CERT_TYPE_RSA2048_SHA256_GUID +from Common.RangeExpression import RangeExpression ##define T_CHAR_SPACE ' ' ##define T_CHAR_NULL '\0' @@ -80,17 +84,35 @@ RegionSizePattern = re.compile("\s*(?P(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P\w+\.\w+)\s*\|\s*(?P\w+\.\w+)\s*") RegionOffsetPcdPattern = re.compile("\s*(?P\w+\.\w+)\s*$") ShortcutPcdPattern = re.compile("\s*\w+\s*=\s*(?P(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P\w+\.\w+)\s*") +BaseAddrValuePattern = re.compile('^0[xX][0-9a-fA-F]+') +FileExtensionPattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)') +TokenFindPattern = re.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 -IncludeFileList = [] + return True def GetRealFileLine (File, Line): InsertedLines = 0 - for Profile in IncludeFileList: - if Line >= Profile.InsertStartLineNumber and Line < Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList): - return (Profile.FileName, Line - Profile.InsertStartLineNumber + 1) - if Line >= Profile.InsertStartLineNumber + Profile.InsertAdjust + len(Profile.FileLinesList): - InsertedLines += Profile.InsertAdjust + len(Profile.FileLinesList) + 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) @@ -111,27 +133,13 @@ class Warning (Exception): 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 -## The MACRO class that used to record macro value data when parsing include file -# -# -class MacroProfile : - ## The constructor - # - # @param self The object pointer - # @param FileName The file that to be parsed - # - def __init__(self, FileName, Line): - self.FileName = FileName - self.DefinedAtLine = Line - self.MacroName = None - self.MacroValue = None - ## The Include file content class that used to record file data when parsing include file # # May raise Exception when opening file. @@ -149,6 +157,10 @@ class IncludeFileProfile : fsock = open(FileName, "rb", 0) try: self.FileLinesList = fsock.readlines() + for index, line in enumerate(self.FileLinesList): + if not line.endswith('\n'): + self.FileLinesList[index] += '\n' + finally: fsock.close() @@ -157,6 +169,38 @@ class IncludeFileProfile : 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 # @@ -183,6 +227,7 @@ class FileProfile : self.PcdDict = {} self.InfList = [] + self.InfDict = {'ArchTBD':[]} # ECC will use this Dict and List information self.PcdFileLineDict = {} self.InfFileLineList = [] @@ -232,21 +277,6 @@ class FdfParser: if GenFdsGlobalVariable.WorkSpaceDir == '': GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE") - ## __IsWhiteSpace() method - # - # Whether char at current FileBufferPos is whitespace - # - # @param self The object pointer - # @param Char The char to test - # @retval True The char is a kind of white space - # @retval False The char is NOT a kind of white space - # - def __IsWhiteSpace(self, Char): - if Char in (T_CHAR_NULL, T_CHAR_CR, T_CHAR_SPACE, T_CHAR_TAB, T_CHAR_LF): - return True - else: - return False - ## __SkipWhiteSpace() method # # Skip white spaces from current char, return number of chars skipped @@ -306,10 +336,12 @@ class FdfParser: # 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): - self.CurrentLineNumber = 1 - self.CurrentOffsetWithinLine = 0 + def Rewind(self, DestLine = 1, DestOffset = 0): + self.CurrentLineNumber = DestLine + self.CurrentOffsetWithinLine = DestOffset ## __UndoOneChar() method # @@ -565,27 +597,48 @@ class FdfParser: # @param self The object pointer # def PreprocessIncludeFile(self): - + # nested include support + Processed = False + MacroDict = {} while self.__GetNextToken(): - if self.__Token == '!include': + if self.__Token == 'DEFINE': + if not self.__GetNextToken(): + raise Warning("expected Macro name", self.FileName, self.CurrentLineNumber) + Macro = self.__Token + if not self.__IsToken( "="): + raise Warning("expected '='", self.FileName, self.CurrentLineNumber) + Value = self.__GetExpression() + MacroDict[Macro] = Value + + elif self.__Token == '!include': + Processed = True IncludeLine = self.CurrentLineNumber IncludeOffset = self.CurrentOffsetWithinLine - len('!include') if not self.__GetNextToken(): raise Warning("expected include file name", self.FileName, self.CurrentLineNumber) IncFileName = self.__Token - __IncludeMacros = {} - for Macro in ['WORKSPACE', 'ECP_SOURCE', 'EFI_SOURCE', 'EDK_SOURCE']: + 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 MacroVal: - __IncludeMacros[Macro] = MacroVal + 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) - try: - IncludedFile = NormPath(ReplaceMacro(IncFileName, __IncludeMacros, RaiseError=True)) - except: - raise Warning("only these system environment variables are permitted to start the path of the included file: " - "$(WORKSPACE), $(ECP_SOURCE), $(EFI_SOURCE), $(EDK_SOURCE)", - self.FileName, self.CurrentLineNumber) + IncludedFile = NormPath(IncFileName) # # First search the include file under the same directory as FDF file # @@ -612,12 +665,19 @@ class FdfParser: 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(): @@ -633,16 +693,21 @@ class FdfParser: self.CurrentLineNumber += 1 InsertAtLine += 1 - IncludeFileList.append(IncFileProfile) + # 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, '#') 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() - def __GetIfListCurrentItemStat(self, IfList): + @staticmethod + def __GetIfListCurrentItemStat(IfList): if len(IfList) == 0: return True @@ -687,7 +752,7 @@ class FdfParser: while StartPos != -1 and EndPos != -1 and self.__Token not in ['!ifdef', '!ifndef', '!if', '!elseif']: MacroName = CurLine[StartPos+2 : EndPos] MacorValue = self.__GetMacroValue(MacroName) - if MacorValue != None: + if MacorValue is not None: CurLine = CurLine.replace('$(' + MacroName + ')', MacorValue, 1) if MacorValue.find('$(') != -1: PreIndex = StartPos @@ -836,6 +901,13 @@ class FdfParser: MacroDict.update(GlobalData.gGlobalDefines) MacroDict.update(GlobalData.gCommandLineDefines) + if GlobalData.BuildOptionPcd: + for Item in GlobalData.BuildOptionPcd: + if type(Item) is tuple: + continue + PcdName, TmpValue = Item.split("=") + TmpValue = BuildOptionValue(TmpValue, {}) + MacroDict[PcdName.strip()] = TmpValue # Highest priority return MacroDict @@ -1053,13 +1125,29 @@ class FdfParser: if not self.__GetNextToken(): return False - p = re.compile('[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}') - if p.match(self.__Token) != None: + if gGuidPattern.match(self.__Token) is not None: return True else: self.__UndoToken() return False + def __Verify(self, Name, Value, Scope): + if Scope in ['UINT64', 'UINT8']: + 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 Scope == 'UINT64': + if ValueNumber >= 0x10000000000000000: + EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name) + if Scope == 'UINT8': + if ValueNumber >= 0x100: + EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name) + return True + ## __UndoToken() method # # Go back one token unit in file buffer @@ -1093,32 +1181,13 @@ class FdfParser: self.__GetOneChar() - ## __HexDigit() method - # - # Whether char input is a Hex data bit - # - # @param self The object pointer - # @param TempChar The char to test - # @retval True The char is a Hex data bit - # @retval False The char is NOT a Hex data bit - # - def __HexDigit(self, TempChar): - if (TempChar >= 'a' and TempChar <= 'f') or (TempChar >= 'A' and TempChar <= 'F') \ - or (TempChar >= '0' and TempChar <= '9'): - return True - else: - return False - def __IsHex(self, HexStr): if not HexStr.upper().startswith("0X"): return False if len(self.__Token) <= 2: return False - charList = [c for c in HexStr[2 : ] if not self.__HexDigit( c)] - if len(charList) == 0: - return True - else: - return False + return True if all(x in string.hexdigits for x in HexStr[2:]) else False + ## __GetNextHexNumber() method # # Get next HEX data before a seperator @@ -1299,35 +1368,40 @@ class FdfParser: try: self.Preprocess() - while self.__GetFd(): - pass - - while self.__GetFv(): - pass - - while self.__GetFmp(): - pass - - while self.__GetCapsule(): - pass - - while self.__GetVtf(): - pass - - while self.__GetRule(): - pass - - while self.__GetOptionRom(): + # + # 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.__GetVtf() or self.__GetRule() or self.__GetOptionRom(): pass except Warning, X: self.__UndoToken() - FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber) #'\n\tGot Token: \"%s\" from File %s\n' % (self.__Token, FileLineTuple[0]) + \ - X.Message += ' near line %d, column %d: %s' \ + # 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('\n').rstrip('\r')) 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("[VTF.") 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.], [VTF.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self.FileName, self.CurrentLineNumber) + ## __GetDefines() method # # Get Defines section contents and store its data into AllMacrosList @@ -1343,9 +1417,7 @@ class FdfParser: S = self.__Token.upper() if S.startswith("[") and not S.startswith("[DEFINES"): - if not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \ - and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): - raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.SectionParser(S) self.__UndoToken() return False @@ -1435,7 +1507,7 @@ class FdfParser: while self.__GetTokenStatements(FdObj): pass for Attr in ("BaseAddress", "Size", "ErasePolarity"): - if getattr(FdObj, Attr) == None: + if getattr(FdObj, Attr) is None: self.__GetNextToken() raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber) @@ -1590,7 +1662,7 @@ class FdfParser: IsBlock = True Item = Obj.BlockSizeList[-1] - if Item[0] == None or Item[1] == None: + if Item[0] is None or Item[1] is None: raise Warning("expected block statement", self.FileName, self.CurrentLineNumber) return IsBlock @@ -1758,7 +1830,7 @@ class FdfParser: # def __GetRegionLayout(self, Fd): Offset = self.__CalcRegionExpr() - if Offset == None: + if Offset is None: return False RegionObj = Region.Region() @@ -1769,14 +1841,14 @@ class FdfParser: raise Warning("expected '|'", self.FileName, self.CurrentLineNumber) Size = self.__CalcRegionExpr() - if Size == None: + 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", "FV", "FILE", "DATA", "CAPSULE"): + if not self.__Token in ("SET", "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. @@ -1817,17 +1889,27 @@ class FdfParser: elif self.__Token == "FILE": self.__UndoToken() - self.__GetRegionFileType( RegionObj) + 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) + self.__GetRegionDataType(RegionObj) else: self.__UndoToken() if self.__GetRegionLayout(Fd): return True raise Warning("A valid region type was not found. " - "Valid types are [SET, FV, CAPSULE, FILE, DATA]. This error occurred", + "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred", self.FileName, self.CurrentLineNumber) return True @@ -1851,7 +1933,7 @@ class FdfParser: raise Warning("expected FV name", self.FileName, self.CurrentLineNumber) RegionObj.RegionType = "FV" - RegionObj.RegionDataList.append(self.__Token) + RegionObj.RegionDataList.append((self.__Token).upper()) while self.__IsKeyword( "FV"): @@ -1861,7 +1943,7 @@ class FdfParser: if not self.__GetNextToken(): raise Warning("expected FV name", self.FileName, self.CurrentLineNumber) - RegionObj.RegionDataList.append(self.__Token) + RegionObj.RegionDataList.append((self.__Token).upper()) ## __GetRegionCapType() method # @@ -2028,9 +2110,7 @@ class FdfParser: S = self.__Token.upper() if S.startswith("[") and not S.startswith("[FV."): - if not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \ - and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): - raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.SectionParser(S) self.__UndoToken() return False @@ -2078,7 +2158,7 @@ class FdfParser: self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy()) while True: - isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy()) + isInf = self.__GetInfStatement(FvObj) isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy()) if not isInf and not isFile: break @@ -2133,9 +2213,7 @@ class FdfParser: if not self.__GetNextToken(): raise Warning("expected FV base address value", self.FileName, self.CurrentLineNumber) - IsValidBaseAddrValue = re.compile('^0[x|X][0-9a-fA-F]+') - - if not IsValidBaseAddrValue.match(self.__Token.upper()): + 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 @@ -2191,7 +2269,7 @@ class FdfParser: "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"): + "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"): self.__UndoToken() return False @@ -2245,7 +2323,7 @@ class FdfParser: def __GetFvExtEntryStatement(self, FvObj): - if not self.__IsKeyword( "FV_EXT_ENTRY"): + if not (self.__IsKeyword( "FV_EXT_ENTRY") or self.__IsKeyword( "FV_EXT_ENTRY_TYPE")): return False if not self.__IsKeyword ("TYPE"): @@ -2345,7 +2423,7 @@ class FdfParser: MacroDict.update(AprSectionObj.DefineVarDict) while True: - IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict) + IsInf = self.__GetInfStatement(AprSectionObj) IsFile = self.__GetFileStatement( AprSectionObj) if not IsInf and not IsFile: break @@ -2356,27 +2434,18 @@ class FdfParser: FvObj.AprioriSectionList.append(AprSectionObj) return True - ## __GetInfStatement() method - # - # Get INF statements - # - # @param self The object pointer - # @param Obj for whom inf statement is got - # @param MacroDict dictionary used to replace macro - # @retval True Successfully find inf statement - # @retval False Not able to find inf statement - # - def __GetInfStatement(self, Obj, ForCapsule = False, MacroDict = {}): - - if not self.__IsKeyword( "INF"): - return False + def __ParseInfStatement(self): + if not self.__IsKeyword("INF"): + return None ffsInf = FfsInfStatement.FfsInfStatement() - self.__GetInfOptions( ffsInf) + 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() @@ -2394,6 +2463,13 @@ class FdfParser: self.Profile.InfList.append(ffsInf.InfFileName) 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('|'): if self.__IsKeyword('RELOCS_STRIPPED'): @@ -2402,7 +2478,22 @@ class FdfParser: 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: capsuleFfs = CapsuleData.CapsuleFfs() capsuleFfs.Ffs = ffsInf @@ -2534,13 +2625,12 @@ class FdfParser: # # Check whether reloc strip flag can be set for a file type. # - # @param self The object pointer # @param FileType The file type to check with # @retval True This type could have relocation strip flag # @retval False No way to have it # - - def __FileCouldHaveRelocFlag (self, FileType): + @staticmethod + def __FileCouldHaveRelocFlag (FileType): if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'): return True else: @@ -2550,13 +2640,12 @@ class FdfParser: # # Check whether reloc strip flag can be set for a section type. # - # @param self The object pointer # @param SectionType The section type to check with # @retval True This type could have relocation strip flag # @retval False No way to have it # - - def __SectionCouldHaveRelocFlag (self, SectionType): + @staticmethod + def __SectionCouldHaveRelocFlag (SectionType): if SectionType in ('TE', 'PE32'): return True else: @@ -2607,6 +2696,11 @@ class FdfParser: elif self.__Token in ("DEFINE", "APRIORI", "SECTION"): self.__UndoToken() self.__GetSectionData( FfsFileObj, MacroDict) + + elif hasattr(FfsFileObj, 'FvFileType') and FfsFileObj.FvFileType == 'RAW': + self.__UndoToken() + self.__GetRAWData(FfsFileObj, MacroDict) + else: FfsFileObj.CurrentLineNum = self.CurrentLineNumber FfsFileObj.CurrentLineContent = self.__CurrentLine() @@ -2616,6 +2710,48 @@ class FdfParser: if not self.__IsToken( "}"): raise Warning("expected '}'", self.FileName, self.CurrentLineNumber) + ## __GetRAWData() method + # + # Get RAW data for FILE statement + # + # @param self The object pointer + # @param FfsFileObj for whom section is got + # @param MacroDict dictionary used to replace macro + # + def __GetRAWData(self, FfsFileObj, MacroDict = {}): + FfsFileObj.FileName = [] + FfsFileObj.SubAlignment = [] + while True: + AlignValue = None + if self.__GetAlignment(): + if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K", + "256K", "512K", "1M", "2M", "4M", "8M", "16M"): + 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 == '}': + 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( "}"): + 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 @@ -2626,12 +2762,11 @@ class FdfParser: def __GetFileOpts(self, FfsFileObj): if self.__GetNextToken(): - Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)') - if Pattern.match(self.__Token): + if TokenFindPattern.match(self.__Token): FfsFileObj.KeyStringList.append(self.__Token) if self.__IsToken(","): while self.__GetNextToken(): - if not Pattern.match(self.__Token): + if not TokenFindPattern.match(self.__Token): raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber) FfsFileObj.KeyStringList.append(self.__Token) @@ -2648,7 +2783,8 @@ class FdfParser: FfsFileObj.CheckSum = True if self.__GetAlignment(): - if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K", + "256K", "512K", "1M", "2M", "4M", "8M", "16M"): raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) #For FFS, Auto is default option same to "" if not self.__Token == "Auto": @@ -2719,7 +2855,8 @@ class FdfParser: AlignValue = None if self.__GetAlignment(): - if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K", + "256K", "512K", "1M", "2M", "4M", "8M", "16M"): raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) AlignValue = self.__Token @@ -2788,7 +2925,7 @@ class FdfParser: self.__GetAprioriSection(FvObj, MacroDict.copy()) while True: - IsInf = self.__GetInfStatement(FvObj, MacroDict.copy()) + IsInf = self.__GetInfStatement(FvObj) IsFile = self.__GetFileStatement(FvObj, MacroDict.copy()) if not IsInf and not IsFile: break @@ -2798,7 +2935,7 @@ class FdfParser: FvImageSectionObj = FvImageSection.FvImageSection() FvImageSectionObj.Alignment = AlignValue - if FvObj != None: + if FvObj is not None: FvImageSectionObj.Fv = FvObj FvImageSectionObj.FvName = None else: @@ -3008,7 +3145,8 @@ class FdfParser: AlignValue = None if self.__GetAlignment(): - if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K", + "256K", "512K", "1M", "2M", "4M", "8M", "16M"): raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) AlignValue = self.__Token @@ -3022,9 +3160,8 @@ class FdfParser: if not self.__GetNextToken(): return False S = self.__Token.upper() - if not S.startswith("[FMPPAYLOAD."): - if not S.startswith("[CAPSULE.") and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): - raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [FmpPayload.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + if S.startswith("[") and not S.startswith("[FMPPAYLOAD."): + self.SectionParser(S) self.__UndoToken() return False @@ -3042,7 +3179,7 @@ class FdfParser: 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'] + 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) @@ -3050,32 +3187,52 @@ class FdfParser: raise Warning("expected '='", 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) + 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.UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_RSA2048_SHA256_GUID and uuid.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': - FmpData.Version = Value + if self.__Verify(Name, Value, 'UINT8'): + FmpData.Version = Value elif Name == 'IMAGE_INDEX': - FmpData.ImageIndex = Value + if self.__Verify(Name, Value, 'UINT8'): + FmpData.ImageIndex = Value elif Name == 'HARDWARE_INSTANCE': - FmpData.HardwareInstance = Value + if self.__Verify(Name, Value, 'UINT8'): + FmpData.HardwareInstance = Value + elif Name == 'MONOTONIC_COUNT': + if self.__Verify(Name, Value, 'UINT64'): + FmpData.MonotonicCount = Value + if FmpData.MonotonicCount.upper().startswith('0X'): + FmpData.MonotonicCount = (long)(FmpData.MonotonicCount, 16) + else: + FmpData.MonotonicCount = (long)(FmpData.MonotonicCount) if not self.__GetNextToken(): break else: self.__UndoToken() - if FmpKeyList: - raise Warning("Missing keywords %s in FMP payload section" % ', '.join(FmpKeyList), self.FileName, self.CurrentLineNumber) - ImageFile = self.__ParseRawFileStatement() - if not ImageFile: - raise Warning("Missing image file in FMP payload section", self.FileName, self.CurrentLineNumber) - FmpData.ImageFile = ImageFile - VendorCodeFile = self.__ParseRawFileStatement() - if VendorCodeFile: - FmpData.VendorCodeFile = VendorCodeFile + 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("Missing keywords 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("At most one Image file and one Vendor code file are allowed in FMP payload section.", self.FileName, self.CurrentLineNumber) self.Profile.FmpPayloadDict[FmpUiName] = FmpData return True @@ -3094,8 +3251,7 @@ class FdfParser: S = self.__Token.upper() if S.startswith("[") and not S.startswith("[CAPSULE."): - if not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): - raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.SectionParser(S) self.__UndoToken() return False @@ -3208,6 +3364,22 @@ class FdfParser: 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 @@ -3217,7 +3389,7 @@ class FdfParser: # @retval True Successfully find a FV statement # @retval False Not able to find a FV statement # - def __GetFvStatement(self, CapsuleObj): + def __GetFvStatement(self, CapsuleObj, FMPCapsule = False): if not self.__IsKeyword("FV"): return False @@ -3233,7 +3405,13 @@ class FdfParser: CapsuleFv = CapsuleData.CapsuleFv() CapsuleFv.FvName = self.__Token - CapsuleObj.CapsuleDataList.append(CapsuleFv) + if FMPCapsule: + if not CapsuleObj.ImageFile: + CapsuleObj.ImageFile.append(CapsuleFv) + else: + CapsuleObj.VendorCodeFile.append(CapsuleFv) + else: + CapsuleObj.CapsuleDataList.append(CapsuleFv) return True ## __GetFdStatement() method @@ -3245,7 +3423,7 @@ class FdfParser: # @retval True Successfully find a FD statement # @retval False Not able to find a FD statement # - def __GetFdStatement(self, CapsuleObj): + def __GetFdStatement(self, CapsuleObj, FMPCapsule = False): if not self.__IsKeyword("FD"): return False @@ -3261,22 +3439,29 @@ class FdfParser: CapsuleFd = CapsuleData.CapsuleFd() CapsuleFd.FdName = self.__Token - CapsuleObj.CapsuleDataList.append(CapsuleFd) + if FMPCapsule: + if not CapsuleObj.ImageFile: + CapsuleObj.ImageFile.append(CapsuleFd) + else: + CapsuleObj.VendorCodeFile.append(CapsuleFd) + else: + CapsuleObj.CapsuleDataList.append(CapsuleFd) return True def __GetFmpStatement(self, CapsuleObj): - if not self.__IsKeyword("FMP"): - return False + 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.__IsKeyword("PAYLOAD"): + self.__UndoToken() + return False if not self.__IsToken("="): raise Warning("expected '='", self.FileName, self.CurrentLineNumber) if not self.__GetNextToken(): - raise Warning("expected payload name after FMP PAYLOAD =", self.FileName, self.CurrentLineNumber) + 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) @@ -3298,9 +3483,11 @@ class FdfParser: raise Warning("expected File name", self.FileName, self.CurrentLineNumber) AnyFileName = self.__Token - AnyFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AnyFileName) - if not os.path.exists(AnyFileName): - raise Warning("File %s not exists"%AnyFileName, self.FileName, self.CurrentLineNumber) + self.__VerifyFile(AnyFileName) + + if not os.path.isabs(AnyFileName): + AnyFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, AnyFileName) + return AnyFileName ## __GetAnyFileStatement() method @@ -3312,14 +3499,20 @@ class FdfParser: # @retval True Successfully find a Anyfile statement # @retval False Not able to find a AnyFile statement # - def __GetAnyFileStatement(self, CapsuleObj): + def __GetAnyFileStatement(self, CapsuleObj, FMPCapsule = False): AnyFileName = self.__ParseRawFileStatement() if not AnyFileName: return False CapsuleAnyFile = CapsuleData.CapsuleAnyFile() CapsuleAnyFile.FileName = AnyFileName - CapsuleObj.CapsuleDataList.append(CapsuleAnyFile) + if FMPCapsule: + if not CapsuleObj.ImageFile: + CapsuleObj.ImageFile.append(CapsuleAnyFile) + else: + CapsuleObj.VendorCodeFile.append(CapsuleAnyFile) + else: + CapsuleObj.CapsuleDataList.append(CapsuleAnyFile) return True ## __GetAfileStatement() method @@ -3378,8 +3571,7 @@ class FdfParser: S = self.__Token.upper() if S.startswith("[") and not S.startswith("[RULE."): - if not S.startswith("[OPTIONROM."): - raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.SectionParser(S) self.__UndoToken() return False self.__UndoToken() @@ -3444,7 +3636,7 @@ class FdfParser: "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \ "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \ "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \ - "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE"): + "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE", "MM_STANDALONE", "MM_CORE_STANDALONE"): raise Warning("Unknown Module type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) return self.__Token @@ -3457,12 +3649,11 @@ class FdfParser: # def __GetFileExtension(self): if not self.__IsToken("."): - raise Warning("expected '.'", self.FileName, self.CurrentLineNumber) + raise Warning("expected '.'", self.FileName, self.CurrentLineNumber) Ext = "" if self.__GetNextToken(): - Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)') - if Pattern.match(self.__Token): + if FileExtensionPattern.match(self.__Token): Ext = self.__Token return '.' + Ext else: @@ -3488,7 +3679,7 @@ class FdfParser: Type = self.__Token.strip().upper() if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\ - "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE"): + "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE", "MM_STANDALONE", "MM_CORE_STANDALONE"): raise Warning("Unknown FV type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) if not self.__IsToken("="): @@ -3519,12 +3710,11 @@ class FdfParser: KeyStringList = [] if self.__GetNextToken(): - Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)') - if Pattern.match(self.__Token): + if TokenFindPattern.match(self.__Token): KeyStringList.append(self.__Token) if self.__IsToken(","): while self.__GetNextToken(): - if not Pattern.match(self.__Token): + if not TokenFindPattern.match(self.__Token): raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber) KeyStringList.append(self.__Token) @@ -3545,7 +3735,8 @@ class FdfParser: AlignValue = "" if self.__GetAlignment(): - if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K", + "256K", "512K", "1M", "2M", "4M", "8M", "16M"): raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) #For FFS, Auto is default option same to "" if not self.__Token == "Auto": @@ -3560,7 +3751,7 @@ class FdfParser: Rule.CheckSum = CheckSum Rule.Fixed = Fixed Rule.KeyStringList = KeyStringList - if KeepReloc != None: + if KeepReloc is not None: Rule.KeepReloc = KeepReloc while True: @@ -3594,7 +3785,8 @@ class FdfParser: SectAlignment = "" if self.__GetAlignment(): - if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K", + "256K", "512K", "1M", "2M", "4M", "8M", "16M"): raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'): raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) @@ -3615,7 +3807,7 @@ class FdfParser: Rule.CheckSum = CheckSum Rule.Fixed = Fixed Rule.KeyStringList = KeyStringList - if KeepReloc != None: + if KeepReloc is not None: Rule.KeepReloc = KeepReloc Rule.FileExtension = Ext Rule.FileName = self.__Token @@ -3673,7 +3865,8 @@ class FdfParser: FvImageSectionObj.FvFileType = self.__Token if self.__GetAlignment(): - if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K", + "256K", "512K", "1M", "2M", "4M", "8M", "16M"): raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) FvImageSectionObj.Alignment = self.__Token @@ -3740,7 +3933,8 @@ class FdfParser: EfiSectionObj.BuildNum = self.__Token if self.__GetAlignment(): - if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"): + if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K", "128K", + "256K", "512K", "1M", "2M", "4M", "8M", "16M"): raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'): raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber) @@ -3752,7 +3946,7 @@ class FdfParser: EfiSectionObj.KeepReloc = False else: EfiSectionObj.KeepReloc = True - if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc: + 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) @@ -3790,12 +3984,12 @@ class FdfParser: # # Get whether a section could be optional # - # @param self The object pointer # @param SectionType The section type to check # @retval True section could be optional # @retval False section never optional # - def __RuleSectionCouldBeOptional(self, SectionType): + @staticmethod + def __RuleSectionCouldBeOptional(SectionType): if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"): return True else: @@ -3805,12 +3999,12 @@ class FdfParser: # # Get whether a section could have build number information # - # @param self The object pointer # @param SectionType The section type to check # @retval True section could have build number information # @retval False section never have build number information # - def __RuleSectionCouldHaveBuildNum(self, SectionType): + @staticmethod + def __RuleSectionCouldHaveBuildNum(SectionType): if SectionType in ("VERSION"): return True else: @@ -3820,12 +4014,12 @@ class FdfParser: # # Get whether a section could have string # - # @param self The object pointer # @param SectionType The section type to check # @retval True section could have string # @retval False section never have string # - def __RuleSectionCouldHaveString(self, SectionType): + @staticmethod + def __RuleSectionCouldHaveString(SectionType): if SectionType in ("UI", "VERSION"): return True else: @@ -3955,8 +4149,7 @@ class FdfParser: S = self.__Token.upper() if S.startswith("[") and not S.startswith("[VTF."): - if not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."): - raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.SectionParser(S) self.__UndoToken() return False @@ -4066,7 +4259,7 @@ class FdfParser: raise Warning("expected Component type", self.FileName, self.CurrentLineNumber) if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"): if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \ - not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]): + not self.__Token[2] in string.hexdigits or not self.__Token[-1] in string.hexdigits: raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) CompStatementObj.CompType = self.__Token @@ -4080,7 +4273,7 @@ class FdfParser: raise Warning("expected Component version", self.FileName, self.CurrentLineNumber) Pattern = re.compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', re.DOTALL) - if Pattern.match(self.__Token) == None: + if Pattern.match(self.__Token) is None: raise Warning("Unknown version format '%s'" % self.__Token, self.FileName, self.CurrentLineNumber) CompStatementObj.CompVer = self.__Token @@ -4162,7 +4355,9 @@ class FdfParser: S = self.__Token.upper() if S.startswith("[") and not S.startswith("[OPTIONROM."): - raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber) + self.SectionParser(S) + self.__UndoToken() + return False self.__UndoToken() if not self.__IsToken("[OptionRom.", True): @@ -4215,6 +4410,13 @@ class FdfParser: self.Profile.InfList.append(ffsInf.InfFileName) 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) @@ -4335,7 +4537,7 @@ class FdfParser: for elementRegionData in elementRegion.RegionDataList: if elementRegionData.endswith(".cap"): continue - if elementRegionData != None and elementRegionData.upper() not in CapList: + if elementRegionData is not None and elementRegionData.upper() not in CapList: CapList.append(elementRegionData.upper()) return CapList @@ -4351,15 +4553,15 @@ class FdfParser: def __GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []): for CapsuleDataObj in CapObj.CapsuleDataList : - if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName != None and CapsuleDataObj.FvName.upper() not in RefFvList: + 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 != None and CapsuleDataObj.FdName.upper() not in RefFdList: + 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 != None: + elif CapsuleDataObj.Ffs is not None: if isinstance(CapsuleDataObj.Ffs, FfsFileStatement.FileStatement): - if CapsuleDataObj.Ffs.FvName != None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList: + 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 != None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList: + 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) @@ -4382,7 +4584,7 @@ class FdfParser: for elementRegionData in elementRegion.RegionDataList: if elementRegionData.endswith(".fv"): continue - if elementRegionData != None and elementRegionData.upper() not in FvList: + if elementRegionData is not None and elementRegionData.upper() not in FvList: FvList.append(elementRegionData.upper()) return FvList @@ -4399,9 +4601,9 @@ class FdfParser: for FfsObj in FvObj.FfsList: if isinstance(FfsObj, FfsFileStatement.FileStatement): - if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList: + if FfsObj.FvName is not None and FfsObj.FvName.upper() not in RefFvList: RefFvList.append(FfsObj.FvName.upper()) - elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList: + elif FfsObj.FdName is not None and FfsObj.FdName.upper() not in RefFdList: RefFdList.append(FfsObj.FdName.upper()) else: self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList) @@ -4422,9 +4624,9 @@ class FdfParser: while SectionStack != []: SectionObj = SectionStack.pop() if isinstance(SectionObj, FvImageSection.FvImageSection): - if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList: + if SectionObj.FvName is not None and SectionObj.FvName.upper() not in FvList: FvList.append(SectionObj.FvName.upper()) - if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList: + 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) @@ -4561,6 +4763,10 @@ class FdfParser: return False + def GetAllIncludedFile (self): + global AllIncludeFileList + return AllIncludeFileList + if __name__ == "__main__": import sys try: