REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2762 The Fv Section in the FDF files use hard coding Guid values which is inconvenient to manage. This patch adds Guid name support in GenFfs to solve this problem. Signed-off-by: Yuwei Chen <yuwei.chen@intel.com> Reviewed-by: Bob Feng<bob.c.feng@intel.com>
		
			
				
	
	
		
			4529 lines
		
	
	
		
			190 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			4529 lines
		
	
	
		
			190 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| ## @file
 | |
| # parse FDF file
 | |
| #
 | |
| #  Copyright (c) 2007 - 2018, 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 .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("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
 | |
| RegionSizeGuidPattern = compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*")
 | |
| RegionOffsetPcdPattern = compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$")
 | |
| ShortcutPcdPattern = compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
 | |
| BaseAddrValuePattern = compile('^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)
 | |
| 
 | |
|         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)
 | |
|         if Arch.upper() not in ARCH_SET_FULL:
 | |
|             raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
 | |
| 
 | |
|         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, BINARY_FILE_TYPE_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!")
 | |
| 
 |