]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/FdfParser.py
BaseTools: Fix merge in FDF parser for OptionROM override
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FdfParser.py
CommitLineData
30fdf114
LG
1## @file\r
2# parse FDF file\r
3#\r
a87e79d9 4# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
118bf096 5# Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>\r
30fdf114 6#\r
40d841f6 7# This program and the accompanying materials\r
30fdf114
LG
8# are licensed and made available under the terms and conditions of the BSD License\r
9# which accompanies this distribution. The full text of the license may be found at\r
10# http://opensource.org/licenses/bsd-license.php\r
11#\r
12# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14#\r
15\r
16##\r
17# Import Modules\r
18#\r
1ccc4d89
LG
19from __future__ import print_function\r
20from __future__ import absolute_import\r
9e47e6f9
CJ
21from re import compile, DOTALL\r
22from string import hexdigits\r
23from uuid import UUID\r
30fdf114
LG
24\r
25from Common.BuildToolError import *\r
26from Common import EdkLogger\r
9e47e6f9
CJ
27from Common.Misc import PathClass, tdict\r
28from Common.StringUtils import NormPath, ReplaceMacro\r
df692f02 29from Common import GlobalData\r
9e47e6f9 30from Common.Expression import *\r
55c84777 31from Common.DataType import *\r
94e4bcbb 32from Common.MultipleWorkspace import MultipleWorkspace as mws\r
1be2ed90
HC
33import Common.LongFilePathOs as os\r
34from Common.LongFilePathSupport import OpenLongFilePath as open\r
2eb370ff 35from Common.RangeExpression import RangeExpression\r
57ee97c0 36from collections import OrderedDict\r
30fdf114 37\r
9e47e6f9
CJ
38from .Fd import FD\r
39from .Region import Region\r
40from .Fv import FV\r
41from .AprioriSection import AprioriSection\r
42from .FfsInfStatement import FfsInfStatement\r
43from .FfsFileStatement import FileStatement\r
44from .VerSection import VerSection\r
45from .UiSection import UiSection\r
46from .FvImageSection import FvImageSection\r
47from .DataSection import DataSection\r
48from .DepexSection import DepexSection\r
49from .CompressSection import CompressSection\r
50from .GuidSection import GuidSection\r
51from .Capsule import EFI_CERT_TYPE_PKCS7_GUID, EFI_CERT_TYPE_RSA2048_SHA256_GUID, Capsule\r
52from .CapsuleData import CapsuleFfs, CapsulePayload, CapsuleFv, CapsuleFd, CapsuleAnyFile, CapsuleAfile\r
53from .RuleComplexFile import RuleComplexFile\r
54from .RuleSimpleFile import RuleSimpleFile\r
55from .EfiSection import EfiSection\r
56from .Vtf import Vtf\r
57from .ComponentStatement import ComponentStatement\r
58from .OptionRom import OPTIONROM\r
59from .OptRomInfStatement import OptRomInfStatement, OverrideAttribs\r
60from .OptRomFileStatement import OptRomFileStatement\r
61from .GenFdsGlobalVariable import GenFdsGlobalVariable\r
62\r
63T_CHAR_CR = '\r'\r
64T_CHAR_TAB = '\t'\r
65T_CHAR_DOUBLE_QUOTE = '\"'\r
66T_CHAR_SINGLE_QUOTE = '\''\r
67T_CHAR_STAR = '*'\r
ea98a825 68T_CHAR_BRACE_R = '}'\r
9e47e6f9 69\r
ea98a825 70SEPARATORS = {TAB_EQUAL_SPLIT, TAB_VALUE_SPLIT, TAB_COMMA_SPLIT, '{', T_CHAR_BRACE_R}\r
9e47e6f9
CJ
71ALIGNMENTS = {"Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K", "64K", "128K",\r
72 "256K", "512K", "1M", "2M", "4M", "8M", "16M"}\r
73ALIGNMENT_NOAUTO = ALIGNMENTS - {"Auto"}\r
5a264f28 74CR_LB_SET = {T_CHAR_CR, TAB_LINE_BREAK}\r
9e47e6f9
CJ
75\r
76RegionSizePattern = compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")\r
77RegionSizeGuidPattern = compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*")\r
78RegionOffsetPcdPattern = compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$")\r
79ShortcutPcdPattern = compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")\r
80BaseAddrValuePattern = compile('^0[xX][0-9a-fA-F]+')\r
81FileExtensionPattern = compile(r'([a-zA-Z][a-zA-Z0-9]*)')\r
82TokenFindPattern = compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')\r
118bf096
CS
83AllIncludeFileList = []\r
84\r
85# Get the closest parent\r
86def GetParentAtLine (Line):\r
87 for Profile in AllIncludeFileList:\r
88 if Profile.IsLineInFile(Line):\r
89 return Profile\r
90 return None\r
91\r
92# Check include loop\r
93def IsValidInclude (File, Line):\r
94 for Profile in AllIncludeFileList:\r
95 if Profile.IsLineInFile(Line) and Profile.FileName == File:\r
96 return False\r
97\r
98 return True\r
30fdf114
LG
99\r
100def GetRealFileLine (File, Line):\r
30fdf114 101 InsertedLines = 0\r
118bf096
CS
102 for Profile in AllIncludeFileList:\r
103 if Profile.IsLineInFile(Line):\r
104 return Profile.GetLineInFile(Line)\r
105 elif Line >= Profile.InsertStartLineNumber and Profile.Level == 1:\r
df81077f 106 InsertedLines += Profile.GetTotalLines()\r
30fdf114
LG
107\r
108 return (File, Line - InsertedLines)\r
109\r
110## The exception class that used to report error messages when parsing FDF\r
111#\r
9e47e6f9 112# Currently the "ToolName" is set to be "FdfParser".\r
30fdf114
LG
113#\r
114class Warning (Exception):\r
115 ## The constructor\r
116 #\r
117 # @param self The object pointer\r
118 # @param Str The message to record\r
119 # @param File The FDF name\r
120 # @param Line The Line number that error occurs\r
121 #\r
122 def __init__(self, Str, File = None, Line = None):\r
30fdf114
LG
123 FileLineTuple = GetRealFileLine(File, Line)\r
124 self.FileName = FileLineTuple[0]\r
125 self.LineNumber = FileLineTuple[1]\r
118bf096 126 self.OriginalLineNumber = Line\r
30fdf114
LG
127 self.Message = Str\r
128 self.ToolName = 'FdfParser'\r
129\r
130 def __str__(self):\r
131 return self.Message\r
132\r
ca957eb5
CJ
133 # helper functions to facilitate consistency in warnings\r
134 # each function is for a different common warning\r
135 @staticmethod\r
136 def Expected(Str, File, Line):\r
137 return Warning("expected {}".format(Str), File, Line)\r
138 @staticmethod\r
139 def ExpectedEquals(File, Line):\r
140 return Warning.Expected("'='", File, Line)\r
141 @staticmethod\r
142 def ExpectedCurlyOpen(File, Line):\r
143 return Warning.Expected("'{'", File, Line)\r
144 @staticmethod\r
145 def ExpectedCurlyClose(File, Line):\r
146 return Warning.Expected("'}'", File, Line)\r
147 @staticmethod\r
148 def ExpectedBracketClose(File, Line):\r
149 return Warning.Expected("']'", File, Line)\r
150\r
30fdf114
LG
151## The Include file content class that used to record file data when parsing include file\r
152#\r
153# May raise Exception when opening file.\r
154#\r
9e47e6f9 155class IncludeFileProfile:\r
30fdf114
LG
156 ## The constructor\r
157 #\r
158 # @param self The object pointer\r
159 # @param FileName The file that to be parsed\r
160 #\r
161 def __init__(self, FileName):\r
162 self.FileName = FileName\r
163 self.FileLinesList = []\r
164 try:\r
9e47e6f9 165 with open(FileName, "rb", 0) as fsock:\r
30fdf114 166 self.FileLinesList = fsock.readlines()\r
47a29bc7 167 for index, line in enumerate(self.FileLinesList):\r
9e47e6f9
CJ
168 if not line.endswith(TAB_LINE_BREAK):\r
169 self.FileLinesList[index] += TAB_LINE_BREAK\r
30fdf114
LG
170 except:\r
171 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)\r
172\r
173 self.InsertStartLineNumber = None\r
174 self.InsertAdjust = 0\r
118bf096
CS
175 self.IncludeFileList = []\r
176 self.Level = 1 # first level include file\r
f7496d71 177\r
118bf096
CS
178 def GetTotalLines(self):\r
179 TotalLines = self.InsertAdjust + len(self.FileLinesList)\r
180\r
181 for Profile in self.IncludeFileList:\r
df81077f 182 TotalLines += Profile.GetTotalLines()\r
118bf096
CS
183\r
184 return TotalLines\r
185\r
186 def IsLineInFile(self, Line):\r
187 if Line >= self.InsertStartLineNumber and Line < self.InsertStartLineNumber + self.GetTotalLines():\r
188 return True\r
189\r
190 return False\r
191\r
192 def GetLineInFile(self, Line):\r
193 if not self.IsLineInFile (Line):\r
194 return (self.FileName, -1)\r
f7496d71 195\r
118bf096
CS
196 InsertedLines = self.InsertStartLineNumber\r
197\r
198 for Profile in self.IncludeFileList:\r
199 if Profile.IsLineInFile(Line):\r
200 return Profile.GetLineInFile(Line)\r
201 elif Line >= Profile.InsertStartLineNumber:\r
202 InsertedLines += Profile.GetTotalLines()\r
203\r
204 return (self.FileName, Line - InsertedLines + 1)\r
205\r
30fdf114
LG
206## The FDF content class that used to record file data when parsing FDF\r
207#\r
208# May raise Exception when opening file.\r
209#\r
9e47e6f9 210class FileProfile:\r
30fdf114
LG
211 ## The constructor\r
212 #\r
213 # @param self The object pointer\r
214 # @param FileName The file that to be parsed\r
215 #\r
216 def __init__(self, FileName):\r
217 self.FileLinesList = []\r
218 try:\r
9e47e6f9 219 with open(FileName, "rb", 0) as fsock:\r
30fdf114 220 self.FileLinesList = fsock.readlines()\r
30fdf114
LG
221\r
222 except:\r
223 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)\r
224\r
543f5ac3 225 self.FileName = FileName\r
57ee97c0
B
226 self.PcdDict = OrderedDict()\r
227 self.PcdLocalDict = OrderedDict()\r
30fdf114 228 self.InfList = []\r
2502b735 229 self.InfDict = {'ArchTBD':[]}\r
d0acc87a
LG
230 # ECC will use this Dict and List information\r
231 self.PcdFileLineDict = {}\r
232 self.InfFileLineList = []\r
f7496d71 233\r
30fdf114 234 self.FdDict = {}\r
52302d4d 235 self.FdNameNotSet = False\r
30fdf114 236 self.FvDict = {}\r
fd171542 237 self.CapsuleDict = {}\r
30fdf114
LG
238 self.VtfList = []\r
239 self.RuleDict = {}\r
240 self.OptRomDict = {}\r
a3251d84 241 self.FmpPayloadDict = {}\r
30fdf114
LG
242\r
243## The syntax parser for FDF\r
244#\r
245# PreprocessFile method should be called prior to ParseFile\r
246# CycleReferenceCheck method can detect cycles in FDF contents\r
247#\r
248# GetNext*** procedures mean these procedures will get next token first, then make judgement.\r
249# Get*** procedures mean these procedures will make judgement on current token only.\r
250#\r
251class FdfParser:\r
252 ## The constructor\r
253 #\r
254 # @param self The object pointer\r
255 # @param FileName The file that to be parsed\r
256 #\r
257 def __init__(self, FileName):\r
258 self.Profile = FileProfile(FileName)\r
259 self.FileName = FileName\r
260 self.CurrentLineNumber = 1\r
261 self.CurrentOffsetWithinLine = 0\r
262 self.CurrentFdName = None\r
263 self.CurrentFvName = None\r
9e47e6f9
CJ
264 self._Token = ""\r
265 self._SkippedChars = ""\r
97fa0ee9 266 GlobalData.gFdfParser = self\r
30fdf114 267\r
d0acc87a 268 # Used to section info\r
9e47e6f9 269 self._CurSection = []\r
d0acc87a 270 # Key: [section name, UI name, arch]\r
9e47e6f9
CJ
271 # Value: {MACRO_NAME: MACRO_VALUE}\r
272 self._MacroDict = tdict(True, 3)\r
273 self._PcdDict = OrderedDict()\r
d0acc87a 274\r
9e47e6f9 275 self._WipeOffArea = []\r
14c48571 276 if GenFdsGlobalVariable.WorkSpaceDir == '':\r
277 GenFdsGlobalVariable.WorkSpaceDir = os.getenv("WORKSPACE")\r
30fdf114 278\r
9e47e6f9 279 ## _SkipWhiteSpace() method\r
30fdf114 280 #\r
9e47e6f9 281 # Skip white spaces from current char.\r
30fdf114
LG
282 #\r
283 # @param self The object pointer\r
30fdf114 284 #\r
9e47e6f9
CJ
285 def _SkipWhiteSpace(self):\r
286 while not self._EndOfFile():\r
5a264f28 287 if self._CurrentChar() in {TAB_PRINTCHAR_NUL, T_CHAR_CR, TAB_LINE_BREAK, TAB_SPACE_SPLIT, T_CHAR_TAB}:\r
9e47e6f9
CJ
288 self._SkippedChars += str(self._CurrentChar())\r
289 self._GetOneChar()\r
30fdf114 290 else:\r
9e47e6f9
CJ
291 return\r
292 return\r
30fdf114 293\r
9e47e6f9 294 ## _EndOfFile() method\r
30fdf114
LG
295 #\r
296 # Judge current buffer pos is at file end\r
297 #\r
298 # @param self The object pointer\r
299 # @retval True Current File buffer position is at file end\r
300 # @retval False Current File buffer position is NOT at file end\r
301 #\r
9e47e6f9 302 def _EndOfFile(self):\r
30fdf114
LG
303 NumberOfLines = len(self.Profile.FileLinesList)\r
304 SizeOfLastLine = len(self.Profile.FileLinesList[-1])\r
305 if self.CurrentLineNumber == NumberOfLines and self.CurrentOffsetWithinLine >= SizeOfLastLine - 1:\r
306 return True\r
9e47e6f9 307 if self.CurrentLineNumber > NumberOfLines:\r
30fdf114 308 return True\r
9e47e6f9 309 return False\r
30fdf114 310\r
9e47e6f9 311 ## _EndOfLine() method\r
30fdf114
LG
312 #\r
313 # Judge current buffer pos is at line end\r
314 #\r
315 # @param self The object pointer\r
316 # @retval True Current File buffer position is at line end\r
317 # @retval False Current File buffer position is NOT at line end\r
318 #\r
9e47e6f9 319 def _EndOfLine(self):\r
30fdf114
LG
320 if self.CurrentLineNumber > len(self.Profile.FileLinesList):\r
321 return True\r
322 SizeOfCurrentLine = len(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
323 if self.CurrentOffsetWithinLine >= SizeOfCurrentLine:\r
324 return True\r
9e47e6f9 325 return False\r
30fdf114
LG
326\r
327 ## Rewind() method\r
328 #\r
329 # Reset file data buffer to the initial state\r
330 #\r
331 # @param self The object pointer\r
118bf096 332 # @param DestLine Optional new destination line number.\r
f7496d71 333 # @param DestOffset Optional new destination offset.\r
30fdf114 334 #\r
f7496d71
LG
335 def Rewind(self, DestLine = 1, DestOffset = 0):\r
336 self.CurrentLineNumber = DestLine\r
337 self.CurrentOffsetWithinLine = DestOffset\r
30fdf114 338\r
9e47e6f9 339 ## _UndoOneChar() method\r
30fdf114
LG
340 #\r
341 # Go back one char in the file buffer\r
342 #\r
343 # @param self The object pointer\r
344 # @retval True Successfully go back one char\r
345 # @retval False Not able to go back one char as file beginning reached\r
346 #\r
9e47e6f9 347 def _UndoOneChar(self):\r
30fdf114
LG
348 if self.CurrentLineNumber == 1 and self.CurrentOffsetWithinLine == 0:\r
349 return False\r
350 elif self.CurrentOffsetWithinLine == 0:\r
351 self.CurrentLineNumber -= 1\r
9e47e6f9 352 self.CurrentOffsetWithinLine = len(self._CurrentLine()) - 1\r
30fdf114
LG
353 else:\r
354 self.CurrentOffsetWithinLine -= 1\r
355 return True\r
356\r
9e47e6f9 357 ## _GetOneChar() method\r
30fdf114
LG
358 #\r
359 # Move forward one char in the file buffer\r
360 #\r
361 # @param self The object pointer\r
362 #\r
9e47e6f9 363 def _GetOneChar(self):\r
30fdf114 364 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:\r
0d2711a6
LG
365 self.CurrentLineNumber += 1\r
366 self.CurrentOffsetWithinLine = 0\r
30fdf114 367 else:\r
0d2711a6 368 self.CurrentOffsetWithinLine += 1\r
30fdf114 369\r
9e47e6f9 370 ## _CurrentChar() method\r
30fdf114
LG
371 #\r
372 # Get the char pointed to by the file buffer pointer\r
373 #\r
374 # @param self The object pointer\r
375 # @retval Char Current char\r
376 #\r
9e47e6f9 377 def _CurrentChar(self):\r
30fdf114
LG
378 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine]\r
379\r
9e47e6f9 380 ## _NextChar() method\r
30fdf114
LG
381 #\r
382 # Get the one char pass the char pointed to by the file buffer pointer\r
383 #\r
384 # @param self The object pointer\r
385 # @retval Char Next char\r
386 #\r
9e47e6f9 387 def _NextChar(self):\r
30fdf114
LG
388 if self.CurrentOffsetWithinLine == len(self.Profile.FileLinesList[self.CurrentLineNumber - 1]) - 1:\r
389 return self.Profile.FileLinesList[self.CurrentLineNumber][0]\r
9e47e6f9 390 return self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine + 1]\r
30fdf114 391\r
9e47e6f9 392 ## _SetCurrentCharValue() method\r
30fdf114
LG
393 #\r
394 # Modify the value of current char\r
395 #\r
396 # @param self The object pointer\r
397 # @param Value The new value of current char\r
398 #\r
9e47e6f9 399 def _SetCurrentCharValue(self, Value):\r
30fdf114
LG
400 self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine] = Value\r
401\r
9e47e6f9 402 ## _CurrentLine() method\r
30fdf114
LG
403 #\r
404 # Get the list that contains current line contents\r
405 #\r
406 # @param self The object pointer\r
407 # @retval List current line contents\r
408 #\r
9e47e6f9 409 def _CurrentLine(self):\r
30fdf114
LG
410 return self.Profile.FileLinesList[self.CurrentLineNumber - 1]\r
411\r
9e47e6f9 412 def _StringToList(self):\r
30fdf114 413 self.Profile.FileLinesList = [list(s) for s in self.Profile.FileLinesList]\r
3b46dd93
YF
414 if not self.Profile.FileLinesList:\r
415 EdkLogger.error('FdfParser', FILE_READ_FAILURE, 'The file is empty!', File=self.FileName)\r
30fdf114
LG
416 self.Profile.FileLinesList[-1].append(' ')\r
417\r
9e47e6f9 418 def _ReplaceFragment(self, StartPos, EndPos, Value = ' '):\r
30fdf114
LG
419 if StartPos[0] == EndPos[0]:\r
420 Offset = StartPos[1]\r
421 while Offset <= EndPos[1]:\r
422 self.Profile.FileLinesList[StartPos[0]][Offset] = Value\r
423 Offset += 1\r
424 return\r
425\r
426 Offset = StartPos[1]\r
5a264f28 427 while self.Profile.FileLinesList[StartPos[0]][Offset] not in CR_LB_SET:\r
30fdf114
LG
428 self.Profile.FileLinesList[StartPos[0]][Offset] = Value\r
429 Offset += 1\r
430\r
431 Line = StartPos[0]\r
432 while Line < EndPos[0]:\r
433 Offset = 0\r
5a264f28 434 while self.Profile.FileLinesList[Line][Offset] not in CR_LB_SET:\r
30fdf114
LG
435 self.Profile.FileLinesList[Line][Offset] = Value\r
436 Offset += 1\r
437 Line += 1\r
438\r
439 Offset = 0\r
440 while Offset <= EndPos[1]:\r
441 self.Profile.FileLinesList[EndPos[0]][Offset] = Value\r
442 Offset += 1\r
443\r
9e47e6f9
CJ
444 def _SetMacroValue(self, Macro, Value):\r
445 if not self._CurSection:\r
d0acc87a
LG
446 return\r
447\r
448 MacroDict = {}\r
9e47e6f9
CJ
449 if not self._MacroDict[self._CurSection[0], self._CurSection[1], self._CurSection[2]]:\r
450 self._MacroDict[self._CurSection[0], self._CurSection[1], self._CurSection[2]] = MacroDict\r
d0acc87a 451 else:\r
9e47e6f9 452 MacroDict = self._MacroDict[self._CurSection[0], self._CurSection[1], self._CurSection[2]]\r
d0acc87a
LG
453 MacroDict[Macro] = Value\r
454\r
9e47e6f9 455 def _GetMacroValue(self, Macro):\r
d0acc87a
LG
456 # Highest priority\r
457 if Macro in GlobalData.gCommandLineDefines:\r
458 return GlobalData.gCommandLineDefines[Macro]\r
459 if Macro in GlobalData.gGlobalDefines:\r
460 return GlobalData.gGlobalDefines[Macro]\r
461\r
9e47e6f9
CJ
462 if self._CurSection:\r
463 MacroDict = self._MacroDict[\r
464 self._CurSection[0],\r
465 self._CurSection[1],\r
466 self._CurSection[2]\r
d0acc87a
LG
467 ]\r
468 if MacroDict and Macro in MacroDict:\r
469 return MacroDict[Macro]\r
470\r
471 # Lowest priority\r
472 if Macro in GlobalData.gPlatformDefines:\r
473 return GlobalData.gPlatformDefines[Macro]\r
474 return None\r
475\r
9e47e6f9 476 def _SectionHeaderParser(self, Section):\r
d0acc87a
LG
477 # [Defines]\r
478 # [FD.UiName]: use dummy instead if UI name is optional\r
479 # [FV.UiName]\r
480 # [Capsule.UiName]\r
481 # [Rule]: don't take rule section into account, macro is not allowed in this section\r
482 # [VTF.arch.UiName, arch]\r
483 # [OptionRom.DriverName]\r
9e47e6f9
CJ
484 self._CurSection = []\r
485 Section = Section.strip()[1:-1].upper().replace(' ', '').strip(TAB_SPLIT)\r
486 ItemList = Section.split(TAB_SPLIT)\r
d0acc87a
LG
487 Item = ItemList[0]\r
488 if Item == '' or Item == 'RULE':\r
489 return\r
490\r
55c84777 491 if Item == TAB_COMMON_DEFINES.upper():\r
9e47e6f9 492 self._CurSection = [TAB_COMMON, TAB_COMMON, TAB_COMMON]\r
d0acc87a
LG
493 elif Item == 'VTF' and len(ItemList) == 3:\r
494 UiName = ItemList[2]\r
9e47e6f9 495 Pos = UiName.find(TAB_COMMA_SPLIT)\r
d0acc87a
LG
496 if Pos != -1:\r
497 UiName = UiName[:Pos]\r
9e47e6f9 498 self._CurSection = ['VTF', UiName, ItemList[1]]\r
d0acc87a 499 elif len(ItemList) > 1:\r
9e47e6f9 500 self._CurSection = [ItemList[0], ItemList[1], TAB_COMMON]\r
d0acc87a 501 elif len(ItemList) > 0:\r
9e47e6f9 502 self._CurSection = [ItemList[0], 'DUMMY', TAB_COMMON]\r
d0acc87a 503\r
30fdf114
LG
504 ## PreprocessFile() method\r
505 #\r
506 # Preprocess file contents, replace comments with spaces.\r
507 # In the end, rewind the file buffer pointer to the beginning\r
508 # BUGBUG: No !include statement processing contained in this procedure\r
509 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]\r
510 #\r
511 # @param self The object pointer\r
512 #\r
513 def PreprocessFile(self):\r
30fdf114
LG
514 self.Rewind()\r
515 InComment = False\r
516 DoubleSlashComment = False\r
517 HashComment = False\r
518 # HashComment in quoted string " " is ignored.\r
519 InString = False\r
520\r
9e47e6f9 521 while not self._EndOfFile():\r
30fdf114 522\r
9e47e6f9 523 if self._CurrentChar() == T_CHAR_DOUBLE_QUOTE and not InComment:\r
30fdf114
LG
524 InString = not InString\r
525 # meet new line, then no longer in a comment for // and '#'\r
9e47e6f9 526 if self._CurrentChar() == TAB_LINE_BREAK:\r
30fdf114
LG
527 self.CurrentLineNumber += 1\r
528 self.CurrentOffsetWithinLine = 0\r
529 if InComment and DoubleSlashComment:\r
530 InComment = False\r
531 DoubleSlashComment = False\r
532 if InComment and HashComment:\r
533 InComment = False\r
534 HashComment = False\r
535 # check for */ comment end\r
9e47e6f9
CJ
536 elif InComment and not DoubleSlashComment and not HashComment and self._CurrentChar() == T_CHAR_STAR and self._NextChar() == TAB_BACK_SLASH:\r
537 self._SetCurrentCharValue(TAB_SPACE_SPLIT)\r
538 self._GetOneChar()\r
539 self._SetCurrentCharValue(TAB_SPACE_SPLIT)\r
540 self._GetOneChar()\r
30fdf114
LG
541 InComment = False\r
542 # set comments to spaces\r
543 elif InComment:\r
9e47e6f9
CJ
544 self._SetCurrentCharValue(TAB_SPACE_SPLIT)\r
545 self._GetOneChar()\r
30fdf114 546 # check for // comment\r
9e47e6f9 547 elif self._CurrentChar() == TAB_BACK_SLASH and self._NextChar() == TAB_BACK_SLASH and not self._EndOfLine():\r
30fdf114
LG
548 InComment = True\r
549 DoubleSlashComment = True\r
550 # check for '#' comment\r
9e47e6f9 551 elif self._CurrentChar() == TAB_COMMENT_SPLIT and not self._EndOfLine() and not InString:\r
30fdf114
LG
552 InComment = True\r
553 HashComment = True\r
554 # check for /* comment start\r
9e47e6f9
CJ
555 elif self._CurrentChar() == TAB_BACK_SLASH and self._NextChar() == T_CHAR_STAR:\r
556 self._SetCurrentCharValue(TAB_SPACE_SPLIT)\r
557 self._GetOneChar()\r
558 self._SetCurrentCharValue(TAB_SPACE_SPLIT)\r
559 self._GetOneChar()\r
30fdf114
LG
560 InComment = True\r
561 else:\r
9e47e6f9 562 self._GetOneChar()\r
30fdf114
LG
563\r
564 # restore from ListOfList to ListOfString\r
565 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]\r
566 self.Rewind()\r
567\r
568 ## PreprocessIncludeFile() method\r
569 #\r
570 # Preprocess file contents, replace !include statements with file contents.\r
571 # In the end, rewind the file buffer pointer to the beginning\r
572 #\r
573 # @param self The object pointer\r
574 #\r
575 def PreprocessIncludeFile(self):\r
f7496d71 576 # nested include support\r
118bf096 577 Processed = False\r
0fdfe274 578 MacroDict = {}\r
9e47e6f9 579 while self._GetNextToken():\r
30fdf114 580\r
9e47e6f9
CJ
581 if self._Token == TAB_DEFINE:\r
582 if not self._GetNextToken():\r
ca957eb5 583 raise Warning.Expected("Macro name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
584 Macro = self._Token\r
585 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 586 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 587 Value = self._GetExpression()\r
0fdfe274
YZ
588 MacroDict[Macro] = Value\r
589\r
9e47e6f9 590 elif self._Token == TAB_INCLUDE:\r
118bf096 591 Processed = True\r
30fdf114 592 IncludeLine = self.CurrentLineNumber\r
9e47e6f9
CJ
593 IncludeOffset = self.CurrentOffsetWithinLine - len(TAB_INCLUDE)\r
594 if not self._GetNextToken():\r
ca957eb5 595 raise Warning.Expected("include file name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 596 IncFileName = self._Token\r
0fdfe274
YZ
597 PreIndex = 0\r
598 StartPos = IncFileName.find('$(', PreIndex)\r
599 EndPos = IncFileName.find(')', StartPos+2)\r
600 while StartPos != -1 and EndPos != -1:\r
9e47e6f9
CJ
601 Macro = IncFileName[StartPos+2: EndPos]\r
602 MacroVal = self._GetMacroValue(Macro)\r
0fdfe274
YZ
603 if not MacroVal:\r
604 if Macro in MacroDict:\r
605 MacroVal = MacroDict[Macro]\r
4231a819 606 if MacroVal is not None:\r
0fdfe274
YZ
607 IncFileName = IncFileName.replace('$(' + Macro + ')', MacroVal, 1)\r
608 if MacroVal.find('$(') != -1:\r
609 PreIndex = StartPos\r
610 else:\r
611 PreIndex = StartPos + len(MacroVal)\r
612 else:\r
613 raise Warning("The Macro %s is not defined" %Macro, self.FileName, self.CurrentLineNumber)\r
614 StartPos = IncFileName.find('$(', PreIndex)\r
615 EndPos = IncFileName.find(')', StartPos+2)\r
616\r
617 IncludedFile = NormPath(IncFileName)\r
2bcc713e
LG
618 #\r
619 # First search the include file under the same directory as FDF file\r
620 #\r
621 IncludedFile1 = PathClass(IncludedFile, os.path.dirname(self.FileName))\r
622 ErrorCode = IncludedFile1.Validate()[0]\r
623 if ErrorCode != 0:\r
624 #\r
625 # Then search the include file under the same directory as DSC file\r
626 #\r
d0acc87a
LG
627 PlatformDir = ''\r
628 if GenFdsGlobalVariable.ActivePlatform:\r
629 PlatformDir = GenFdsGlobalVariable.ActivePlatform.Dir\r
630 elif GlobalData.gActivePlatform:\r
631 PlatformDir = GlobalData.gActivePlatform.MetaFile.Dir\r
632 IncludedFile1 = PathClass(IncludedFile, PlatformDir)\r
2bcc713e
LG
633 ErrorCode = IncludedFile1.Validate()[0]\r
634 if ErrorCode != 0:\r
635 #\r
636 # Also search file under the WORKSPACE directory\r
637 #\r
638 IncludedFile1 = PathClass(IncludedFile, GlobalData.gWorkspace)\r
639 ErrorCode = IncludedFile1.Validate()[0]\r
640 if ErrorCode != 0:\r
f7496d71 641 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),\r
2bcc713e 642 self.FileName, self.CurrentLineNumber)\r
30fdf114 643\r
118bf096
CS
644 if not IsValidInclude (IncludedFile1.Path, self.CurrentLineNumber):\r
645 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1.Path), self.FileName, self.CurrentLineNumber)\r
646\r
2bcc713e 647 IncFileProfile = IncludeFileProfile(IncludedFile1.Path)\r
30fdf114
LG
648\r
649 CurrentLine = self.CurrentLineNumber\r
650 CurrentOffset = self.CurrentOffsetWithinLine\r
651 # list index of the insertion, note that line number is 'CurrentLine + 1'\r
652 InsertAtLine = CurrentLine\r
118bf096 653 ParentProfile = GetParentAtLine (CurrentLine)\r
4231a819 654 if ParentProfile is not None:\r
118bf096
CS
655 ParentProfile.IncludeFileList.insert(0, IncFileProfile)\r
656 IncFileProfile.Level = ParentProfile.Level + 1\r
30fdf114
LG
657 IncFileProfile.InsertStartLineNumber = InsertAtLine + 1\r
658 # deal with remaining portions after "!include filename", if exists.\r
9e47e6f9 659 if self._GetNextToken():\r
30fdf114 660 if self.CurrentLineNumber == CurrentLine:\r
9e47e6f9 661 RemainingLine = self._CurrentLine()[CurrentOffset:]\r
30fdf114
LG
662 self.Profile.FileLinesList.insert(self.CurrentLineNumber, RemainingLine)\r
663 IncFileProfile.InsertAdjust += 1\r
664 self.CurrentLineNumber += 1\r
665 self.CurrentOffsetWithinLine = 0\r
666\r
667 for Line in IncFileProfile.FileLinesList:\r
668 self.Profile.FileLinesList.insert(InsertAtLine, Line)\r
669 self.CurrentLineNumber += 1\r
670 InsertAtLine += 1\r
671\r
118bf096
CS
672 # reversely sorted to better determine error in file\r
673 AllIncludeFileList.insert(0, IncFileProfile)\r
30fdf114
LG
674\r
675 # comment out the processed include file statement\r
676 TempList = list(self.Profile.FileLinesList[IncludeLine - 1])\r
9e47e6f9 677 TempList.insert(IncludeOffset, TAB_COMMENT_SPLIT)\r
30fdf114 678 self.Profile.FileLinesList[IncludeLine - 1] = ''.join(TempList)\r
118bf096
CS
679 if Processed: # Nested and back-to-back support\r
680 self.Rewind(DestLine = IncFileProfile.InsertStartLineNumber - 1)\r
681 Processed = False\r
682 # Preprocess done.\r
30fdf114 683 self.Rewind()\r
f7496d71 684\r
5bcf1d56 685 @staticmethod\r
9e47e6f9 686 def _GetIfListCurrentItemStat(IfList):\r
da92f276
LG
687 if len(IfList) == 0:\r
688 return True\r
f7496d71 689\r
da92f276
LG
690 for Item in IfList:\r
691 if Item[1] == False:\r
692 return False\r
f7496d71 693\r
da92f276 694 return True\r
f7496d71 695\r
6780eef1 696 ## PreprocessConditionalStatement() method\r
30fdf114 697 #\r
6780eef1 698 # Preprocess conditional statement.\r
30fdf114
LG
699 # In the end, rewind the file buffer pointer to the beginning\r
700 #\r
701 # @param self The object pointer\r
702 #\r
703 def PreprocessConditionalStatement(self):\r
704 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]\r
705 IfList = []\r
0d2711a6 706 RegionLayoutLine = 0\r
d0acc87a 707 ReplacedLine = -1\r
9e47e6f9 708 while self._GetNextToken():\r
d0acc87a 709 # Determine section name and the location dependent macro\r
9e47e6f9
CJ
710 if self._GetIfListCurrentItemStat(IfList):\r
711 if self._Token.startswith(TAB_SECTION_START):\r
712 Header = self._Token\r
713 if not self._Token.endswith(TAB_SECTION_END):\r
714 self._SkipToToken(TAB_SECTION_END)\r
715 Header += self._SkippedChars\r
d0acc87a
LG
716 if Header.find('$(') != -1:\r
717 raise Warning("macro cannot be used in section header", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 718 self._SectionHeaderParser(Header)\r
d0acc87a
LG
719 continue\r
720 # Replace macros except in RULE section or out of section\r
9e47e6f9 721 elif self._CurSection and ReplacedLine != self.CurrentLineNumber:\r
d0acc87a 722 ReplacedLine = self.CurrentLineNumber\r
9e47e6f9 723 self._UndoToken()\r
d0acc87a
LG
724 CurLine = self.Profile.FileLinesList[ReplacedLine - 1]\r
725 PreIndex = 0\r
726 StartPos = CurLine.find('$(', PreIndex)\r
727 EndPos = CurLine.find(')', StartPos+2)\r
5a264f28 728 while StartPos != -1 and EndPos != -1 and self._Token not in {TAB_IF_DEF, TAB_IF_N_DEF, TAB_IF, TAB_ELSE_IF}:\r
9e47e6f9
CJ
729 MacroName = CurLine[StartPos+2: EndPos]\r
730 MacorValue = self._GetMacroValue(MacroName)\r
4231a819 731 if MacorValue is not None:\r
d0acc87a
LG
732 CurLine = CurLine.replace('$(' + MacroName + ')', MacorValue, 1)\r
733 if MacorValue.find('$(') != -1:\r
734 PreIndex = StartPos\r
735 else:\r
736 PreIndex = StartPos + len(MacorValue)\r
737 else:\r
738 PreIndex = EndPos + 1\r
739 StartPos = CurLine.find('$(', PreIndex)\r
740 EndPos = CurLine.find(')', StartPos+2)\r
741 self.Profile.FileLinesList[ReplacedLine - 1] = CurLine\r
742 continue\r
743\r
9e47e6f9
CJ
744 if self._Token == TAB_DEFINE:\r
745 if self._GetIfListCurrentItemStat(IfList):\r
746 if not self._CurSection:\r
d0acc87a 747 raise Warning("macro cannot be defined in Rule section or out of section", self.FileName, self.CurrentLineNumber)\r
da92f276 748 DefineLine = self.CurrentLineNumber - 1\r
9e47e6f9
CJ
749 DefineOffset = self.CurrentOffsetWithinLine - len(TAB_DEFINE)\r
750 if not self._GetNextToken():\r
ca957eb5 751 raise Warning.Expected("Macro name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
752 Macro = self._Token\r
753 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 754 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
f7496d71 755\r
9e47e6f9
CJ
756 Value = self._GetExpression()\r
757 self._SetMacroValue(Macro, Value)\r
758 self._WipeOffArea.append(((DefineLine, DefineOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
759 elif self._Token == 'SET':\r
760 if not self._GetIfListCurrentItemStat(IfList):\r
2f04e527 761 continue\r
64b2609f
LG
762 SetLine = self.CurrentLineNumber - 1\r
763 SetOffset = self.CurrentOffsetWithinLine - len('SET')\r
9e47e6f9 764 PcdPair = self._GetNextPcdSettings()\r
0d2711a6 765 PcdName = "%s.%s" % (PcdPair[1], PcdPair[0])\r
9e47e6f9 766 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 767 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
0d2711a6 768\r
9e47e6f9
CJ
769 Value = self._GetExpression()\r
770 Value = self._EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)\r
30fdf114 771\r
9e47e6f9 772 self._PcdDict[PcdName] = Value\r
64b2609f
LG
773\r
774 self.Profile.PcdDict[PcdPair] = Value\r
543f5ac3 775 self.SetPcdLocalation(PcdPair)\r
64b2609f
LG
776 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
777 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
778\r
9e47e6f9 779 self._WipeOffArea.append(((SetLine, SetOffset), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
5a264f28 780 elif self._Token in {TAB_IF_DEF, TAB_IF_N_DEF, TAB_IF}:\r
9e47e6f9 781 IfStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self._Token))\r
30fdf114 782 IfList.append([IfStartPos, None, None])\r
0d2711a6 783\r
9e47e6f9
CJ
784 CondLabel = self._Token\r
785 Expression = self._GetExpression()\r
f7496d71 786\r
9e47e6f9
CJ
787 if CondLabel == TAB_IF:\r
788 ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')\r
30fdf114 789 else:\r
9e47e6f9
CJ
790 ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'in')\r
791 if CondLabel == TAB_IF_N_DEF:\r
30fdf114 792 ConditionSatisfied = not ConditionSatisfied\r
30fdf114 793\r
0d2711a6
LG
794 BranchDetermined = ConditionSatisfied\r
795 IfList[-1] = [IfList[-1][0], ConditionSatisfied, BranchDetermined]\r
796 if ConditionSatisfied:\r
9e47e6f9 797 self._WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
5a264f28 798 elif self._Token in {TAB_ELSE_IF, TAB_ELSE}:\r
9e47e6f9 799 ElseStartPos = (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len(self._Token))\r
30fdf114
LG
800 if len(IfList) <= 0:\r
801 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)\r
0d2711a6 802\r
30fdf114
LG
803 if IfList[-1][1]:\r
804 IfList[-1] = [ElseStartPos, False, True]\r
9e47e6f9 805 self._WipeOffArea.append((ElseStartPos, (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
30fdf114 806 else:\r
9e47e6f9 807 self._WipeOffArea.append((IfList[-1][0], ElseStartPos))\r
30fdf114 808 IfList[-1] = [ElseStartPos, True, IfList[-1][2]]\r
9e47e6f9
CJ
809 if self._Token == TAB_ELSE_IF:\r
810 Expression = self._GetExpression()\r
811 ConditionSatisfied = self._EvaluateConditional(Expression, IfList[-1][0][0] + 1, 'eval')\r
30fdf114
LG
812 IfList[-1] = [IfList[-1][0], ConditionSatisfied, IfList[-1][2]]\r
813\r
814 if IfList[-1][1]:\r
815 if IfList[-1][2]:\r
816 IfList[-1][1] = False\r
817 else:\r
818 IfList[-1][2] = True\r
9e47e6f9
CJ
819 self._WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
820 elif self._Token == '!endif':\r
d0acc87a
LG
821 if len(IfList) <= 0:\r
822 raise Warning("Missing !if statement", self.FileName, self.CurrentLineNumber)\r
30fdf114 823 if IfList[-1][1]:\r
9e47e6f9 824 self._WipeOffArea.append(((self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - len('!endif')), (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
30fdf114 825 else:\r
9e47e6f9 826 self._WipeOffArea.append((IfList[-1][0], (self.CurrentLineNumber - 1, self.CurrentOffsetWithinLine - 1)))\r
30fdf114
LG
827\r
828 IfList.pop()\r
0d2711a6
LG
829 elif not IfList: # Don't use PCDs inside conditional directive\r
830 if self.CurrentLineNumber <= RegionLayoutLine:\r
831 # Don't try the same line twice\r
832 continue\r
64b2609f
LG
833 SetPcd = ShortcutPcdPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
834 if SetPcd:\r
9e47e6f9 835 self._PcdDict[SetPcd.group('name')] = SetPcd.group('value')\r
64b2609f
LG
836 RegionLayoutLine = self.CurrentLineNumber\r
837 continue\r
0d2711a6
LG
838 RegionSize = RegionSizePattern.match(self.Profile.FileLinesList[self.CurrentLineNumber - 1])\r
839 if not RegionSize:\r
840 RegionLayoutLine = self.CurrentLineNumber\r
841 continue\r
842 RegionSizeGuid = RegionSizeGuidPattern.match(self.Profile.FileLinesList[self.CurrentLineNumber])\r
843 if not RegionSizeGuid:\r
844 RegionLayoutLine = self.CurrentLineNumber + 1\r
845 continue\r
9e47e6f9
CJ
846 self._PcdDict[RegionSizeGuid.group('base')] = RegionSize.group('base')\r
847 self._PcdDict[RegionSizeGuid.group('size')] = RegionSize.group('size')\r
0d2711a6
LG
848 RegionLayoutLine = self.CurrentLineNumber + 1\r
849\r
850 if IfList:\r
30fdf114
LG
851 raise Warning("Missing !endif", self.FileName, self.CurrentLineNumber)\r
852 self.Rewind()\r
853\r
9e47e6f9 854 def _CollectMacroPcd(self):\r
d0acc87a
LG
855 MacroDict = {}\r
856\r
857 # PCD macro\r
64b2609f 858 MacroDict.update(GlobalData.gPlatformPcds)\r
9e47e6f9 859 MacroDict.update(self._PcdDict)\r
d0acc87a
LG
860\r
861 # Lowest priority\r
862 MacroDict.update(GlobalData.gPlatformDefines)\r
863\r
9e47e6f9 864 if self._CurSection:\r
d0acc87a 865 # Defines macro\r
9e47e6f9 866 ScopeMacro = self._MacroDict[TAB_COMMON, TAB_COMMON, TAB_COMMON]\r
d0acc87a
LG
867 if ScopeMacro:\r
868 MacroDict.update(ScopeMacro)\r
f7496d71 869\r
d0acc87a 870 # Section macro\r
9e47e6f9
CJ
871 ScopeMacro = self._MacroDict[\r
872 self._CurSection[0],\r
873 self._CurSection[1],\r
874 self._CurSection[2]\r
d0acc87a
LG
875 ]\r
876 if ScopeMacro:\r
877 MacroDict.update(ScopeMacro)\r
878\r
879 MacroDict.update(GlobalData.gGlobalDefines)\r
880 MacroDict.update(GlobalData.gCommandLineDefines)\r
5a264f28
CJ
881 for Item in GlobalData.BuildOptionPcd:\r
882 if isinstance(Item, tuple):\r
883 continue\r
884 PcdName, TmpValue = Item.split(TAB_EQUAL_SPLIT)\r
885 TmpValue = BuildOptionValue(TmpValue, {})\r
886 MacroDict[PcdName.strip()] = TmpValue\r
d0acc87a
LG
887 # Highest priority\r
888\r
889 return MacroDict\r
890\r
9e47e6f9
CJ
891 def _EvaluateConditional(self, Expression, Line, Op = None, Value = None):\r
892 MacroPcdDict = self._CollectMacroPcd()\r
0d2711a6
LG
893 if Op == 'eval':\r
894 try:\r
d0acc87a
LG
895 if Value:\r
896 return ValueExpression(Expression, MacroPcdDict)(True)\r
897 else:\r
898 return ValueExpression(Expression, MacroPcdDict)()\r
5b0671c1 899 except WrnExpression as Excpt:\r
f7496d71 900 #\r
0d2711a6
LG
901 # Catch expression evaluation warning here. We need to report\r
902 # the precise number of line and return the evaluation result\r
903 #\r
904 EdkLogger.warn('Parser', "Suspicious expression: %s" % str(Excpt),\r
9e47e6f9 905 File=self.FileName, ExtraData=self._CurrentLine(),\r
0d2711a6
LG
906 Line=Line)\r
907 return Excpt.result\r
5b0671c1 908 except Exception as Excpt:\r
64b2609f
LG
909 if hasattr(Excpt, 'Pcd'):\r
910 if Excpt.Pcd in GlobalData.gPlatformOtherPcds:\r
911 Info = GlobalData.gPlatformOtherPcds[Excpt.Pcd]\r
912 raise Warning("Cannot use this PCD (%s) in an expression as"\r
913 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"\r
914 " of the DSC file (%s), and it is currently defined in this section:"\r
915 " %s, line #: %d." % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE'], Info[0], Info[1]),\r
20274d23 916 self.FileName, Line)\r
64b2609f
LG
917 else:\r
918 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt.Pcd, GlobalData.gPlatformOtherPcds['DSCFILE']),\r
20274d23 919 self.FileName, Line)\r
64b2609f 920 else:\r
20274d23 921 raise Warning(str(Excpt), self.FileName, Line)\r
0d2711a6
LG
922 else:\r
923 if Expression.startswith('$(') and Expression[-1] == ')':\r
f7496d71 924 Expression = Expression[2:-1]\r
d0acc87a 925 return Expression in MacroPcdDict\r
30fdf114 926\r
9e47e6f9 927 ## _IsToken() method\r
30fdf114
LG
928 #\r
929 # Check whether input string is found from current char position along\r
9e47e6f9 930 # If found, the string value is put into self._Token\r
30fdf114
LG
931 #\r
932 # @param self The object pointer\r
933 # @param String The string to search\r
934 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
935 # @retval True Successfully find string, file buffer pointer moved forward\r
936 # @retval False Not able to find string, file buffer pointer not changed\r
937 #\r
9e47e6f9
CJ
938 def _IsToken(self, String, IgnoreCase = False):\r
939 self._SkipWhiteSpace()\r
30fdf114
LG
940\r
941 # Only consider the same line, no multi-line token allowed\r
942 StartPos = self.CurrentOffsetWithinLine\r
943 index = -1\r
944 if IgnoreCase:\r
9e47e6f9 945 index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(String.upper())\r
30fdf114 946 else:\r
9e47e6f9 947 index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(String)\r
30fdf114
LG
948 if index == 0:\r
949 self.CurrentOffsetWithinLine += len(String)\r
9e47e6f9 950 self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]\r
30fdf114
LG
951 return True\r
952 return False\r
953\r
9e47e6f9 954 ## _IsKeyword() method\r
30fdf114
LG
955 #\r
956 # Check whether input keyword is found from current char position along, whole word only!\r
9e47e6f9 957 # If found, the string value is put into self._Token\r
30fdf114
LG
958 #\r
959 # @param self The object pointer\r
960 # @param Keyword The string to search\r
961 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
962 # @retval True Successfully find string, file buffer pointer moved forward\r
963 # @retval False Not able to find string, file buffer pointer not changed\r
964 #\r
9e47e6f9
CJ
965 def _IsKeyword(self, KeyWord, IgnoreCase = False):\r
966 self._SkipWhiteSpace()\r
30fdf114
LG
967\r
968 # Only consider the same line, no multi-line token allowed\r
969 StartPos = self.CurrentOffsetWithinLine\r
970 index = -1\r
971 if IgnoreCase:\r
9e47e6f9 972 index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(KeyWord.upper())\r
30fdf114 973 else:\r
9e47e6f9 974 index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(KeyWord)\r
30fdf114 975 if index == 0:\r
9e47e6f9
CJ
976 followingChar = self._CurrentLine()[self.CurrentOffsetWithinLine + len(KeyWord)]\r
977 if not str(followingChar).isspace() and followingChar not in SEPARATORS:\r
30fdf114
LG
978 return False\r
979 self.CurrentOffsetWithinLine += len(KeyWord)\r
9e47e6f9 980 self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]\r
30fdf114
LG
981 return True\r
982 return False\r
983\r
9e47e6f9 984 def _GetExpression(self):\r
0d2711a6
LG
985 Line = self.Profile.FileLinesList[self.CurrentLineNumber - 1]\r
986 Index = len(Line) - 1\r
5a264f28 987 while Line[Index] in CR_LB_SET:\r
0d2711a6
LG
988 Index -= 1\r
989 ExpressionString = self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:Index+1]\r
990 self.CurrentOffsetWithinLine += len(ExpressionString)\r
991 ExpressionString = ExpressionString.strip()\r
992 return ExpressionString\r
993\r
9e47e6f9 994 ## _GetNextWord() method\r
30fdf114
LG
995 #\r
996 # Get next C name from file lines\r
9e47e6f9 997 # If found, the string value is put into self._Token\r
30fdf114
LG
998 #\r
999 # @param self The object pointer\r
1000 # @retval True Successfully find a C name string, file buffer pointer moved forward\r
1001 # @retval False Not able to find a C name string, file buffer pointer not changed\r
1002 #\r
9e47e6f9
CJ
1003 def _GetNextWord(self):\r
1004 self._SkipWhiteSpace()\r
1005 if self._EndOfFile():\r
30fdf114
LG
1006 return False\r
1007\r
9e47e6f9 1008 TempChar = self._CurrentChar()\r
30fdf114
LG
1009 StartPos = self.CurrentOffsetWithinLine\r
1010 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_':\r
9e47e6f9
CJ
1011 self._GetOneChar()\r
1012 while not self._EndOfLine():\r
1013 TempChar = self._CurrentChar()\r
30fdf114
LG
1014 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \\r
1015 or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-':\r
9e47e6f9 1016 self._GetOneChar()\r
30fdf114
LG
1017\r
1018 else:\r
1019 break\r
1020\r
9e47e6f9 1021 self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]\r
30fdf114
LG
1022 return True\r
1023\r
1024 return False\r
1025\r
9e47e6f9
CJ
1026 def _GetNextPcdWord(self):\r
1027 self._SkipWhiteSpace()\r
1028 if self._EndOfFile():\r
543f5ac3
B
1029 return False\r
1030\r
9e47e6f9 1031 TempChar = self._CurrentChar()\r
543f5ac3 1032 StartPos = self.CurrentOffsetWithinLine\r
9e47e6f9
CJ
1033 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') or TempChar == '_' or TempChar == TAB_SECTION_START or TempChar == TAB_SECTION_END:\r
1034 self._GetOneChar()\r
1035 while not self._EndOfLine():\r
1036 TempChar = self._CurrentChar()\r
543f5ac3 1037 if (TempChar >= 'a' and TempChar <= 'z') or (TempChar >= 'A' and TempChar <= 'Z') \\r
9e47e6f9
CJ
1038 or (TempChar >= '0' and TempChar <= '9') or TempChar == '_' or TempChar == '-' or TempChar == TAB_SECTION_START or TempChar == TAB_SECTION_END:\r
1039 self._GetOneChar()\r
543f5ac3
B
1040\r
1041 else:\r
1042 break\r
1043\r
9e47e6f9 1044 self._Token = self._CurrentLine()[StartPos: self.CurrentOffsetWithinLine]\r
543f5ac3
B
1045 return True\r
1046\r
1047 return False\r
1048\r
9e47e6f9 1049 ## _GetNextToken() method\r
30fdf114
LG
1050 #\r
1051 # Get next token unit before a seperator\r
9e47e6f9 1052 # If found, the string value is put into self._Token\r
30fdf114
LG
1053 #\r
1054 # @param self The object pointer\r
1055 # @retval True Successfully find a token unit, file buffer pointer moved forward\r
1056 # @retval False Not able to find a token unit, file buffer pointer not changed\r
1057 #\r
9e47e6f9 1058 def _GetNextToken(self):\r
30fdf114 1059 # Skip leading spaces, if exist.\r
9e47e6f9
CJ
1060 self._SkipWhiteSpace()\r
1061 if self._EndOfFile():\r
30fdf114
LG
1062 return False\r
1063 # Record the token start position, the position of the first non-space char.\r
1064 StartPos = self.CurrentOffsetWithinLine\r
1065 StartLine = self.CurrentLineNumber\r
d0acc87a 1066 while StartLine == self.CurrentLineNumber:\r
9e47e6f9 1067 TempChar = self._CurrentChar()\r
30fdf114
LG
1068 # Try to find the end char that is not a space and not in seperator tuple.\r
1069 # That is, when we got a space or any char in the tuple, we got the end of token.\r
9e47e6f9
CJ
1070 if not str(TempChar).isspace() and TempChar not in SEPARATORS:\r
1071 self._GetOneChar()\r
30fdf114
LG
1072 # if we happen to meet a seperator as the first char, we must proceed to get it.\r
1073 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.\r
9e47e6f9
CJ
1074 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPARATORS:\r
1075 self._GetOneChar()\r
30fdf114
LG
1076 break\r
1077 else:\r
1078 break\r
1079# else:\r
1080# return False\r
1081\r
1082 EndPos = self.CurrentOffsetWithinLine\r
1083 if self.CurrentLineNumber != StartLine:\r
1084 EndPos = len(self.Profile.FileLinesList[StartLine-1])\r
9e47e6f9 1085 self._Token = self.Profile.FileLinesList[StartLine-1][StartPos: EndPos]\r
5a264f28 1086 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}:\r
9e47e6f9 1087 self._Token = self._Token.lower()\r
30fdf114
LG
1088 if StartPos != self.CurrentOffsetWithinLine:\r
1089 return True\r
1090 else:\r
1091 return False\r
1092\r
9e47e6f9 1093 ## _GetNextGuid() method\r
30fdf114
LG
1094 #\r
1095 # Get next token unit before a seperator\r
9e47e6f9 1096 # If found, the GUID string is put into self._Token\r
30fdf114
LG
1097 #\r
1098 # @param self The object pointer\r
1099 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward\r
1100 # @retval False Not able to find a registry format GUID, file buffer pointer not changed\r
1101 #\r
9e47e6f9
CJ
1102 def _GetNextGuid(self):\r
1103 if not self._GetNextToken():\r
30fdf114 1104 return False\r
9e47e6f9 1105 if gGuidPattern.match(self._Token) is not None:\r
30fdf114
LG
1106 return True\r
1107 else:\r
9e47e6f9 1108 self._UndoToken()\r
30fdf114
LG
1109 return False\r
1110\r
227dbb11 1111 @staticmethod\r
9e47e6f9 1112 def _Verify(Name, Value, Scope):\r
bff74750 1113 # value verification only applies to numeric values.\r
053cd183 1114 if Scope not in TAB_PCD_NUMERIC_TYPES:\r
bff74750
CJ
1115 return\r
1116\r
1117 ValueNumber = 0\r
1118 try:\r
1119 ValueNumber = int(Value, 0)\r
1120 except:\r
1121 EdkLogger.error("FdfParser", FORMAT_INVALID, "The value is not valid dec or hex number for %s." % Name)\r
1122 if ValueNumber < 0:\r
1123 EdkLogger.error("FdfParser", FORMAT_INVALID, "The value can't be set to negative value for %s." % Name)\r
1124 if ValueNumber > MAX_VAL_TYPE[Scope]:\r
1125 EdkLogger.error("FdfParser", FORMAT_INVALID, "Too large value for %s." % Name)\r
1126 return True\r
91ae2988 1127\r
9e47e6f9 1128 ## _UndoToken() method\r
30fdf114
LG
1129 #\r
1130 # Go back one token unit in file buffer\r
1131 #\r
1132 # @param self The object pointer\r
1133 #\r
9e47e6f9
CJ
1134 def _UndoToken(self):\r
1135 self._UndoOneChar()\r
1136 while self._CurrentChar().isspace():\r
1137 if not self._UndoOneChar():\r
1138 self._GetOneChar()\r
30fdf114
LG
1139 return\r
1140\r
1141\r
1142 StartPos = self.CurrentOffsetWithinLine\r
1143 CurrentLine = self.CurrentLineNumber\r
1144 while CurrentLine == self.CurrentLineNumber:\r
1145\r
9e47e6f9 1146 TempChar = self._CurrentChar()\r
30fdf114
LG
1147 # Try to find the end char that is not a space and not in seperator tuple.\r
1148 # That is, when we got a space or any char in the tuple, we got the end of token.\r
9e47e6f9
CJ
1149 if not str(TempChar).isspace() and not TempChar in SEPARATORS:\r
1150 if not self._UndoOneChar():\r
d0acc87a 1151 return\r
30fdf114
LG
1152 # if we happen to meet a seperator as the first char, we must proceed to get it.\r
1153 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.\r
9e47e6f9 1154 elif StartPos == self.CurrentOffsetWithinLine and TempChar in SEPARATORS:\r
30fdf114
LG
1155 return\r
1156 else:\r
1157 break\r
1158\r
9e47e6f9 1159 self._GetOneChar()\r
30fdf114 1160\r
9e47e6f9 1161 ## _GetNextHexNumber() method\r
30fdf114
LG
1162 #\r
1163 # Get next HEX data before a seperator\r
9e47e6f9 1164 # If found, the HEX data is put into self._Token\r
30fdf114
LG
1165 #\r
1166 # @param self The object pointer\r
1167 # @retval True Successfully find a HEX data, file buffer pointer moved forward\r
1168 # @retval False Not able to find a HEX data, file buffer pointer not changed\r
1169 #\r
9e47e6f9
CJ
1170 def _GetNextHexNumber(self):\r
1171 if not self._GetNextToken():\r
30fdf114 1172 return False\r
9e47e6f9 1173 if gHexPatternAll.match(self._Token):\r
30fdf114
LG
1174 return True\r
1175 else:\r
9e47e6f9 1176 self._UndoToken()\r
30fdf114
LG
1177 return False\r
1178\r
9e47e6f9 1179 ## _GetNextDecimalNumber() method\r
30fdf114
LG
1180 #\r
1181 # Get next decimal data before a seperator\r
9e47e6f9 1182 # If found, the decimal data is put into self._Token\r
30fdf114
LG
1183 #\r
1184 # @param self The object pointer\r
1185 # @retval True Successfully find a decimal data, file buffer pointer moved forward\r
1186 # @retval False Not able to find a decimal data, file buffer pointer not changed\r
1187 #\r
9e47e6f9
CJ
1188 def _GetNextDecimalNumber(self):\r
1189 if not self._GetNextToken():\r
30fdf114 1190 return False\r
9e47e6f9 1191 if self._Token.isdigit():\r
30fdf114
LG
1192 return True\r
1193 else:\r
9e47e6f9 1194 self._UndoToken()\r
30fdf114
LG
1195 return False\r
1196\r
9e47e6f9
CJ
1197 def _GetNextPcdSettings(self):\r
1198 if not self._GetNextWord():\r
ca957eb5 1199 raise Warning.Expected("<PcdTokenSpaceCName>", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 1200 pcdTokenSpaceCName = self._Token\r
543f5ac3 1201\r
9e47e6f9 1202 if not self._IsToken(TAB_SPLIT):\r
ca957eb5 1203 raise Warning.Expected(".", self.FileName, self.CurrentLineNumber)\r
543f5ac3 1204\r
9e47e6f9 1205 if not self._GetNextWord():\r
ca957eb5 1206 raise Warning.Expected("<PcdCName>", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 1207 pcdCName = self._Token\r
543f5ac3
B
1208\r
1209 Fields = []\r
9e47e6f9
CJ
1210 while self._IsToken(TAB_SPLIT):\r
1211 if not self._GetNextPcdWord():\r
ca957eb5 1212 raise Warning.Expected("Pcd Fields", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 1213 Fields.append(self._Token)\r
543f5ac3 1214\r
9e47e6f9 1215 return (pcdCName, pcdTokenSpaceCName,TAB_SPLIT.join(Fields))\r
543f5ac3 1216\r
9e47e6f9 1217 ## _GetStringData() method\r
30fdf114
LG
1218 #\r
1219 # Get string contents quoted in ""\r
9e47e6f9 1220 # If found, the decimal data is put into self._Token\r
30fdf114
LG
1221 #\r
1222 # @param self The object pointer\r
1223 # @retval True Successfully find a string data, file buffer pointer moved forward\r
1224 # @retval False Not able to find a string data, file buffer pointer not changed\r
1225 #\r
9e47e6f9 1226 def _GetStringData(self):\r
ca957eb5 1227 QuoteToUse = None\r
9e47e6f9 1228 if self._Token.startswith(T_CHAR_DOUBLE_QUOTE) or self._Token.startswith("L\""):\r
ca957eb5 1229 QuoteToUse = T_CHAR_DOUBLE_QUOTE\r
9e47e6f9 1230 elif self._Token.startswith(T_CHAR_SINGLE_QUOTE) or self._Token.startswith("L\'"):\r
ca957eb5 1231 QuoteToUse = T_CHAR_SINGLE_QUOTE\r
30fdf114
LG
1232 else:\r
1233 return False\r
1234\r
ca957eb5
CJ
1235 self._UndoToken()\r
1236 self._SkipToToken(QuoteToUse)\r
1237 currentLineNumber = self.CurrentLineNumber\r
1238\r
1239 if not self._SkipToToken(QuoteToUse):\r
1240 raise Warning(QuoteToUse, self.FileName, self.CurrentLineNumber)\r
1241 if currentLineNumber != self.CurrentLineNumber:\r
1242 raise Warning(QuoteToUse, self.FileName, self.CurrentLineNumber)\r
1243 self._Token = self._SkippedChars.rstrip(QuoteToUse)\r
1244 return True\r
1245\r
9e47e6f9 1246 ## _SkipToToken() method\r
30fdf114
LG
1247 #\r
1248 # Search forward in file buffer for the string\r
9e47e6f9 1249 # The skipped chars are put into self._SkippedChars\r
30fdf114
LG
1250 #\r
1251 # @param self The object pointer\r
1252 # @param String The string to search\r
1253 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive\r
1254 # @retval True Successfully find the string, file buffer pointer moved forward\r
1255 # @retval False Not able to find the string, file buffer pointer not changed\r
1256 #\r
9e47e6f9 1257 def _SkipToToken(self, String, IgnoreCase = False):\r
30fdf114
LG
1258 StartPos = self.GetFileBufferPos()\r
1259\r
9e47e6f9
CJ
1260 self._SkippedChars = ""\r
1261 while not self._EndOfFile():\r
30fdf114
LG
1262 index = -1\r
1263 if IgnoreCase:\r
9e47e6f9 1264 index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].upper().find(String.upper())\r
30fdf114 1265 else:\r
9e47e6f9 1266 index = self._CurrentLine()[self.CurrentOffsetWithinLine: ].find(String)\r
30fdf114
LG
1267 if index == 0:\r
1268 self.CurrentOffsetWithinLine += len(String)\r
9e47e6f9 1269 self._SkippedChars += String\r
30fdf114 1270 return True\r
9e47e6f9
CJ
1271 self._SkippedChars += str(self._CurrentChar())\r
1272 self._GetOneChar()\r
30fdf114 1273\r
9e47e6f9
CJ
1274 self.SetFileBufferPos(StartPos)\r
1275 self._SkippedChars = ""\r
30fdf114
LG
1276 return False\r
1277\r
1278 ## GetFileBufferPos() method\r
1279 #\r
1280 # Return the tuple of current line and offset within the line\r
1281 #\r
1282 # @param self The object pointer\r
1283 # @retval Tuple Line number and offset pair\r
1284 #\r
1285 def GetFileBufferPos(self):\r
1286 return (self.CurrentLineNumber, self.CurrentOffsetWithinLine)\r
1287\r
1288 ## SetFileBufferPos() method\r
1289 #\r
1290 # Restore the file buffer position\r
1291 #\r
1292 # @param self The object pointer\r
1293 # @param Pos The new file buffer position\r
1294 #\r
1295 def SetFileBufferPos(self, Pos):\r
1296 (self.CurrentLineNumber, self.CurrentOffsetWithinLine) = Pos\r
1297\r
d40b2ee6
LG
1298 ## Preprocess() method\r
1299 #\r
1300 # Preprocess comment, conditional directive, include directive, replace macro.\r
1301 # Exception will be raised if syntax error found\r
1302 #\r
1303 # @param self The object pointer\r
1304 #\r
1305 def Preprocess(self):\r
9e47e6f9 1306 self._StringToList()\r
d40b2ee6
LG
1307 self.PreprocessFile()\r
1308 self.PreprocessIncludeFile()\r
9e47e6f9 1309 self._StringToList()\r
d40b2ee6
LG
1310 self.PreprocessFile()\r
1311 self.PreprocessConditionalStatement()\r
9e47e6f9
CJ
1312 self._StringToList()\r
1313 for Pos in self._WipeOffArea:\r
1314 self._ReplaceFragment(Pos[0], Pos[1])\r
d40b2ee6
LG
1315 self.Profile.FileLinesList = ["".join(list) for list in self.Profile.FileLinesList]\r
1316\r
9e47e6f9 1317 while self._GetDefines():\r
d40b2ee6 1318 pass\r
d40b2ee6 1319\r
30fdf114
LG
1320 ## ParseFile() method\r
1321 #\r
1322 # Parse the file profile buffer to extract fd, fv ... information\r
1323 # Exception will be raised if syntax error found\r
1324 #\r
1325 # @param self The object pointer\r
1326 #\r
1327 def ParseFile(self):\r
30fdf114 1328 try:\r
d40b2ee6 1329 self.Preprocess()\r
9e47e6f9 1330 self._GetError()\r
dd170333
MK
1331 #\r
1332 # Keep processing sections of the FDF until no new sections or a syntax error is found\r
1333 #\r
9e47e6f9 1334 while self._GetFd() or self._GetFv() or self._GetFmp() or self._GetCapsule() or self._GetVtf() or self._GetRule() or self._GetOptionRom():\r
30fdf114
LG
1335 pass\r
1336\r
5b0671c1 1337 except Warning as X:\r
9e47e6f9
CJ
1338 self._UndoToken()\r
1339 #'\n\tGot Token: \"%s\" from File %s\n' % (self._Token, FileLineTuple[0]) + \\r
118bf096
CS
1340 # At this point, the closest parent would be the included file itself\r
1341 Profile = GetParentAtLine(X.OriginalLineNumber)\r
4231a819 1342 if Profile is not None:\r
118bf096
CS
1343 X.Message += ' near line %d, column %d: %s' \\r
1344 % (X.LineNumber, 0, Profile.FileLinesList[X.LineNumber-1])\r
1345 else:\r
1346 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1347 X.Message += ' near line %d, column %d: %s' \\r
9e47e6f9 1348 % (FileLineTuple[1], self.CurrentOffsetWithinLine + 1, self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:].rstrip(TAB_LINE_BREAK).rstrip(T_CHAR_CR))\r
30fdf114
LG
1349 raise\r
1350\r
df81077f
YZ
1351 ## SectionParser() method\r
1352 #\r
1353 # Parse the file section info\r
1354 # Exception will be raised if syntax error found\r
1355 #\r
1356 # @param self The object pointer\r
1357 # @param section The section string\r
1358\r
1359 def SectionParser(self, section):\r
1360 S = section.upper()\r
1361 if not S.startswith("[DEFINES") and not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \\r
1362 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM.") and not S.startswith('[FMPPAYLOAD.'):\r
1363 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self.FileName, self.CurrentLineNumber)\r
1364\r
9e47e6f9 1365 ## _GetDefines() method\r
30fdf114
LG
1366 #\r
1367 # Get Defines section contents and store its data into AllMacrosList\r
1368 #\r
1369 # @param self The object pointer\r
1370 # @retval True Successfully find a Defines\r
1371 # @retval False Not able to find a Defines\r
1372 #\r
9e47e6f9
CJ
1373 def _GetDefines(self):\r
1374 if not self._GetNextToken():\r
30fdf114
LG
1375 return False\r
1376\r
9e47e6f9
CJ
1377 S = self._Token.upper()\r
1378 if S.startswith(TAB_SECTION_START) and not S.startswith("[DEFINES"):\r
df81077f 1379 self.SectionParser(S)\r
9e47e6f9 1380 self._UndoToken()\r
30fdf114
LG
1381 return False\r
1382\r
9e47e6f9
CJ
1383 self._UndoToken()\r
1384 if not self._IsToken("[DEFINES", True):\r
30fdf114
LG
1385 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1386 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9 1387 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
ca957eb5 1388 raise Warning.Expected("[DEFINES", self.FileName, self.CurrentLineNumber)\r
30fdf114 1389\r
9e47e6f9 1390 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 1391 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 1392\r
9e47e6f9 1393 while self._GetNextWord():\r
6780eef1 1394 # handle the SET statement\r
9e47e6f9
CJ
1395 if self._Token == 'SET':\r
1396 self._UndoToken()\r
1397 self._GetSetStatement(None)\r
6780eef1 1398 continue\r
f7496d71 1399\r
9e47e6f9 1400 Macro = self._Token\r
f7496d71 1401\r
9e47e6f9 1402 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1403 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 1404 if not self._GetNextToken() or self._Token.startswith(TAB_SECTION_START):\r
ca957eb5 1405 raise Warning.Expected("MACRO value", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 1406 Value = self._Token\r
30fdf114
LG
1407\r
1408 return False\r
1409\r
9e47e6f9
CJ
1410 ##_GetError() method\r
1411 def _GetError(self):\r
09ef8e92
YF
1412 #save the Current information\r
1413 CurrentLine = self.CurrentLineNumber\r
1414 CurrentOffset = self.CurrentOffsetWithinLine\r
9e47e6f9
CJ
1415 while self._GetNextToken():\r
1416 if self._Token == TAB_ERROR:\r
1417 EdkLogger.error('FdfParser', ERROR_STATEMENT, self._CurrentLine().replace(TAB_ERROR, '', 1), File=self.FileName, Line=self.CurrentLineNumber)\r
09ef8e92
YF
1418 self.CurrentLineNumber = CurrentLine\r
1419 self.CurrentOffsetWithinLine = CurrentOffset\r
1420\r
9e47e6f9 1421 ## _GetFd() method\r
30fdf114
LG
1422 #\r
1423 # Get FD section contents and store its data into FD dictionary of self.Profile\r
1424 #\r
1425 # @param self The object pointer\r
1426 # @retval True Successfully find a FD\r
1427 # @retval False Not able to find a FD\r
1428 #\r
9e47e6f9
CJ
1429 def _GetFd(self):\r
1430 if not self._GetNextToken():\r
30fdf114
LG
1431 return False\r
1432\r
9e47e6f9
CJ
1433 S = self._Token.upper()\r
1434 if S.startswith(TAB_SECTION_START) and not S.startswith("[FD."):\r
a3251d84 1435 if not S.startswith("[FV.") and not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \\r
30fdf114
LG
1436 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):\r
1437 raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 1438 self._UndoToken()\r
30fdf114
LG
1439 return False\r
1440\r
9e47e6f9
CJ
1441 self._UndoToken()\r
1442 if not self._IsToken("[FD.", True):\r
30fdf114
LG
1443 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1444 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9 1445 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
ca957eb5 1446 raise Warning.Expected("[FD.]", self.FileName, self.CurrentLineNumber)\r
30fdf114 1447\r
9e47e6f9 1448 FdName = self._GetUiName()\r
52302d4d
LG
1449 if FdName == "":\r
1450 if len (self.Profile.FdDict) == 0:\r
1451 FdName = GenFdsGlobalVariable.PlatformName\r
d0acc87a
LG
1452 if FdName == "" and GlobalData.gActivePlatform:\r
1453 FdName = GlobalData.gActivePlatform.PlatformName\r
52302d4d
LG
1454 self.Profile.FdNameNotSet = True\r
1455 else:\r
ca957eb5 1456 raise Warning.Expected("FdName in [FD.] section", self.FileName, self.CurrentLineNumber)\r
30fdf114 1457 self.CurrentFdName = FdName.upper()\r
f7496d71 1458\r
52302d4d
LG
1459 if self.CurrentFdName in self.Profile.FdDict:\r
1460 raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber)\r
30fdf114 1461\r
9e47e6f9 1462 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 1463 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 1464\r
9e47e6f9 1465 FdObj = FD()\r
30fdf114
LG
1466 FdObj.FdUiName = self.CurrentFdName\r
1467 self.Profile.FdDict[self.CurrentFdName] = FdObj\r
52302d4d
LG
1468\r
1469 if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet:\r
ca957eb5 1470 raise Warning.Expected("all FDs have their name", self.FileName, self.CurrentLineNumber)\r
52302d4d 1471\r
9e47e6f9 1472 Status = self._GetCreateFile(FdObj)\r
30fdf114
LG
1473 if not Status:\r
1474 raise Warning("FD name error", self.FileName, self.CurrentLineNumber)\r
1475\r
9e47e6f9 1476 while self._GetTokenStatements(FdObj):\r
e8a47801
LG
1477 pass\r
1478 for Attr in ("BaseAddress", "Size", "ErasePolarity"):\r
4231a819 1479 if getattr(FdObj, Attr) is None:\r
9e47e6f9 1480 self._GetNextToken()\r
e8a47801
LG
1481 raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber)\r
1482\r
1483 if not FdObj.BlockSizeList:\r
1484 FdObj.BlockSizeList.append((1, FdObj.Size, None))\r
30fdf114 1485\r
9e47e6f9 1486 self._GetDefineStatements(FdObj)\r
30fdf114 1487\r
9e47e6f9 1488 self._GetSetStatements(FdObj)\r
30fdf114 1489\r
9e47e6f9 1490 if not self._GetRegionLayout(FdObj):\r
ca957eb5 1491 raise Warning.Expected("region layout", self.FileName, self.CurrentLineNumber)\r
30fdf114 1492\r
9e47e6f9 1493 while self._GetRegionLayout(FdObj):\r
30fdf114
LG
1494 pass\r
1495 return True\r
1496\r
9e47e6f9 1497 ## _GetUiName() method\r
30fdf114
LG
1498 #\r
1499 # Return the UI name of a section\r
1500 #\r
1501 # @param self The object pointer\r
1502 # @retval FdName UI name\r
1503 #\r
9e47e6f9 1504 def _GetUiName(self):\r
30fdf114 1505 Name = ""\r
9e47e6f9
CJ
1506 if self._GetNextWord():\r
1507 Name = self._Token\r
30fdf114
LG
1508\r
1509 return Name\r
1510\r
9e47e6f9 1511 ## _GetCreateFile() method\r
30fdf114
LG
1512 #\r
1513 # Return the output file name of object\r
1514 #\r
1515 # @param self The object pointer\r
1516 # @param Obj object whose data will be stored in file\r
1517 # @retval FdName UI name\r
1518 #\r
9e47e6f9
CJ
1519 def _GetCreateFile(self, Obj):\r
1520 if self._IsKeyword("CREATE_FILE"):\r
1521 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1522 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1523\r
9e47e6f9 1524 if not self._GetNextToken():\r
ca957eb5 1525 raise Warning.Expected("file name", self.FileName, self.CurrentLineNumber)\r
30fdf114 1526\r
9e47e6f9 1527 FileName = self._Token\r
30fdf114
LG
1528 Obj.CreateFileName = FileName\r
1529\r
1530 return True\r
1531\r
543f5ac3
B
1532 def SetPcdLocalation(self,pcdpair):\r
1533 self.Profile.PcdLocalDict[pcdpair] = (self.Profile.FileName,self.CurrentLineNumber)\r
1534\r
9e47e6f9 1535 ## _GetTokenStatements() method\r
30fdf114
LG
1536 #\r
1537 # Get token statements\r
1538 #\r
1539 # @param self The object pointer\r
1540 # @param Obj for whom token statement is got\r
30fdf114 1541 #\r
9e47e6f9
CJ
1542 def _GetTokenStatements(self, Obj):\r
1543 if self._IsKeyword("BaseAddress"):\r
1544 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1545 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
f7496d71 1546\r
9e47e6f9 1547 if not self._GetNextHexNumber():\r
ca957eb5 1548 raise Warning.Expected("Hex base address", self.FileName, self.CurrentLineNumber)\r
f7496d71 1549\r
9e47e6f9 1550 Obj.BaseAddress = self._Token\r
f7496d71 1551\r
9e47e6f9
CJ
1552 if self._IsToken(TAB_VALUE_SPLIT):\r
1553 pcdPair = self._GetNextPcdSettings()\r
e8a47801
LG
1554 Obj.BaseAddressPcd = pcdPair\r
1555 self.Profile.PcdDict[pcdPair] = Obj.BaseAddress\r
543f5ac3 1556 self.SetPcdLocalation(pcdPair)\r
e8a47801
LG
1557 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1558 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple\r
1559 return True\r
30fdf114 1560\r
9e47e6f9
CJ
1561 if self._IsKeyword("Size"):\r
1562 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1563 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
f7496d71 1564\r
9e47e6f9 1565 if not self._GetNextHexNumber():\r
ca957eb5 1566 raise Warning.Expected("Hex size", self.FileName, self.CurrentLineNumber)\r
30fdf114 1567\r
9e47e6f9
CJ
1568 Size = self._Token\r
1569 if self._IsToken(TAB_VALUE_SPLIT):\r
1570 pcdPair = self._GetNextPcdSettings()\r
e8a47801
LG
1571 Obj.SizePcd = pcdPair\r
1572 self.Profile.PcdDict[pcdPair] = Size\r
543f5ac3 1573 self.SetPcdLocalation(pcdPair)\r
e8a47801
LG
1574 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1575 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple\r
1ccc4d89 1576 Obj.Size = long(Size, 0)\r
e8a47801 1577 return True\r
30fdf114 1578\r
9e47e6f9
CJ
1579 if self._IsKeyword("ErasePolarity"):\r
1580 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1581 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
f7496d71 1582\r
9e47e6f9 1583 if not self._GetNextToken():\r
ca957eb5 1584 raise Warning.Expected("Erase Polarity", self.FileName, self.CurrentLineNumber)\r
f7496d71 1585\r
ca957eb5
CJ
1586 if not self._Token in {"1", "0"}:\r
1587 raise Warning.Expected("1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)\r
f7496d71 1588\r
9e47e6f9 1589 Obj.ErasePolarity = self._Token\r
e8a47801 1590 return True\r
30fdf114 1591\r
9e47e6f9 1592 return self._GetBlockStatements(Obj)\r
30fdf114 1593\r
9e47e6f9 1594 ## _GetAddressStatements() method\r
30fdf114
LG
1595 #\r
1596 # Get address statements\r
1597 #\r
1598 # @param self The object pointer\r
1599 # @param Obj for whom address statement is got\r
1600 # @retval True Successfully find\r
1601 # @retval False Not able to find\r
1602 #\r
9e47e6f9
CJ
1603 def _GetAddressStatements(self, Obj):\r
1604 if self._IsKeyword("BsBaseAddress"):\r
1605 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1606 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1607\r
9e47e6f9 1608 if not self._GetNextDecimalNumber() and not self._GetNextHexNumber():\r
ca957eb5 1609 raise Warning.Expected("address", self.FileName, self.CurrentLineNumber)\r
30fdf114 1610\r
9e47e6f9 1611 BsAddress = long(self._Token, 0)\r
30fdf114
LG
1612 Obj.BsBaseAddress = BsAddress\r
1613\r
9e47e6f9
CJ
1614 if self._IsKeyword("RtBaseAddress"):\r
1615 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1616 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1617\r
9e47e6f9 1618 if not self._GetNextDecimalNumber() and not self._GetNextHexNumber():\r
ca957eb5 1619 raise Warning.Expected("address", self.FileName, self.CurrentLineNumber)\r
30fdf114 1620\r
9e47e6f9 1621 RtAddress = long(self._Token, 0)\r
30fdf114
LG
1622 Obj.RtBaseAddress = RtAddress\r
1623\r
9e47e6f9 1624 ## _GetBlockStatements() method\r
30fdf114
LG
1625 #\r
1626 # Get block statements\r
1627 #\r
1628 # @param self The object pointer\r
1629 # @param Obj for whom block statement is got\r
30fdf114 1630 #\r
9e47e6f9 1631 def _GetBlockStatements(self, Obj):\r
e8a47801 1632 IsBlock = False\r
9e47e6f9 1633 while self._GetBlockStatement(Obj):\r
e8a47801 1634 IsBlock = True\r
f7496d71 1635\r
e8a47801 1636 Item = Obj.BlockSizeList[-1]\r
4231a819 1637 if Item[0] is None or Item[1] is None:\r
ca957eb5 1638 raise Warning.Expected("block statement", self.FileName, self.CurrentLineNumber)\r
e8a47801 1639 return IsBlock\r
30fdf114 1640\r
9e47e6f9 1641 ## _GetBlockStatement() method\r
30fdf114
LG
1642 #\r
1643 # Get block statement\r
1644 #\r
1645 # @param self The object pointer\r
1646 # @param Obj for whom block statement is got\r
1647 # @retval True Successfully find\r
1648 # @retval False Not able to find\r
1649 #\r
9e47e6f9
CJ
1650 def _GetBlockStatement(self, Obj):\r
1651 if not self._IsKeyword("BlockSize"):\r
30fdf114
LG
1652 return False\r
1653\r
9e47e6f9 1654 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1655 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1656\r
9e47e6f9 1657 if not self._GetNextHexNumber() and not self._GetNextDecimalNumber():\r
ca957eb5 1658 raise Warning.Expected("Hex or Integer block size", self.FileName, self.CurrentLineNumber)\r
30fdf114 1659\r
9e47e6f9 1660 BlockSize = self._Token\r
30fdf114 1661 BlockSizePcd = None\r
9e47e6f9
CJ
1662 if self._IsToken(TAB_VALUE_SPLIT):\r
1663 PcdPair = self._GetNextPcdSettings()\r
30fdf114
LG
1664 BlockSizePcd = PcdPair\r
1665 self.Profile.PcdDict[PcdPair] = BlockSize\r
543f5ac3 1666 self.SetPcdLocalation(PcdPair)\r
d0acc87a
LG
1667 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1668 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
1ccc4d89 1669 BlockSize = long(BlockSize, 0)\r
30fdf114
LG
1670\r
1671 BlockNumber = None\r
9e47e6f9
CJ
1672 if self._IsKeyword("NumBlocks"):\r
1673 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1674 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1675\r
9e47e6f9 1676 if not self._GetNextDecimalNumber() and not self._GetNextHexNumber():\r
ca957eb5 1677 raise Warning.Expected("block numbers", self.FileName, self.CurrentLineNumber)\r
30fdf114 1678\r
9e47e6f9 1679 BlockNumber = long(self._Token, 0)\r
30fdf114
LG
1680\r
1681 Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))\r
1682 return True\r
1683\r
9e47e6f9 1684 ## _GetDefineStatements() method\r
30fdf114
LG
1685 #\r
1686 # Get define statements\r
1687 #\r
1688 # @param self The object pointer\r
1689 # @param Obj for whom define statement is got\r
1690 # @retval True Successfully find\r
1691 # @retval False Not able to find\r
1692 #\r
9e47e6f9
CJ
1693 def _GetDefineStatements(self, Obj):\r
1694 while self._GetDefineStatement(Obj):\r
30fdf114
LG
1695 pass\r
1696\r
9e47e6f9 1697 ## _GetDefineStatement() method\r
30fdf114
LG
1698 #\r
1699 # Get define statement\r
1700 #\r
1701 # @param self The object pointer\r
1702 # @param Obj for whom define statement is got\r
1703 # @retval True Successfully find\r
1704 # @retval False Not able to find\r
1705 #\r
9e47e6f9
CJ
1706 def _GetDefineStatement(self, Obj):\r
1707 if self._IsKeyword(TAB_DEFINE):\r
1708 self._GetNextToken()\r
1709 Macro = self._Token\r
1710 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1711 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1712\r
9e47e6f9 1713 if not self._GetNextToken():\r
ca957eb5 1714 raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)\r
30fdf114 1715\r
9e47e6f9 1716 Value = self._Token\r
30fdf114
LG
1717 Macro = '$(' + Macro + ')'\r
1718 Obj.DefineVarDict[Macro] = Value\r
1719 return True\r
1720\r
1721 return False\r
1722\r
9e47e6f9 1723 ## _GetSetStatements() method\r
30fdf114
LG
1724 #\r
1725 # Get set statements\r
1726 #\r
1727 # @param self The object pointer\r
1728 # @param Obj for whom set statement is got\r
1729 # @retval True Successfully find\r
1730 # @retval False Not able to find\r
1731 #\r
9e47e6f9
CJ
1732 def _GetSetStatements(self, Obj):\r
1733 while self._GetSetStatement(Obj):\r
30fdf114
LG
1734 pass\r
1735\r
9e47e6f9 1736 ## _GetSetStatement() method\r
30fdf114
LG
1737 #\r
1738 # Get set statement\r
1739 #\r
1740 # @param self The object pointer\r
1741 # @param Obj for whom set statement is got\r
1742 # @retval True Successfully find\r
1743 # @retval False Not able to find\r
1744 #\r
9e47e6f9
CJ
1745 def _GetSetStatement(self, Obj):\r
1746 if self._IsKeyword("SET"):\r
1747 PcdPair = self._GetNextPcdSettings()\r
30fdf114 1748\r
9e47e6f9 1749 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1750 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1751\r
9e47e6f9
CJ
1752 Value = self._GetExpression()\r
1753 Value = self._EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)\r
30fdf114 1754\r
6780eef1
LG
1755 if Obj:\r
1756 Obj.SetVarDict[PcdPair] = Value\r
30fdf114 1757 self.Profile.PcdDict[PcdPair] = Value\r
543f5ac3 1758 self.SetPcdLocalation(PcdPair)\r
d0acc87a
LG
1759 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1760 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple\r
30fdf114
LG
1761 return True\r
1762\r
1763 return False\r
1764\r
9e47e6f9 1765 ## _CalcRegionExpr(self)\r
4afd3d04
LG
1766 #\r
1767 # Calculate expression for offset or size of a region\r
1768 #\r
1769 # @return: None if invalid expression\r
1770 # Calculated number if successfully\r
1771 #\r
9e47e6f9 1772 def _CalcRegionExpr(self):\r
4afd3d04
LG
1773 StartPos = self.GetFileBufferPos()\r
1774 Expr = ''\r
1775 PairCount = 0\r
9e47e6f9
CJ
1776 while not self._EndOfFile():\r
1777 CurCh = self._CurrentChar()\r
4afd3d04
LG
1778 if CurCh == '(':\r
1779 PairCount += 1\r
1780 elif CurCh == ')':\r
1781 PairCount -= 1\r
1782\r
1783 if CurCh in '|\r\n' and PairCount == 0:\r
1784 break\r
1785 Expr += CurCh\r
9e47e6f9 1786 self._GetOneChar()\r
4afd3d04 1787 try:\r
1ccc4d89 1788 return long(\r
4afd3d04 1789 ValueExpression(Expr,\r
9e47e6f9 1790 self._CollectMacroPcd()\r
ccaa7754 1791 )(True), 0)\r
4afd3d04
LG
1792 except Exception:\r
1793 self.SetFileBufferPos(StartPos)\r
1794 return None\r
1795\r
9e47e6f9 1796 ## _GetRegionLayout() method\r
30fdf114
LG
1797 #\r
1798 # Get region layout for FD\r
1799 #\r
1800 # @param self The object pointer\r
9e47e6f9 1801 # @param theFd for whom region is got\r
30fdf114
LG
1802 # @retval True Successfully find\r
1803 # @retval False Not able to find\r
1804 #\r
9e47e6f9
CJ
1805 def _GetRegionLayout(self, theFd):\r
1806 Offset = self._CalcRegionExpr()\r
4231a819 1807 if Offset is None:\r
30fdf114
LG
1808 return False\r
1809\r
9e47e6f9 1810 RegionObj = Region()\r
4afd3d04 1811 RegionObj.Offset = Offset\r
9e47e6f9 1812 theFd.RegionList.append(RegionObj)\r
30fdf114 1813\r
9e47e6f9 1814 if not self._IsToken(TAB_VALUE_SPLIT):\r
ca957eb5 1815 raise Warning.Expected("'|'", self.FileName, self.CurrentLineNumber)\r
30fdf114 1816\r
9e47e6f9 1817 Size = self._CalcRegionExpr()\r
4231a819 1818 if Size is None:\r
ca957eb5 1819 raise Warning.Expected("Region Size", self.FileName, self.CurrentLineNumber)\r
4afd3d04 1820 RegionObj.Size = Size\r
30fdf114 1821\r
9e47e6f9 1822 if not self._GetNextWord():\r
30fdf114
LG
1823 return True\r
1824\r
5a264f28 1825 if not self._Token in {"SET", BINARY_FILE_TYPE_FV, "FILE", "DATA", "CAPSULE", "INF"}:\r
2bc3256c
LG
1826 #\r
1827 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]\r
1828 # Or it might be next region's offset described by an expression which starts with a PCD.\r
1829 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size\r
1830 #\r
9e47e6f9
CJ
1831 self._UndoToken()\r
1832 IsRegionPcd = (RegionSizeGuidPattern.match(self._CurrentLine()[self.CurrentOffsetWithinLine:]) or\r
1833 RegionOffsetPcdPattern.match(self._CurrentLine()[self.CurrentOffsetWithinLine:]))\r
2bc3256c 1834 if IsRegionPcd:\r
9e47e6f9
CJ
1835 RegionObj.PcdOffset = self._GetNextPcdSettings()\r
1836 self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(theFd.BaseAddress, 0))\r
543f5ac3 1837 self.SetPcdLocalation(RegionObj.PcdOffset)\r
9e47e6f9 1838 self._PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset\r
d0acc87a 1839 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2bc3256c 1840 self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple\r
9e47e6f9
CJ
1841 if self._IsToken(TAB_VALUE_SPLIT):\r
1842 RegionObj.PcdSize = self._GetNextPcdSettings()\r
2bc3256c 1843 self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size\r
543f5ac3 1844 self.SetPcdLocalation(RegionObj.PcdSize)\r
9e47e6f9 1845 self._PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size\r
2bc3256c
LG
1846 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
1847 self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple\r
30fdf114 1848\r
9e47e6f9 1849 if not self._GetNextWord():\r
30fdf114
LG
1850 return True\r
1851\r
9e47e6f9
CJ
1852 if self._Token == "SET":\r
1853 self._UndoToken()\r
1854 self._GetSetStatements(RegionObj)\r
1855 if not self._GetNextWord():\r
30fdf114
LG
1856 return True\r
1857\r
9e47e6f9
CJ
1858 elif self._Token == BINARY_FILE_TYPE_FV:\r
1859 self._UndoToken()\r
1860 self._GetRegionFvType(RegionObj)\r
30fdf114 1861\r
9e47e6f9
CJ
1862 elif self._Token == "CAPSULE":\r
1863 self._UndoToken()\r
1864 self._GetRegionCapType(RegionObj)\r
fd171542 1865\r
9e47e6f9
CJ
1866 elif self._Token == "FILE":\r
1867 self._UndoToken()\r
1868 self._GetRegionFileType(RegionObj)\r
b21a13fb 1869\r
9e47e6f9
CJ
1870 elif self._Token == "INF":\r
1871 self._UndoToken()\r
b21a13fb 1872 RegionObj.RegionType = "INF"\r
9e47e6f9
CJ
1873 while self._IsKeyword("INF"):\r
1874 self._UndoToken()\r
1875 ffsInf = self._ParseInfStatement()\r
b21a13fb
YZ
1876 if not ffsInf:\r
1877 break\r
1878 RegionObj.RegionDataList.append(ffsInf)\r
30fdf114 1879\r
9e47e6f9
CJ
1880 elif self._Token == "DATA":\r
1881 self._UndoToken()\r
1882 self._GetRegionDataType(RegionObj)\r
79b74a03 1883 else:\r
9e47e6f9
CJ
1884 self._UndoToken()\r
1885 if self._GetRegionLayout(theFd):\r
2bc3256c 1886 return True\r
79b74a03 1887 raise Warning("A valid region type was not found. "\r
b21a13fb 1888 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",\r
79b74a03 1889 self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1890\r
1891 return True\r
1892\r
9e47e6f9 1893 ## _GetRegionFvType() method\r
30fdf114
LG
1894 #\r
1895 # Get region fv data for region\r
1896 #\r
1897 # @param self The object pointer\r
1898 # @param RegionObj for whom region data is got\r
1899 #\r
9e47e6f9
CJ
1900 def _GetRegionFvType(self, RegionObj):\r
1901 if not self._IsKeyword(BINARY_FILE_TYPE_FV):\r
ca957eb5 1902 raise Warning.Expected("'FV'", self.FileName, self.CurrentLineNumber)\r
30fdf114 1903\r
9e47e6f9 1904 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1905 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1906\r
9e47e6f9 1907 if not self._GetNextToken():\r
ca957eb5 1908 raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)\r
30fdf114 1909\r
91fa33ee 1910 RegionObj.RegionType = BINARY_FILE_TYPE_FV\r
9e47e6f9 1911 RegionObj.RegionDataList.append((self._Token).upper())\r
30fdf114 1912\r
9e47e6f9 1913 while self._IsKeyword(BINARY_FILE_TYPE_FV):\r
30fdf114 1914\r
9e47e6f9 1915 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1916 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1917\r
9e47e6f9 1918 if not self._GetNextToken():\r
ca957eb5 1919 raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)\r
30fdf114 1920\r
9e47e6f9 1921 RegionObj.RegionDataList.append((self._Token).upper())\r
30fdf114 1922\r
9e47e6f9 1923 ## _GetRegionCapType() method\r
fd171542 1924 #\r
1925 # Get region capsule data for region\r
1926 #\r
1927 # @param self The object pointer\r
1928 # @param RegionObj for whom region data is got\r
1929 #\r
9e47e6f9
CJ
1930 def _GetRegionCapType(self, RegionObj):\r
1931 if not self._IsKeyword("CAPSULE"):\r
ca957eb5 1932 raise Warning.Expected("'CAPSULE'", self.FileName, self.CurrentLineNumber)\r
fd171542 1933\r
9e47e6f9 1934 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1935 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
fd171542 1936\r
9e47e6f9 1937 if not self._GetNextToken():\r
ca957eb5 1938 raise Warning.Expected("CAPSULE name", self.FileName, self.CurrentLineNumber)\r
fd171542 1939\r
1940 RegionObj.RegionType = "CAPSULE"\r
9e47e6f9 1941 RegionObj.RegionDataList.append(self._Token)\r
fd171542 1942\r
9e47e6f9 1943 while self._IsKeyword("CAPSULE"):\r
fd171542 1944\r
9e47e6f9 1945 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1946 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
fd171542 1947\r
9e47e6f9 1948 if not self._GetNextToken():\r
ca957eb5 1949 raise Warning.Expected("CAPSULE name", self.FileName, self.CurrentLineNumber)\r
fd171542 1950\r
9e47e6f9 1951 RegionObj.RegionDataList.append(self._Token)\r
fd171542 1952\r
9e47e6f9 1953 ## _GetRegionFileType() method\r
30fdf114
LG
1954 #\r
1955 # Get region file data for region\r
1956 #\r
1957 # @param self The object pointer\r
1958 # @param RegionObj for whom region data is got\r
1959 #\r
9e47e6f9
CJ
1960 def _GetRegionFileType(self, RegionObj):\r
1961 if not self._IsKeyword("FILE"):\r
ca957eb5 1962 raise Warning.Expected("'FILE'", self.FileName, self.CurrentLineNumber)\r
30fdf114 1963\r
9e47e6f9 1964 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1965 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1966\r
9e47e6f9 1967 if not self._GetNextToken():\r
ca957eb5 1968 raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
1969\r
1970 RegionObj.RegionType = "FILE"\r
9e47e6f9 1971 RegionObj.RegionDataList.append(self._Token)\r
30fdf114 1972\r
9e47e6f9 1973 while self._IsKeyword("FILE"):\r
30fdf114 1974\r
9e47e6f9 1975 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1976 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1977\r
9e47e6f9 1978 if not self._GetNextToken():\r
ca957eb5 1979 raise Warning.Expected("FILE name", self.FileName, self.CurrentLineNumber)\r
30fdf114 1980\r
9e47e6f9 1981 RegionObj.RegionDataList.append(self._Token)\r
30fdf114 1982\r
9e47e6f9 1983 ## _GetRegionDataType() method\r
30fdf114
LG
1984 #\r
1985 # Get region array data for region\r
1986 #\r
1987 # @param self The object pointer\r
1988 # @param RegionObj for whom region data is got\r
1989 #\r
9e47e6f9
CJ
1990 def _GetRegionDataType(self, RegionObj):\r
1991 if not self._IsKeyword("DATA"):\r
ca957eb5 1992 raise Warning.Expected("Region Data type", self.FileName, self.CurrentLineNumber)\r
30fdf114 1993\r
9e47e6f9 1994 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 1995 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 1996\r
9e47e6f9 1997 if not self._IsToken("{"):\r
ca957eb5 1998 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
30fdf114 1999\r
9e47e6f9 2000 if not self._GetNextHexNumber():\r
ca957eb5 2001 raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber)\r
30fdf114 2002\r
9e47e6f9 2003 if len(self._Token) > 18:\r
636f2be6
LG
2004 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)\r
2005\r
2006 # convert hex string value to byte hex string array\r
9e47e6f9 2007 AllString = self._Token\r
636f2be6
LG
2008 AllStrLen = len (AllString)\r
2009 DataString = ""\r
2010 while AllStrLen > 4:\r
9e47e6f9 2011 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + TAB_COMMA_SPLIT\r
636f2be6 2012 AllStrLen = AllStrLen - 2\r
9e47e6f9 2013 DataString = DataString + AllString[:AllStrLen] + TAB_COMMA_SPLIT\r
636f2be6
LG
2014\r
2015 # byte value array\r
9e47e6f9
CJ
2016 if len (self._Token) <= 4:\r
2017 while self._IsToken(TAB_COMMA_SPLIT):\r
2018 if not self._GetNextHexNumber():\r
636f2be6 2019 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2020 if len(self._Token) > 4:\r
636f2be6 2021 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2022 DataString += self._Token\r
2023 DataString += TAB_COMMA_SPLIT\r
30fdf114 2024\r
ea98a825 2025 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2026 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 2027\r
9e47e6f9 2028 DataString = DataString.rstrip(TAB_COMMA_SPLIT)\r
30fdf114 2029 RegionObj.RegionType = "DATA"\r
9e47e6f9 2030 RegionObj.RegionDataList.append(DataString)\r
30fdf114 2031\r
9e47e6f9 2032 while self._IsKeyword("DATA"):\r
30fdf114 2033\r
9e47e6f9 2034 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2035 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2036\r
9e47e6f9 2037 if not self._IsToken("{"):\r
ca957eb5 2038 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
30fdf114 2039\r
9e47e6f9 2040 if not self._GetNextHexNumber():\r
ca957eb5 2041 raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber)\r
30fdf114 2042\r
9e47e6f9 2043 if len(self._Token) > 18:\r
636f2be6
LG
2044 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)\r
2045\r
2046 # convert hex string value to byte hex string array\r
9e47e6f9 2047 AllString = self._Token\r
636f2be6
LG
2048 AllStrLen = len (AllString)\r
2049 DataString = ""\r
2050 while AllStrLen > 4:\r
9e47e6f9 2051 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + TAB_COMMA_SPLIT\r
636f2be6 2052 AllStrLen = AllStrLen - 2\r
9e47e6f9 2053 DataString = DataString + AllString[:AllStrLen] + TAB_COMMA_SPLIT\r
636f2be6
LG
2054\r
2055 # byte value array\r
9e47e6f9
CJ
2056 if len (self._Token) <= 4:\r
2057 while self._IsToken(TAB_COMMA_SPLIT):\r
2058 if not self._GetNextHexNumber():\r
636f2be6 2059 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2060 if len(self._Token) > 4:\r
636f2be6 2061 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2062 DataString += self._Token\r
2063 DataString += TAB_COMMA_SPLIT\r
30fdf114 2064\r
ea98a825 2065 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2066 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 2067\r
9e47e6f9
CJ
2068 DataString = DataString.rstrip(TAB_COMMA_SPLIT)\r
2069 RegionObj.RegionDataList.append(DataString)\r
30fdf114 2070\r
9e47e6f9 2071 ## _GetFv() method\r
30fdf114
LG
2072 #\r
2073 # Get FV section contents and store its data into FV dictionary of self.Profile\r
2074 #\r
2075 # @param self The object pointer\r
2076 # @retval True Successfully find a FV\r
2077 # @retval False Not able to find a FV\r
2078 #\r
9e47e6f9
CJ
2079 def _GetFv(self):\r
2080 if not self._GetNextToken():\r
30fdf114
LG
2081 return False\r
2082\r
9e47e6f9
CJ
2083 S = self._Token.upper()\r
2084 if S.startswith(TAB_SECTION_START) and not S.startswith("[FV."):\r
df81077f 2085 self.SectionParser(S)\r
9e47e6f9 2086 self._UndoToken()\r
30fdf114
LG
2087 return False\r
2088\r
9e47e6f9
CJ
2089 self._UndoToken()\r
2090 if not self._IsToken("[FV.", True):\r
30fdf114
LG
2091 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2092 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9
CJ
2093 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
2094 raise Warning("Unknown Keyword '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114 2095\r
9e47e6f9 2096 FvName = self._GetUiName()\r
30fdf114
LG
2097 self.CurrentFvName = FvName.upper()\r
2098\r
9e47e6f9 2099 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 2100 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 2101\r
9ffaaac2 2102 FvObj = FV(Name=self.CurrentFvName)\r
30fdf114
LG
2103 self.Profile.FvDict[self.CurrentFvName] = FvObj\r
2104\r
9e47e6f9 2105 Status = self._GetCreateFile(FvObj)\r
30fdf114
LG
2106 if not Status:\r
2107 raise Warning("FV name error", self.FileName, self.CurrentLineNumber)\r
2108\r
9e47e6f9 2109 self._GetDefineStatements(FvObj)\r
30fdf114 2110\r
9e47e6f9 2111 self._GetAddressStatements(FvObj)\r
30fdf114 2112\r
b303ea72 2113 while True:\r
9e47e6f9 2114 self._GetSetStatements(FvObj)\r
e8a47801 2115\r
9e47e6f9
CJ
2116 if not (self._GetBlockStatement(FvObj) or self._GetFvBaseAddress(FvObj) or\r
2117 self._GetFvForceRebase(FvObj) or self._GetFvAlignment(FvObj) or\r
2118 self._GetFvAttributes(FvObj) or self._GetFvNameGuid(FvObj) or\r
2119 self._GetFvExtEntryStatement(FvObj) or self._GetFvNameString(FvObj)):\r
b303ea72
LG
2120 break\r
2121\r
aaf8aa7b
YL
2122 if FvObj.FvNameString == 'TRUE' and not FvObj.FvNameGuid:\r
2123 raise Warning("FvNameString found but FvNameGuid was not found", self.FileName, self.CurrentLineNumber)\r
2124\r
5a6a268d
JC
2125 self._GetAprioriSection(FvObj)\r
2126 self._GetAprioriSection(FvObj)\r
30fdf114
LG
2127\r
2128 while True:\r
9e47e6f9 2129 isInf = self._GetInfStatement(FvObj)\r
5a6a268d 2130 isFile = self._GetFileStatement(FvObj)\r
30fdf114
LG
2131 if not isInf and not isFile:\r
2132 break\r
2133\r
2134 return True\r
2135\r
9e47e6f9 2136 ## _GetFvAlignment() method\r
30fdf114
LG
2137 #\r
2138 # Get alignment for FV\r
2139 #\r
2140 # @param self The object pointer\r
2141 # @param Obj for whom alignment is got\r
2142 # @retval True Successfully find a alignment statement\r
2143 # @retval False Not able to find a alignment statement\r
2144 #\r
9e47e6f9
CJ
2145 def _GetFvAlignment(self, Obj):\r
2146 if not self._IsKeyword("FvAlignment"):\r
30fdf114
LG
2147 return False\r
2148\r
9e47e6f9 2149 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2150 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2151\r
9e47e6f9 2152 if not self._GetNextToken():\r
ca957eb5 2153 raise Warning.Expected("alignment value", self.FileName, self.CurrentLineNumber)\r
30fdf114 2154\r
5a264f28 2155 if self._Token.upper() not in {"1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \\r
30fdf114
LG
2156 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \\r
2157 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \\r
5a264f28 2158 "1G", "2G"}:\r
9e47e6f9
CJ
2159 raise Warning("Unknown alignment value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
2160 Obj.FvAlignment = self._Token\r
30fdf114 2161 return True\r
f7496d71 2162\r
9e47e6f9 2163 ## _GetFvBaseAddress() method\r
4234283c
LG
2164 #\r
2165 # Get BaseAddress for FV\r
2166 #\r
2167 # @param self The object pointer\r
2168 # @param Obj for whom FvBaseAddress is got\r
2169 # @retval True Successfully find a FvBaseAddress statement\r
2170 # @retval False Not able to find a FvBaseAddress statement\r
2171 #\r
9e47e6f9
CJ
2172 def _GetFvBaseAddress(self, Obj):\r
2173 if not self._IsKeyword("FvBaseAddress"):\r
4234283c
LG
2174 return False\r
2175\r
9e47e6f9 2176 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2177 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
4234283c 2178\r
9e47e6f9 2179 if not self._GetNextToken():\r
ca957eb5 2180 raise Warning.Expected("FV base address value", self.FileName, self.CurrentLineNumber)\r
4234283c 2181\r
9e47e6f9
CJ
2182 if not BaseAddrValuePattern.match(self._Token.upper()):\r
2183 raise Warning("Unknown FV base address value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
2184 Obj.FvBaseAddress = self._Token\r
f7496d71
LG
2185 return True\r
2186\r
9e47e6f9 2187 ## _GetFvForceRebase() method\r
79b74a03
LG
2188 #\r
2189 # Get FvForceRebase for FV\r
2190 #\r
2191 # @param self The object pointer\r
2192 # @param Obj for whom FvForceRebase is got\r
2193 # @retval True Successfully find a FvForceRebase statement\r
2194 # @retval False Not able to find a FvForceRebase statement\r
2195 #\r
9e47e6f9
CJ
2196 def _GetFvForceRebase(self, Obj):\r
2197 if not self._IsKeyword("FvForceRebase"):\r
79b74a03
LG
2198 return False\r
2199\r
9e47e6f9 2200 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2201 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
79b74a03 2202\r
9e47e6f9 2203 if not self._GetNextToken():\r
ca957eb5 2204 raise Warning.Expected("FvForceRebase value", self.FileName, self.CurrentLineNumber)\r
30fdf114 2205\r
5a264f28 2206 if self._Token.upper() not in {"TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"}:\r
9e47e6f9 2207 raise Warning("Unknown FvForceRebase value '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
f7496d71 2208\r
5a264f28 2209 if self._Token.upper() in {"TRUE", "1", "0X1", "0X01"}:\r
79b74a03 2210 Obj.FvForceRebase = True\r
5a264f28 2211 elif self._Token.upper() in {"FALSE", "0", "0X0", "0X00"}:\r
79b74a03
LG
2212 Obj.FvForceRebase = False\r
2213 else:\r
2214 Obj.FvForceRebase = None\r
f7496d71 2215\r
79b74a03 2216 return True\r
0d2711a6
LG
2217\r
2218\r
9e47e6f9 2219 ## _GetFvAttributes() method\r
30fdf114
LG
2220 #\r
2221 # Get attributes for FV\r
2222 #\r
2223 # @param self The object pointer\r
2224 # @param Obj for whom attribute is got\r
2225 # @retval None\r
2226 #\r
9e47e6f9 2227 def _GetFvAttributes(self, FvObj):\r
2bc3256c 2228 IsWordToken = False\r
9e47e6f9 2229 while self._GetNextWord():\r
2bc3256c 2230 IsWordToken = True\r
9e47e6f9 2231 name = self._Token\r
5a264f28 2232 if name not in {"ERASE_POLARITY", "MEMORY_MAPPED", \\r
30fdf114
LG
2233 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \\r
2234 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \\r
2235 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \\r
2236 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \\r
5a264f28 2237 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"}:\r
9e47e6f9 2238 self._UndoToken()\r
e8a47801 2239 return False\r
30fdf114 2240\r
9e47e6f9 2241 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2242 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2243\r
5a264f28 2244 if not self._GetNextToken() or self._Token.upper() not in {"TRUE", "FALSE", "1", "0"}:\r
ca957eb5 2245 raise Warning.Expected("TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)\r
30fdf114 2246\r
9e47e6f9 2247 FvObj.FvAttributeDict[name] = self._Token\r
30fdf114 2248\r
2bc3256c 2249 return IsWordToken\r
f7496d71 2250\r
9e47e6f9 2251 ## _GetFvNameGuid() method\r
30fdf114
LG
2252 #\r
2253 # Get FV GUID for FV\r
2254 #\r
2255 # @param self The object pointer\r
2256 # @param Obj for whom GUID is got\r
2257 # @retval None\r
2258 #\r
9e47e6f9
CJ
2259 def _GetFvNameGuid(self, FvObj):\r
2260 if not self._IsKeyword("FvNameGuid"):\r
e8a47801 2261 return False\r
30fdf114 2262\r
9e47e6f9 2263 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2264 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2265\r
9e47e6f9 2266 if not self._GetNextGuid():\r
ca957eb5 2267 raise Warning.Expected("GUID value", self.FileName, self.CurrentLineNumber)\r
30fdf114 2268\r
9e47e6f9 2269 FvObj.FvNameGuid = self._Token\r
30fdf114 2270\r
e8a47801 2271 return True\r
30fdf114 2272\r
9e47e6f9
CJ
2273 def _GetFvNameString(self, FvObj):\r
2274 if not self._IsKeyword("FvNameString"):\r
aaf8aa7b
YL
2275 return False\r
2276\r
9e47e6f9 2277 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2278 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
aaf8aa7b 2279\r
ca957eb5
CJ
2280 if not self._GetNextToken() or self._Token.upper() not in {'TRUE', 'FALSE'}:\r
2281 raise Warning.Expected("TRUE or FALSE for FvNameString", self.FileName, self.CurrentLineNumber)\r
aaf8aa7b 2282\r
9e47e6f9 2283 FvObj.FvNameString = self._Token\r
aaf8aa7b
YL
2284\r
2285 return True\r
2286\r
9e47e6f9
CJ
2287 def _GetFvExtEntryStatement(self, FvObj):\r
2288 if not (self._IsKeyword("FV_EXT_ENTRY") or self._IsKeyword("FV_EXT_ENTRY_TYPE")):\r
b303ea72
LG
2289 return False\r
2290\r
9e47e6f9 2291 if not self._IsKeyword ("TYPE"):\r
ca957eb5 2292 raise Warning.Expected("'TYPE'", self.FileName, self.CurrentLineNumber)\r
f7496d71 2293\r
9e47e6f9 2294 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2295 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
b303ea72 2296\r
9e47e6f9 2297 if not self._GetNextHexNumber() and not self._GetNextDecimalNumber():\r
ca957eb5 2298 raise Warning.Expected("Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber)\r
b303ea72 2299\r
9e47e6f9 2300 FvObj.FvExtEntryTypeValue.append(self._Token)\r
b303ea72 2301\r
9e47e6f9 2302 if not self._IsToken("{"):\r
ca957eb5 2303 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
b303ea72 2304\r
ca957eb5
CJ
2305 if not self._IsKeyword("FILE") and not self._IsKeyword("DATA"):\r
2306 raise Warning.Expected("'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber)\r
b303ea72 2307\r
9e47e6f9 2308 FvObj.FvExtEntryType.append(self._Token)\r
b303ea72 2309\r
9e47e6f9 2310 if self._Token == 'DATA':\r
9e47e6f9 2311 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2312 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
f7496d71 2313\r
9e47e6f9 2314 if not self._IsToken("{"):\r
ca957eb5 2315 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
b303ea72 2316\r
9e47e6f9 2317 if not self._GetNextHexNumber():\r
ca957eb5 2318 raise Warning.Expected("Hex byte", self.FileName, self.CurrentLineNumber)\r
b303ea72 2319\r
9e47e6f9 2320 if len(self._Token) > 4:\r
b303ea72
LG
2321 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
2322\r
9e47e6f9
CJ
2323 DataString = self._Token\r
2324 DataString += TAB_COMMA_SPLIT\r
b303ea72 2325\r
9e47e6f9
CJ
2326 while self._IsToken(TAB_COMMA_SPLIT):\r
2327 if not self._GetNextHexNumber():\r
b303ea72 2328 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2329 if len(self._Token) > 4:\r
b303ea72 2330 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2331 DataString += self._Token\r
2332 DataString += TAB_COMMA_SPLIT\r
b303ea72 2333\r
ea98a825 2334 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2335 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
b303ea72 2336\r
ea98a825 2337 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2338 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
b303ea72 2339\r
9e47e6f9 2340 DataString = DataString.rstrip(TAB_COMMA_SPLIT)\r
caf74495 2341 FvObj.FvExtEntryData.append(DataString)\r
b303ea72 2342\r
9e47e6f9 2343 if self._Token == 'FILE':\r
9e47e6f9 2344 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2345 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
f7496d71 2346\r
9e47e6f9 2347 if not self._GetNextToken():\r
ca957eb5 2348 raise Warning.Expected("FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber)\r
f7496d71 2349\r
9e47e6f9 2350 FvObj.FvExtEntryData.append(self._Token)\r
b303ea72 2351\r
ea98a825 2352 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2353 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
b303ea72
LG
2354\r
2355 return True\r
2356\r
9e47e6f9 2357 ## _GetAprioriSection() method\r
30fdf114
LG
2358 #\r
2359 # Get token statements\r
2360 #\r
2361 # @param self The object pointer\r
2362 # @param FvObj for whom apriori is got\r
30fdf114
LG
2363 # @retval True Successfully find apriori statement\r
2364 # @retval False Not able to find apriori statement\r
2365 #\r
5a6a268d 2366 def _GetAprioriSection(self, FvObj):\r
9e47e6f9 2367 if not self._IsKeyword("APRIORI"):\r
30fdf114
LG
2368 return False\r
2369\r
9e47e6f9 2370 if not self._IsKeyword("PEI") and not self._IsKeyword("DXE"):\r
ca957eb5 2371 raise Warning.Expected("Apriori file type", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2372 AprType = self._Token\r
30fdf114 2373\r
9e47e6f9 2374 if not self._IsToken("{"):\r
ca957eb5 2375 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
30fdf114 2376\r
9e47e6f9 2377 AprSectionObj = AprioriSection()\r
30fdf114
LG
2378 AprSectionObj.AprioriType = AprType\r
2379\r
9e47e6f9 2380 self._GetDefineStatements(AprSectionObj)\r
30fdf114
LG
2381\r
2382 while True:\r
9e47e6f9
CJ
2383 IsInf = self._GetInfStatement(AprSectionObj)\r
2384 IsFile = self._GetFileStatement(AprSectionObj)\r
30fdf114
LG
2385 if not IsInf and not IsFile:\r
2386 break\r
2387\r
ea98a825 2388 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2389 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2390\r
2391 FvObj.AprioriSectionList.append(AprSectionObj)\r
2392 return True\r
2393\r
9e47e6f9
CJ
2394 def _ParseInfStatement(self):\r
2395 if not self._IsKeyword("INF"):\r
b21a13fb 2396 return None\r
30fdf114 2397\r
9e47e6f9
CJ
2398 ffsInf = FfsInfStatement()\r
2399 self._GetInfOptions(ffsInf)\r
30fdf114 2400\r
9e47e6f9 2401 if not self._GetNextToken():\r
ca957eb5 2402 raise Warning.Expected("INF file path", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2403 ffsInf.InfFileName = self._Token\r
a87e79d9 2404 if not ffsInf.InfFileName.endswith('.inf'):\r
ca957eb5 2405 raise Warning.Expected(".inf file path", self.FileName, self.CurrentLineNumber)\r
64b2609f
LG
2406\r
2407 ffsInf.CurrentLineNum = self.CurrentLineNumber\r
9e47e6f9 2408 ffsInf.CurrentLineContent = self._CurrentLine()\r
64b2609f 2409\r
97fa0ee9
YL
2410 #Replace $(SAPCE) with real space\r
2411 ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')\r
2412\r
9e47e6f9 2413 if ffsInf.InfFileName.replace(TAB_WORKSPACE, '').find('$') == -1:\r
14c48571 2414 #do case sensitive check for file path\r
2415 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
2416 if ErrorCode != 0:\r
2417 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 2418\r
30fdf114
LG
2419 if not ffsInf.InfFileName in self.Profile.InfList:\r
2420 self.Profile.InfList.append(ffsInf.InfFileName)\r
d0acc87a
LG
2421 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
2422 self.Profile.InfFileLineList.append(FileLineTuple)\r
2502b735
YZ
2423 if ffsInf.UseArch:\r
2424 if ffsInf.UseArch not in self.Profile.InfDict:\r
2425 self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]\r
2426 else:\r
2427 self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)\r
2428 else:\r
2429 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)\r
30fdf114 2430\r
9e47e6f9
CJ
2431 if self._IsToken(TAB_VALUE_SPLIT):\r
2432 if self._IsKeyword('RELOCS_STRIPPED'):\r
30fdf114 2433 ffsInf.KeepReloc = False\r
9e47e6f9 2434 elif self._IsKeyword('RELOCS_RETAINED'):\r
30fdf114
LG
2435 ffsInf.KeepReloc = True\r
2436 else:\r
9e47e6f9 2437 raise Warning("Unknown reloc strip flag '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
b21a13fb
YZ
2438 return ffsInf\r
2439\r
9e47e6f9 2440 ## _GetInfStatement() method\r
b21a13fb
YZ
2441 #\r
2442 # Get INF statements\r
2443 #\r
2444 # @param self The object pointer\r
2445 # @param Obj for whom inf statement is got\r
b21a13fb
YZ
2446 # @retval True Successfully find inf statement\r
2447 # @retval False Not able to find inf statement\r
2448 #\r
9e47e6f9
CJ
2449 def _GetInfStatement(self, Obj, ForCapsule=False):\r
2450 ffsInf = self._ParseInfStatement()\r
b21a13fb
YZ
2451 if not ffsInf:\r
2452 return False\r
2453\r
30fdf114 2454 if ForCapsule:\r
9e47e6f9
CJ
2455 myCapsuleFfs = CapsuleFfs()\r
2456 myCapsuleFfs.Ffs = ffsInf\r
2457 Obj.CapsuleDataList.append(myCapsuleFfs)\r
30fdf114
LG
2458 else:\r
2459 Obj.FfsList.append(ffsInf)\r
2460 return True\r
2461\r
9e47e6f9 2462 ## _GetInfOptions() method\r
30fdf114
LG
2463 #\r
2464 # Get options for INF\r
2465 #\r
2466 # @param self The object pointer\r
2467 # @param FfsInfObj for whom option is got\r
2468 #\r
9e47e6f9
CJ
2469 def _GetInfOptions(self, FfsInfObj):\r
2470 if self._IsKeyword("FILE_GUID"):\r
2471 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2472 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2473 if not self._GetNextGuid():\r
ca957eb5 2474 raise Warning.Expected("GUID value", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2475 FfsInfObj.OverrideGuid = self._Token\r
30fdf114 2476\r
9e47e6f9
CJ
2477 if self._IsKeyword("RuleOverride"):\r
2478 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2479 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2480 if not self._GetNextToken():\r
ca957eb5 2481 raise Warning.Expected("Rule name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2482 FfsInfObj.Rule = self._Token\r
30fdf114 2483\r
9e47e6f9
CJ
2484 if self._IsKeyword("VERSION"):\r
2485 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2486 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2487 if not self._GetNextToken():\r
ca957eb5 2488 raise Warning.Expected("Version", self.FileName, self.CurrentLineNumber)\r
30fdf114 2489\r
9e47e6f9
CJ
2490 if self._GetStringData():\r
2491 FfsInfObj.Version = self._Token\r
30fdf114 2492\r
9e47e6f9
CJ
2493 if self._IsKeyword(BINARY_FILE_TYPE_UI):\r
2494 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2495 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2496 if not self._GetNextToken():\r
ca957eb5 2497 raise Warning.Expected("UI name", self.FileName, self.CurrentLineNumber)\r
30fdf114 2498\r
9e47e6f9
CJ
2499 if self._GetStringData():\r
2500 FfsInfObj.Ui = self._Token\r
30fdf114 2501\r
9e47e6f9
CJ
2502 if self._IsKeyword("USE"):\r
2503 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2504 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2505 if not self._GetNextToken():\r
ca957eb5 2506 raise Warning.Expected("ARCH name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2507 FfsInfObj.UseArch = self._Token\r
30fdf114 2508\r
f7496d71 2509\r
9e47e6f9
CJ
2510 if self._GetNextToken():\r
2511 p = compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')\r
2512 if p.match(self._Token) and p.match(self._Token).span()[1] == len(self._Token):\r
2513 FfsInfObj.KeyStringList.append(self._Token)\r
2514 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
2515 return\r
2516 else:\r
9e47e6f9 2517 self._UndoToken()\r
30fdf114
LG
2518 return\r
2519\r
9e47e6f9
CJ
2520 while self._GetNextToken():\r
2521 if not p.match(self._Token):\r
ca957eb5 2522 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2523 FfsInfObj.KeyStringList.append(self._Token)\r
30fdf114 2524\r
9e47e6f9 2525 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
2526 break\r
2527\r
9e47e6f9 2528 ## _GetFileStatement() method\r
30fdf114
LG
2529 #\r
2530 # Get FILE statements\r
2531 #\r
2532 # @param self The object pointer\r
2533 # @param Obj for whom FILE statement is got\r
30fdf114
LG
2534 # @retval True Successfully find FILE statement\r
2535 # @retval False Not able to find FILE statement\r
2536 #\r
5a6a268d 2537 def _GetFileStatement(self, Obj, ForCapsule = False):\r
9e47e6f9 2538 if not self._IsKeyword("FILE"):\r
30fdf114
LG
2539 return False\r
2540\r
9e47e6f9 2541 if not self._GetNextWord():\r
ca957eb5 2542 raise Warning.Expected("FFS type", self.FileName, self.CurrentLineNumber)\r
b36d134f 2543\r
9e47e6f9
CJ
2544 if ForCapsule and self._Token == 'DATA':\r
2545 self._UndoToken()\r
2546 self._UndoToken()\r
b36d134f 2547 return False\r
f7496d71 2548\r
9e47e6f9
CJ
2549 FfsFileObj = FileStatement()\r
2550 FfsFileObj.FvFileType = self._Token\r
30fdf114 2551\r
9e47e6f9 2552 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2553 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2554\r
9e47e6f9
CJ
2555 if not self._GetNextGuid():\r
2556 if not self._GetNextWord():\r
ca957eb5 2557 raise Warning.Expected("File GUID", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2558 if self._Token == 'PCD':\r
2559 if not self._IsToken("("):\r
ca957eb5 2560 raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2561 PcdPair = self._GetNextPcdSettings()\r
2562 if not self._IsToken(")"):\r
ca957eb5 2563 raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2564 self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'\r
f7496d71 2565\r
9e47e6f9 2566 FfsFileObj.NameGuid = self._Token\r
f7496d71 2567\r
5a6a268d 2568 self._GetFilePart(FfsFileObj)\r
30fdf114
LG
2569\r
2570 if ForCapsule:\r
9e47e6f9 2571 capsuleFfs = CapsuleFfs()\r
30fdf114
LG
2572 capsuleFfs.Ffs = FfsFileObj\r
2573 Obj.CapsuleDataList.append(capsuleFfs)\r
2574 else:\r
2575 Obj.FfsList.append(FfsFileObj)\r
2576\r
2577 return True\r
2578\r
9e47e6f9 2579 ## _FileCouldHaveRelocFlag() method\r
30fdf114
LG
2580 #\r
2581 # Check whether reloc strip flag can be set for a file type.\r
2582 #\r
30fdf114
LG
2583 # @param FileType The file type to check with\r
2584 # @retval True This type could have relocation strip flag\r
2585 # @retval False No way to have it\r
2586 #\r
5bcf1d56 2587 @staticmethod\r
9e47e6f9 2588 def _FileCouldHaveRelocFlag (FileType):\r
5a264f28 2589 if FileType in {SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, 'PEI_DXE_COMBO'}:\r
30fdf114
LG
2590 return True\r
2591 else:\r
2592 return False\r
2593\r
9e47e6f9 2594 ## _SectionCouldHaveRelocFlag() method\r
30fdf114
LG
2595 #\r
2596 # Check whether reloc strip flag can be set for a section type.\r
2597 #\r
30fdf114
LG
2598 # @param SectionType The section type to check with\r
2599 # @retval True This type could have relocation strip flag\r
2600 # @retval False No way to have it\r
2601 #\r
5bcf1d56 2602 @staticmethod\r
9e47e6f9 2603 def _SectionCouldHaveRelocFlag (SectionType):\r
5a264f28 2604 if SectionType in {BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32}:\r
30fdf114
LG
2605 return True\r
2606 else:\r
2607 return False\r
2608\r
9e47e6f9 2609 ## _GetFilePart() method\r
30fdf114
LG
2610 #\r
2611 # Get components for FILE statement\r
2612 #\r
2613 # @param self The object pointer\r
2614 # @param FfsFileObj for whom component is got\r
30fdf114 2615 #\r
5a6a268d 2616 def _GetFilePart(self, FfsFileObj):\r
9e47e6f9 2617 self._GetFileOpts(FfsFileObj)\r
30fdf114 2618\r
9e47e6f9
CJ
2619 if not self._IsToken("{"):\r
2620 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
2621 if self._FileCouldHaveRelocFlag(FfsFileObj.FvFileType):\r
2622 if self._Token == 'RELOCS_STRIPPED':\r
4afd3d04
LG
2623 FfsFileObj.KeepReloc = False\r
2624 else:\r
2625 FfsFileObj.KeepReloc = True\r
2626 else:\r
2627 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
2628\r
9e47e6f9 2629 if not self._IsToken("{"):\r
ca957eb5 2630 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
30fdf114 2631\r
9e47e6f9 2632 if not self._GetNextToken():\r
ca957eb5 2633 raise Warning.Expected("File name or section data", self.FileName, self.CurrentLineNumber)\r
30fdf114 2634\r
9e47e6f9
CJ
2635 if self._Token == BINARY_FILE_TYPE_FV:\r
2636 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2637 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2638 if not self._GetNextToken():\r
ca957eb5 2639 raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2640 FfsFileObj.FvName = self._Token\r
30fdf114 2641\r
9e47e6f9
CJ
2642 elif self._Token == "FD":\r
2643 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2644 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2645 if not self._GetNextToken():\r
ca957eb5 2646 raise Warning.Expected("FD name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2647 FfsFileObj.FdName = self._Token\r
30fdf114 2648\r
5a264f28 2649 elif self._Token in {TAB_DEFINE, "APRIORI", "SECTION"}:\r
9e47e6f9 2650 self._UndoToken()\r
5a6a268d 2651 self._GetSectionData(FfsFileObj)\r
860992ed
YZ
2652\r
2653 elif hasattr(FfsFileObj, 'FvFileType') and FfsFileObj.FvFileType == 'RAW':\r
9e47e6f9 2654 self._UndoToken()\r
5a6a268d 2655 self._GetRAWData(FfsFileObj)\r
860992ed 2656\r
30fdf114 2657 else:\r
64b2609f 2658 FfsFileObj.CurrentLineNum = self.CurrentLineNumber\r
9e47e6f9
CJ
2659 FfsFileObj.CurrentLineContent = self._CurrentLine()\r
2660 FfsFileObj.FileName = self._Token.replace('$(SPACE)', ' ')\r
2661 self._VerifyFile(FfsFileObj.FileName)\r
0d2711a6 2662\r
ea98a825 2663 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2664 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 2665\r
9e47e6f9 2666 ## _GetRAWData() method\r
860992ed
YZ
2667 #\r
2668 # Get RAW data for FILE statement\r
2669 #\r
2670 # @param self The object pointer\r
2671 # @param FfsFileObj for whom section is got\r
860992ed 2672 #\r
5a6a268d 2673 def _GetRAWData(self, FfsFileObj):\r
860992ed 2674 FfsFileObj.FileName = []\r
cfaaf99b 2675 FfsFileObj.SubAlignment = []\r
860992ed
YZ
2676 while True:\r
2677 AlignValue = None\r
9e47e6f9
CJ
2678 if self._GetAlignment():\r
2679 if self._Token not in ALIGNMENTS:\r
2680 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
f475f1e2 2681 #For FFS, Auto is default option same to ""\r
9e47e6f9
CJ
2682 if not self._Token == "Auto":\r
2683 AlignValue = self._Token\r
2684 if not self._GetNextToken():\r
ca957eb5 2685 raise Warning.Expected("Filename value", self.FileName, self.CurrentLineNumber)\r
860992ed 2686\r
9e47e6f9 2687 FileName = self._Token.replace('$(SPACE)', ' ')\r
ea98a825 2688 if FileName == T_CHAR_BRACE_R:\r
9e47e6f9 2689 self._UndoToken()\r
ca957eb5 2690 raise Warning.Expected("Filename value", self.FileName, self.CurrentLineNumber)\r
860992ed 2691\r
9e47e6f9 2692 self._VerifyFile(FileName)\r
860992ed
YZ
2693 File = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir)\r
2694 FfsFileObj.FileName.append(File.Path)\r
cfaaf99b 2695 FfsFileObj.SubAlignment.append(AlignValue)\r
860992ed 2696\r
ea98a825 2697 if self._IsToken(T_CHAR_BRACE_R):\r
9e47e6f9 2698 self._UndoToken()\r
860992ed
YZ
2699 break\r
2700\r
cfaaf99b
YZ
2701 if len(FfsFileObj.SubAlignment) == 1:\r
2702 FfsFileObj.SubAlignment = FfsFileObj.SubAlignment[0]\r
860992ed
YZ
2703 if len(FfsFileObj.FileName) == 1:\r
2704 FfsFileObj.FileName = FfsFileObj.FileName[0]\r
2705\r
9e47e6f9 2706 ## _GetFileOpts() method\r
30fdf114
LG
2707 #\r
2708 # Get options for FILE statement\r
2709 #\r
2710 # @param self The object pointer\r
2711 # @param FfsFileObj for whom options is got\r
2712 #\r
9e47e6f9
CJ
2713 def _GetFileOpts(self, FfsFileObj):\r
2714 if self._GetNextToken():\r
2715 if TokenFindPattern.match(self._Token):\r
2716 FfsFileObj.KeyStringList.append(self._Token)\r
2717 if self._IsToken(TAB_COMMA_SPLIT):\r
2718 while self._GetNextToken():\r
2719 if not TokenFindPattern.match(self._Token):\r
ca957eb5 2720 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2721 FfsFileObj.KeyStringList.append(self._Token)\r
30fdf114 2722\r
9e47e6f9 2723 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
2724 break\r
2725\r
2726 else:\r
9e47e6f9 2727 self._UndoToken()\r
30fdf114 2728\r
9e47e6f9 2729 if self._IsKeyword("FIXED", True):\r
30fdf114
LG
2730 FfsFileObj.Fixed = True\r
2731\r
9e47e6f9 2732 if self._IsKeyword("CHECKSUM", True):\r
30fdf114
LG
2733 FfsFileObj.CheckSum = True\r
2734\r
9e47e6f9
CJ
2735 if self._GetAlignment():\r
2736 if self._Token not in ALIGNMENTS:\r
2737 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
9053bc51 2738 #For FFS, Auto is default option same to ""\r
9e47e6f9
CJ
2739 if not self._Token == "Auto":\r
2740 FfsFileObj.Alignment = self._Token\r
30fdf114 2741\r
9e47e6f9 2742 ## _GetAlignment() method\r
30fdf114
LG
2743 #\r
2744 # Return the alignment value\r
2745 #\r
2746 # @param self The object pointer\r
2747 # @retval True Successfully find alignment\r
2748 # @retval False Not able to find alignment\r
2749 #\r
9e47e6f9
CJ
2750 def _GetAlignment(self):\r
2751 if self._IsKeyword("Align", True):\r
2752 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2753 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2754\r
9e47e6f9 2755 if not self._GetNextToken():\r
ca957eb5 2756 raise Warning.Expected("alignment value", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2757 return True\r
2758\r
2759 return False\r
2760\r
5a6a268d 2761 ## _GetSectionData() method\r
30fdf114
LG
2762 #\r
2763 # Get section data for FILE statement\r
2764 #\r
2765 # @param self The object pointer\r
2766 # @param FfsFileObj for whom section is got\r
30fdf114 2767 #\r
5a6a268d 2768 def _GetSectionData(self, FfsFileObj):\r
9e47e6f9 2769 self._GetDefineStatements(FfsFileObj)\r
30fdf114 2770\r
30fdf114 2771 while True:\r
5a6a268d 2772 IsLeafSection = self._GetLeafSection(FfsFileObj)\r
9e47e6f9 2773 IsEncapSection = self._GetEncapsulationSec(FfsFileObj)\r
30fdf114
LG
2774 if not IsLeafSection and not IsEncapSection:\r
2775 break\r
2776\r
9e47e6f9 2777 ## _GetLeafSection() method\r
30fdf114
LG
2778 #\r
2779 # Get leaf section for Obj\r
2780 #\r
2781 # @param self The object pointer\r
2782 # @param Obj for whom leaf section is got\r
30fdf114
LG
2783 # @retval True Successfully find section statement\r
2784 # @retval False Not able to find section statement\r
2785 #\r
5a6a268d 2786 def _GetLeafSection(self, Obj):\r
30fdf114
LG
2787 OldPos = self.GetFileBufferPos()\r
2788\r
9e47e6f9 2789 if not self._IsKeyword("SECTION"):\r
30fdf114 2790 if len(Obj.SectionList) == 0:\r
ca957eb5 2791 raise Warning.Expected("SECTION", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2792 else:\r
2793 return False\r
2794\r
2795 AlignValue = None\r
9e47e6f9
CJ
2796 if self._GetAlignment():\r
2797 if self._Token not in ALIGNMENTS:\r
2798 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
2799 AlignValue = self._Token\r
30fdf114
LG
2800\r
2801 BuildNum = None\r
9e47e6f9
CJ
2802 if self._IsKeyword("BUILD_NUM"):\r
2803 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2804 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 2805\r
9e47e6f9 2806 if not self._GetNextToken():\r
ca957eb5 2807 raise Warning.Expected("Build number value", self.FileName, self.CurrentLineNumber)\r
30fdf114 2808\r
9e47e6f9 2809 BuildNum = self._Token\r
30fdf114 2810\r
9e47e6f9 2811 if self._IsKeyword("VERSION"):\r
52302d4d
LG
2812 if AlignValue == 'Auto':\r
2813 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2814 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2815 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2816 if not self._GetNextToken():\r
ca957eb5 2817 raise Warning.Expected("version", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2818 VerSectionObj = VerSection()\r
30fdf114
LG
2819 VerSectionObj.Alignment = AlignValue\r
2820 VerSectionObj.BuildNum = BuildNum\r
9e47e6f9
CJ
2821 if self._GetStringData():\r
2822 VerSectionObj.StringData = self._Token\r
30fdf114 2823 else:\r
9e47e6f9 2824 VerSectionObj.FileName = self._Token\r
30fdf114 2825 Obj.SectionList.append(VerSectionObj)\r
f7496d71 2826\r
9e47e6f9 2827 elif self._IsKeyword(BINARY_FILE_TYPE_UI):\r
52302d4d
LG
2828 if AlignValue == 'Auto':\r
2829 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2830 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2831 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2832 if not self._GetNextToken():\r
ca957eb5 2833 raise Warning.Expected("UI", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2834 UiSectionObj = UiSection()\r
30fdf114 2835 UiSectionObj.Alignment = AlignValue\r
9e47e6f9
CJ
2836 if self._GetStringData():\r
2837 UiSectionObj.StringData = self._Token\r
30fdf114 2838 else:\r
9e47e6f9 2839 UiSectionObj.FileName = self._Token\r
30fdf114
LG
2840 Obj.SectionList.append(UiSectionObj)\r
2841\r
9e47e6f9 2842 elif self._IsKeyword("FV_IMAGE"):\r
52302d4d
LG
2843 if AlignValue == 'Auto':\r
2844 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2845 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2846 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2847 if not self._GetNextToken():\r
ca957eb5 2848 raise Warning.Expected("FV name or FV file path", self.FileName, self.CurrentLineNumber)\r
30fdf114 2849\r
9e47e6f9 2850 FvName = self._Token\r
30fdf114
LG
2851 FvObj = None\r
2852\r
9e47e6f9
CJ
2853 if self._IsToken("{"):\r
2854 FvObj = FV()\r
30fdf114 2855 FvObj.UiFvName = FvName.upper()\r
9e47e6f9 2856 self._GetDefineStatements(FvObj)\r
5a6a268d 2857\r
9e47e6f9
CJ
2858 self._GetBlockStatement(FvObj)\r
2859 self._GetSetStatements(FvObj)\r
2860 self._GetFvAlignment(FvObj)\r
2861 self._GetFvAttributes(FvObj)\r
30fdf114
LG
2862\r
2863 while True:\r
9e47e6f9 2864 IsInf = self._GetInfStatement(FvObj)\r
5a6a268d 2865 IsFile = self._GetFileStatement(FvObj)\r
30fdf114
LG
2866 if not IsInf and not IsFile:\r
2867 break\r
2868\r
ea98a825 2869 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2870 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 2871\r
9e47e6f9 2872 FvImageSectionObj = FvImageSection()\r
30fdf114 2873 FvImageSectionObj.Alignment = AlignValue\r
4231a819 2874 if FvObj is not None:\r
30fdf114
LG
2875 FvImageSectionObj.Fv = FvObj\r
2876 FvImageSectionObj.FvName = None\r
2877 else:\r
2878 FvImageSectionObj.FvName = FvName.upper()\r
2879 FvImageSectionObj.FvFileName = FvName\r
2880\r
2881 Obj.SectionList.append(FvImageSectionObj)\r
2882\r
9e47e6f9 2883 elif self._IsKeyword("PEI_DEPEX_EXP") or self._IsKeyword("DXE_DEPEX_EXP") or self._IsKeyword("SMM_DEPEX_EXP"):\r
52302d4d
LG
2884 if AlignValue == 'Auto':\r
2885 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2886 DepexSectionObj = DepexSection()\r
30fdf114 2887 DepexSectionObj.Alignment = AlignValue\r
9e47e6f9 2888 DepexSectionObj.DepexType = self._Token\r
30fdf114 2889\r
9e47e6f9 2890 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 2891 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 2892 if not self._IsToken("{"):\r
ca957eb5 2893 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
ea98a825 2894 if not self._SkipToToken(T_CHAR_BRACE_R):\r
ca957eb5 2895 raise Warning.Expected("Depex expression ending '}'", self.FileName, self.CurrentLineNumber)\r
30fdf114 2896\r
ea98a825 2897 DepexSectionObj.Expression = self._SkippedChars.rstrip(T_CHAR_BRACE_R)\r
30fdf114
LG
2898 Obj.SectionList.append(DepexSectionObj)\r
2899\r
2900 else:\r
9e47e6f9 2901 if not self._GetNextWord():\r
ca957eb5 2902 raise Warning.Expected("section type", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
2903\r
2904 # Encapsulation section appear, UndoToken and return\r
9e47e6f9 2905 if self._Token == "COMPRESS" or self._Token == "GUIDED":\r
30fdf114
LG
2906 self.SetFileBufferPos(OldPos)\r
2907 return False\r
2908\r
5a264f28
CJ
2909 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,\\r
2910 BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX}:\r
9e47e6f9
CJ
2911 raise Warning("Unknown section type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
2912 if AlignValue == 'Auto'and (not self._Token == BINARY_FILE_TYPE_PE32) and (not self._Token == BINARY_FILE_TYPE_TE):\r
52302d4d
LG
2913 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
2914\r
30fdf114 2915 # DataSection\r
9e47e6f9 2916 DataSectionObj = DataSection()\r
30fdf114 2917 DataSectionObj.Alignment = AlignValue\r
9e47e6f9 2918 DataSectionObj.SecType = self._Token\r
30fdf114 2919\r
9e47e6f9
CJ
2920 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
2921 if self._FileCouldHaveRelocFlag(Obj.FvFileType) and self._SectionCouldHaveRelocFlag(DataSectionObj.SecType):\r
2922 if self._Token == 'RELOCS_STRIPPED':\r
30fdf114
LG
2923 DataSectionObj.KeepReloc = False\r
2924 else:\r
2925 DataSectionObj.KeepReloc = True\r
2926 else:\r
2927 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)\r
2928\r
9e47e6f9
CJ
2929 if self._IsToken(TAB_EQUAL_SPLIT):\r
2930 if not self._GetNextToken():\r
ca957eb5 2931 raise Warning.Expected("section file path", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
2932 DataSectionObj.SectFileName = self._Token\r
2933 self._VerifyFile(DataSectionObj.SectFileName)\r
30fdf114 2934 else:\r
9e47e6f9 2935 if not self._GetCglSection(DataSectionObj):\r
30fdf114
LG
2936 return False\r
2937\r
2938 Obj.SectionList.append(DataSectionObj)\r
2939\r
2940 return True\r
2941\r
9e47e6f9 2942 ## _VerifyFile\r
2bc3256c
LG
2943 #\r
2944 # Check if file exists or not:\r
2945 # If current phase if GenFds, the file must exist;\r
2946 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist\r
2947 # @param FileName: File path to be verified.\r
2948 #\r
9e47e6f9
CJ
2949 def _VerifyFile(self, FileName):\r
2950 if FileName.replace(TAB_WORKSPACE, '').find('$') != -1:\r
2bc3256c 2951 return\r
9e47e6f9 2952 if not GlobalData.gAutoGenPhase or not self._GetMacroValue(TAB_DSC_DEFINES_OUTPUT_DIRECTORY) in FileName:\r
2bc3256c
LG
2953 ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
2954 if ErrorCode != 0:\r
2955 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
2956\r
9e47e6f9 2957 ## _GetCglSection() method\r
30fdf114
LG
2958 #\r
2959 # Get compressed or GUIDed section for Obj\r
2960 #\r
2961 # @param self The object pointer\r
2962 # @param Obj for whom leaf section is got\r
2963 # @param AlignValue alignment value for complex section\r
2964 # @retval True Successfully find section statement\r
2965 # @retval False Not able to find section statement\r
2966 #\r
9e47e6f9 2967 def _GetCglSection(self, Obj, AlignValue = None):\r
30fdf114 2968\r
9e47e6f9 2969 if self._IsKeyword("COMPRESS"):\r
30fdf114 2970 type = "PI_STD"\r
9e47e6f9
CJ
2971 if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"):\r
2972 type = self._Token\r
30fdf114 2973\r
9e47e6f9 2974 if not self._IsToken("{"):\r
ca957eb5 2975 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
30fdf114 2976\r
9e47e6f9 2977 CompressSectionObj = CompressSection()\r
30fdf114
LG
2978 CompressSectionObj.Alignment = AlignValue\r
2979 CompressSectionObj.CompType = type\r
2980 # Recursive sections...\r
2981 while True:\r
9e47e6f9
CJ
2982 IsLeafSection = self._GetLeafSection(CompressSectionObj)\r
2983 IsEncapSection = self._GetEncapsulationSec(CompressSectionObj)\r
30fdf114
LG
2984 if not IsLeafSection and not IsEncapSection:\r
2985 break\r
2986\r
2987\r
ea98a825 2988 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 2989 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 2990 Obj.SectionList.append(CompressSectionObj)\r
30fdf114
LG
2991 return True\r
2992\r
9e47e6f9 2993 elif self._IsKeyword("GUIDED"):\r
30fdf114 2994 GuidValue = None\r
9e47e6f9
CJ
2995 if self._GetNextGuid():\r
2996 GuidValue = self._Token\r
30fdf114 2997\r
9e47e6f9
CJ
2998 AttribDict = self._GetGuidAttrib()\r
2999 if not self._IsToken("{"):\r
ca957eb5 3000 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3001 GuidSectionObj = GuidSection()\r
30fdf114
LG
3002 GuidSectionObj.Alignment = AlignValue\r
3003 GuidSectionObj.NameGuid = GuidValue\r
3004 GuidSectionObj.SectionType = "GUIDED"\r
3005 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]\r
3006 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]\r
25918452 3007 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]\r
30fdf114
LG
3008 # Recursive sections...\r
3009 while True:\r
9e47e6f9
CJ
3010 IsLeafSection = self._GetLeafSection(GuidSectionObj)\r
3011 IsEncapSection = self._GetEncapsulationSec(GuidSectionObj)\r
30fdf114
LG
3012 if not IsLeafSection and not IsEncapSection:\r
3013 break\r
3014\r
ea98a825 3015 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 3016 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3017 Obj.SectionList.append(GuidSectionObj)\r
3018\r
3019 return True\r
3020\r
3021 return False\r
3022\r
9e47e6f9 3023 ## _GetGuidAttri() method\r
30fdf114
LG
3024 #\r
3025 # Get attributes for GUID section\r
3026 #\r
3027 # @param self The object pointer\r
3028 # @retval AttribDict Dictionary of key-value pair of section attributes\r
3029 #\r
9e47e6f9 3030 def _GetGuidAttrib(self):\r
30fdf114 3031 AttribDict = {}\r
14c48571 3032 AttribDict["PROCESSING_REQUIRED"] = "NONE"\r
3033 AttribDict["AUTH_STATUS_VALID"] = "NONE"\r
25918452 3034 AttribDict["EXTRA_HEADER_SIZE"] = -1\r
9e47e6f9
CJ
3035 while self._IsKeyword("PROCESSING_REQUIRED") or self._IsKeyword("AUTH_STATUS_VALID") \\r
3036 or self._IsKeyword("EXTRA_HEADER_SIZE"):\r
3037 AttribKey = self._Token\r
30fdf114 3038\r
9e47e6f9 3039 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3040 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 3041\r
9e47e6f9 3042 if not self._GetNextToken():\r
ca957eb5 3043 raise Warning.Expected("TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber)\r
25918452
LG
3044 elif AttribKey == "EXTRA_HEADER_SIZE":\r
3045 Base = 10\r
9e47e6f9 3046 if self._Token[0:2].upper() == "0X":\r
25918452
LG
3047 Base = 16\r
3048 try:\r
9e47e6f9 3049 AttribDict[AttribKey] = int(self._Token, Base)\r
25918452
LG
3050 continue\r
3051 except ValueError:\r
ca957eb5 3052 raise Warning.Expected("Number", self.FileName, self.CurrentLineNumber)\r
5a264f28 3053 elif self._Token.upper() not in {"TRUE", "FALSE", "1", "0"}:\r
ca957eb5 3054 raise Warning.Expected("TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3055 AttribDict[AttribKey] = self._Token\r
30fdf114
LG
3056\r
3057 return AttribDict\r
3058\r
9e47e6f9 3059 ## _GetEncapsulationSec() method\r
30fdf114
LG
3060 #\r
3061 # Get encapsulation section for FILE\r
3062 #\r
3063 # @param self The object pointer\r
3064 # @param FfsFile for whom section is got\r
3065 # @retval True Successfully find section statement\r
3066 # @retval False Not able to find section statement\r
3067 #\r
9e47e6f9 3068 def _GetEncapsulationSec(self, FfsFileObj):\r
30fdf114 3069 OldPos = self.GetFileBufferPos()\r
9e47e6f9 3070 if not self._IsKeyword("SECTION"):\r
30fdf114 3071 if len(FfsFileObj.SectionList) == 0:\r
ca957eb5 3072 raise Warning.Expected("SECTION", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3073 else:\r
3074 return False\r
3075\r
3076 AlignValue = None\r
9e47e6f9
CJ
3077 if self._GetAlignment():\r
3078 if self._Token not in ALIGNMENT_NOAUTO:\r
3079 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3080 AlignValue = self._Token\r
30fdf114 3081\r
9e47e6f9 3082 if not self._GetCglSection(FfsFileObj, AlignValue):\r
30fdf114
LG
3083 self.SetFileBufferPos(OldPos)\r
3084 return False\r
3085 else:\r
3086 return True\r
3087\r
9e47e6f9
CJ
3088 def _GetFmp(self):\r
3089 if not self._GetNextToken():\r
a3251d84 3090 return False\r
9e47e6f9
CJ
3091 S = self._Token.upper()\r
3092 if S.startswith(TAB_SECTION_START) and not S.startswith("[FMPPAYLOAD."):\r
df81077f 3093 self.SectionParser(S)\r
9e47e6f9 3094 self._UndoToken()\r
a3251d84
YL
3095 return False\r
3096\r
9e47e6f9
CJ
3097 self._UndoToken()\r
3098 self._SkipToToken("[FMPPAYLOAD.", True)\r
3099 FmpUiName = self._GetUiName().upper()\r
a3251d84
YL
3100 if FmpUiName in self.Profile.FmpPayloadDict:\r
3101 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName, self.FileName, self.CurrentLineNumber)\r
3102\r
9e47e6f9 3103 FmpData = CapsulePayload()\r
a3251d84
YL
3104 FmpData.UiName = FmpUiName\r
3105\r
9e47e6f9 3106 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 3107 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
a3251d84 3108\r
9e47e6f9 3109 if not self._GetNextToken():\r
a3251d84 3110 raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber)\r
91ae2988 3111 FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']\r
9e47e6f9
CJ
3112 while self._Token in FmpKeyList:\r
3113 Name = self._Token\r
a3251d84 3114 FmpKeyList.remove(Name)\r
9e47e6f9 3115 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3116 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
a3251d84 3117 if Name == 'IMAGE_TYPE_ID':\r
9e47e6f9 3118 if not self._GetNextGuid():\r
ca957eb5 3119 raise Warning.Expected("GUID value for IMAGE_TYPE_ID.", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3120 FmpData.ImageTypeId = self._Token\r
91ae2988 3121 elif Name == 'CERTIFICATE_GUID':\r
9e47e6f9 3122 if not self._GetNextGuid():\r
ca957eb5 3123 raise Warning.Expected("GUID value for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3124 FmpData.Certificate_Guid = self._Token\r
3125 if UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_RSA2048_SHA256_GUID and UUID(FmpData.Certificate_Guid) != EFI_CERT_TYPE_PKCS7_GUID:\r
91ae2988 3126 raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self.FileName, self.CurrentLineNumber)\r
a3251d84 3127 else:\r
9e47e6f9 3128 if not self._GetNextToken():\r
ca957eb5 3129 raise Warning.Expected("value of %s" % Name, self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3130 Value = self._Token\r
a3251d84 3131 if Name == 'IMAGE_HEADER_INIT_VERSION':\r
9e47e6f9 3132 if FdfParser._Verify(Name, Value, 'UINT8'):\r
91ae2988 3133 FmpData.Version = Value\r
a3251d84 3134 elif Name == 'IMAGE_INDEX':\r
9e47e6f9 3135 if FdfParser._Verify(Name, Value, 'UINT8'):\r
91ae2988 3136 FmpData.ImageIndex = Value\r
a3251d84 3137 elif Name == 'HARDWARE_INSTANCE':\r
9e47e6f9 3138 if FdfParser._Verify(Name, Value, 'UINT8'):\r
91ae2988
YZ
3139 FmpData.HardwareInstance = Value\r
3140 elif Name == 'MONOTONIC_COUNT':\r
9e47e6f9 3141 if FdfParser._Verify(Name, Value, 'UINT64'):\r
91ae2988
YZ
3142 FmpData.MonotonicCount = Value\r
3143 if FmpData.MonotonicCount.upper().startswith('0X'):\r
1ccc4d89 3144 FmpData.MonotonicCount = (long)(FmpData.MonotonicCount, 16)\r
91ae2988 3145 else:\r
1ccc4d89 3146 FmpData.MonotonicCount = (long)(FmpData.MonotonicCount)\r
9e47e6f9 3147 if not self._GetNextToken():\r
a3251d84
YL
3148 break\r
3149 else:\r
9e47e6f9 3150 self._UndoToken()\r
a3251d84 3151\r
91ae2988
YZ
3152 if (FmpData.MonotonicCount and not FmpData.Certificate_Guid) or (not FmpData.MonotonicCount and FmpData.Certificate_Guid):\r
3153 EdkLogger.error("FdfParser", FORMAT_INVALID, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")\r
9ce9bf53
YZ
3154\r
3155 # Only the IMAGE_TYPE_ID is required item\r
3156 if FmpKeyList and 'IMAGE_TYPE_ID' in FmpKeyList:\r
ca957eb5 3157 raise Warning("'IMAGE_TYPE_ID' in FMP payload section.", self.FileName, self.CurrentLineNumber)\r
19e3aa7a 3158 # get the Image file and Vendor code file\r
9e47e6f9 3159 self._GetFMPCapsuleData(FmpData)\r
19e3aa7a 3160 if not FmpData.ImageFile:\r
91ae2988 3161 raise Warning("Missing image file in FMP payload section.", self.FileName, self.CurrentLineNumber)\r
19e3aa7a
YZ
3162 # check whether more than one Vendor code file\r
3163 if len(FmpData.VendorCodeFile) > 1:\r
ca957eb5 3164 raise Warning("Vendor code file max of 1 per FMP payload section.", self.FileName, self.CurrentLineNumber)\r
a3251d84
YL
3165 self.Profile.FmpPayloadDict[FmpUiName] = FmpData\r
3166 return True\r
3167\r
9e47e6f9 3168 ## _GetCapsule() method\r
30fdf114
LG
3169 #\r
3170 # Get capsule section contents and store its data into capsule list of self.Profile\r
3171 #\r
3172 # @param self The object pointer\r
3173 # @retval True Successfully find a capsule\r
3174 # @retval False Not able to find a capsule\r
3175 #\r
9e47e6f9
CJ
3176 def _GetCapsule(self):\r
3177 if not self._GetNextToken():\r
30fdf114
LG
3178 return False\r
3179\r
9e47e6f9
CJ
3180 S = self._Token.upper()\r
3181 if S.startswith(TAB_SECTION_START) and not S.startswith("[CAPSULE."):\r
df81077f 3182 self.SectionParser(S)\r
9e47e6f9 3183 self._UndoToken()\r
30fdf114
LG
3184 return False\r
3185\r
9e47e6f9
CJ
3186 self._UndoToken()\r
3187 if not self._IsToken("[CAPSULE.", True):\r
30fdf114
LG
3188 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
3189 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9 3190 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
ca957eb5 3191 raise Warning.Expected("[Capsule.]", self.FileName, self.CurrentLineNumber)\r
30fdf114 3192\r
9e47e6f9 3193 CapsuleObj = Capsule()\r
30fdf114 3194\r
9e47e6f9 3195 CapsuleName = self._GetUiName()\r
30fdf114 3196 if not CapsuleName:\r
ca957eb5 3197 raise Warning.Expected("capsule name", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3198\r
3199 CapsuleObj.UiCapsuleName = CapsuleName.upper()\r
3200\r
9e47e6f9 3201 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 3202 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 3203\r
9e47e6f9
CJ
3204 if self._IsKeyword("CREATE_FILE"):\r
3205 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3206 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 3207\r
9e47e6f9 3208 if not self._GetNextToken():\r
ca957eb5 3209 raise Warning.Expected("file name", self.FileName, self.CurrentLineNumber)\r
30fdf114 3210\r
9e47e6f9 3211 CapsuleObj.CreateFile = self._Token\r
30fdf114 3212\r
9e47e6f9 3213 self._GetCapsuleStatements(CapsuleObj)\r
fd171542 3214 self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj\r
30fdf114
LG
3215 return True\r
3216\r
9e47e6f9 3217 ## _GetCapsuleStatements() method\r
30fdf114
LG
3218 #\r
3219 # Get statements for capsule\r
3220 #\r
3221 # @param self The object pointer\r
3222 # @param Obj for whom statements are got\r
3223 #\r
9e47e6f9
CJ
3224 def _GetCapsuleStatements(self, Obj):\r
3225 self._GetCapsuleTokens(Obj)\r
3226 self._GetDefineStatements(Obj)\r
3227 self._GetSetStatements(Obj)\r
3228 self._GetCapsuleData(Obj)\r
30fdf114 3229\r
9e47e6f9 3230 ## _GetCapsuleTokens() method\r
30fdf114
LG
3231 #\r
3232 # Get token statements for capsule\r
3233 #\r
3234 # @param self The object pointer\r
3235 # @param Obj for whom token statements are got\r
3236 #\r
9e47e6f9
CJ
3237 def _GetCapsuleTokens(self, Obj):\r
3238 if not self._GetNextToken():\r
b303ea72 3239 return False\r
5a264f28 3240 while self._Token in {"CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"}:\r
9e47e6f9
CJ
3241 Name = self._Token.strip()\r
3242 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3243 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3244 if not self._GetNextToken():\r
ca957eb5 3245 raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)\r
b303ea72 3246 if Name == 'CAPSULE_FLAGS':\r
5a264f28 3247 if not self._Token in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:\r
ca957eb5 3248 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3249 Value = self._Token.strip()\r
3250 while self._IsToken(TAB_COMMA_SPLIT):\r
3251 Value += TAB_COMMA_SPLIT\r
3252 if not self._GetNextToken():\r
ca957eb5 3253 raise Warning.Expected("value", self.FileName, self.CurrentLineNumber)\r
5a264f28 3254 if not self._Token in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:\r
ca957eb5 3255 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3256 Value += self._Token.strip()\r
e8a47801 3257 elif Name == 'OEM_CAPSULE_FLAGS':\r
9e47e6f9 3258 Value = self._Token.strip()\r
2bc3256c 3259 if not Value.upper().startswith('0X'):\r
ca957eb5 3260 raise Warning.Expected("hex value starting with 0x", self.FileName, self.CurrentLineNumber)\r
e8a47801
LG
3261 try:\r
3262 Value = int(Value, 0)\r
3263 except ValueError:\r
ca957eb5 3264 raise Warning.Expected("hex string failed to convert to value", self.FileName, self.CurrentLineNumber)\r
e8a47801 3265 if not 0x0000 <= Value <= 0xFFFF:\r
ca957eb5 3266 raise Warning.Expected("hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3267 Value = self._Token.strip()\r
b303ea72 3268 else:\r
9e47e6f9 3269 Value = self._Token.strip()\r
f7496d71 3270 Obj.TokensDict[Name] = Value\r
9e47e6f9 3271 if not self._GetNextToken():\r
b303ea72 3272 return False\r
9e47e6f9 3273 self._UndoToken()\r
30fdf114 3274\r
9e47e6f9 3275 ## _GetCapsuleData() method\r
30fdf114
LG
3276 #\r
3277 # Get capsule data for capsule\r
3278 #\r
3279 # @param self The object pointer\r
3280 # @param Obj for whom capsule data are got\r
3281 #\r
9e47e6f9 3282 def _GetCapsuleData(self, Obj):\r
30fdf114 3283 while True:\r
9e47e6f9
CJ
3284 IsInf = self._GetInfStatement(Obj, True)\r
3285 IsFile = self._GetFileStatement(Obj, True)\r
3286 IsFv = self._GetFvStatement(Obj)\r
3287 IsFd = self._GetFdStatement(Obj)\r
3288 IsAnyFile = self._GetAnyFileStatement(Obj)\r
3289 IsAfile = self._GetAfileStatement(Obj)\r
3290 IsFmp = self._GetFmpStatement(Obj)\r
a3251d84 3291 if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp):\r
30fdf114
LG
3292 break\r
3293\r
9e47e6f9 3294 ## _GetFMPCapsuleData() method\r
19e3aa7a
YZ
3295 #\r
3296 # Get capsule data for FMP capsule\r
3297 #\r
3298 # @param self The object pointer\r
3299 # @param Obj for whom capsule data are got\r
3300 #\r
9e47e6f9 3301 def _GetFMPCapsuleData(self, Obj):\r
19e3aa7a 3302 while True:\r
9e47e6f9
CJ
3303 IsFv = self._GetFvStatement(Obj, True)\r
3304 IsFd = self._GetFdStatement(Obj, True)\r
3305 IsAnyFile = self._GetAnyFileStatement(Obj, True)\r
19e3aa7a
YZ
3306 if not (IsFv or IsFd or IsAnyFile):\r
3307 break\r
3308\r
9e47e6f9 3309 ## _GetFvStatement() method\r
30fdf114
LG
3310 #\r
3311 # Get FV for capsule\r
3312 #\r
3313 # @param self The object pointer\r
3314 # @param CapsuleObj for whom FV is got\r
3315 # @retval True Successfully find a FV statement\r
3316 # @retval False Not able to find a FV statement\r
3317 #\r
9e47e6f9
CJ
3318 def _GetFvStatement(self, CapsuleObj, FMPCapsule = False):\r
3319 if not self._IsKeyword(BINARY_FILE_TYPE_FV):\r
30fdf114
LG
3320 return False\r
3321\r
9e47e6f9 3322 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3323 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 3324\r
9e47e6f9 3325 if not self._GetNextToken():\r
ca957eb5 3326 raise Warning.Expected("FV name", self.FileName, self.CurrentLineNumber)\r
30fdf114 3327\r
9e47e6f9 3328 if self._Token.upper() not in self.Profile.FvDict:\r
2bcc713e
LG
3329 raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)\r
3330\r
9e47e6f9
CJ
3331 myCapsuleFv = CapsuleFv()\r
3332 myCapsuleFv.FvName = self._Token\r
19e3aa7a
YZ
3333 if FMPCapsule:\r
3334 if not CapsuleObj.ImageFile:\r
9e47e6f9 3335 CapsuleObj.ImageFile.append(myCapsuleFv)\r
19e3aa7a 3336 else:\r
9e47e6f9 3337 CapsuleObj.VendorCodeFile.append(myCapsuleFv)\r
19e3aa7a 3338 else:\r
9e47e6f9 3339 CapsuleObj.CapsuleDataList.append(myCapsuleFv)\r
30fdf114
LG
3340 return True\r
3341\r
9e47e6f9 3342 ## _GetFdStatement() method\r
b36d134f
LG
3343 #\r
3344 # Get FD for capsule\r
3345 #\r
3346 # @param self The object pointer\r
3347 # @param CapsuleObj for whom FD is got\r
3348 # @retval True Successfully find a FD statement\r
3349 # @retval False Not able to find a FD statement\r
3350 #\r
9e47e6f9
CJ
3351 def _GetFdStatement(self, CapsuleObj, FMPCapsule = False):\r
3352 if not self._IsKeyword("FD"):\r
b36d134f
LG
3353 return False\r
3354\r
9e47e6f9 3355 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3356 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
b36d134f 3357\r
9e47e6f9 3358 if not self._GetNextToken():\r
ca957eb5 3359 raise Warning.Expected("FD name", self.FileName, self.CurrentLineNumber)\r
b36d134f 3360\r
9e47e6f9 3361 if self._Token.upper() not in self.Profile.FdDict:\r
2bcc713e
LG
3362 raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)\r
3363\r
9e47e6f9
CJ
3364 myCapsuleFd = CapsuleFd()\r
3365 myCapsuleFd.FdName = self._Token\r
19e3aa7a
YZ
3366 if FMPCapsule:\r
3367 if not CapsuleObj.ImageFile:\r
9e47e6f9 3368 CapsuleObj.ImageFile.append(myCapsuleFd)\r
19e3aa7a 3369 else:\r
9e47e6f9 3370 CapsuleObj.VendorCodeFile.append(myCapsuleFd)\r
19e3aa7a 3371 else:\r
9e47e6f9 3372 CapsuleObj.CapsuleDataList.append(myCapsuleFd)\r
b36d134f
LG
3373 return True\r
3374\r
9e47e6f9
CJ
3375 def _GetFmpStatement(self, CapsuleObj):\r
3376 if not self._IsKeyword("FMP_PAYLOAD"):\r
3377 if not self._IsKeyword("FMP"):\r
df81077f 3378 return False\r
b36d134f 3379\r
9e47e6f9
CJ
3380 if not self._IsKeyword("PAYLOAD"):\r
3381 self._UndoToken()\r
df81077f 3382 return False\r
b36d134f 3383\r
9e47e6f9 3384 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3385 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
a3251d84 3386\r
9e47e6f9 3387 if not self._GetNextToken():\r
ca957eb5 3388 raise Warning.Expected("payload name after FMP_PAYLOAD =", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3389 Payload = self._Token.upper()\r
a3251d84 3390 if Payload not in self.Profile.FmpPayloadDict:\r
9e47e6f9 3391 raise Warning("This FMP Payload does not exist: %s" % self._Token, self.FileName, self.CurrentLineNumber)\r
a3251d84
YL
3392 CapsuleObj.FmpPayloadList.append(self.Profile.FmpPayloadDict[Payload])\r
3393 return True\r
3394\r
9e47e6f9
CJ
3395 def _ParseRawFileStatement(self):\r
3396 if not self._IsKeyword("FILE"):\r
a3251d84
YL
3397 return None\r
3398\r
9e47e6f9
CJ
3399 if not self._IsKeyword("DATA"):\r
3400 self._UndoToken()\r
a3251d84 3401 return None\r
b36d134f 3402\r
9e47e6f9 3403 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3404 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
b36d134f 3405\r
9e47e6f9 3406 if not self._GetNextToken():\r
ca957eb5 3407 raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)\r
f7496d71 3408\r
9e47e6f9
CJ
3409 AnyFileName = self._Token\r
3410 self._VerifyFile(AnyFileName)\r
35217a33 3411\r
94e4bcbb
YZ
3412 if not os.path.isabs(AnyFileName):\r
3413 AnyFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, AnyFileName)\r
3414\r
a3251d84
YL
3415 return AnyFileName\r
3416\r
9e47e6f9 3417 ## _GetAnyFileStatement() method\r
a3251d84
YL
3418 #\r
3419 # Get AnyFile for capsule\r
3420 #\r
3421 # @param self The object pointer\r
3422 # @param CapsuleObj for whom AnyFile is got\r
3423 # @retval True Successfully find a Anyfile statement\r
3424 # @retval False Not able to find a AnyFile statement\r
3425 #\r
9e47e6f9
CJ
3426 def _GetAnyFileStatement(self, CapsuleObj, FMPCapsule = False):\r
3427 AnyFileName = self._ParseRawFileStatement()\r
a3251d84
YL
3428 if not AnyFileName:\r
3429 return False\r
b36d134f 3430\r
9e47e6f9
CJ
3431 myCapsuleAnyFile = CapsuleAnyFile()\r
3432 myCapsuleAnyFile.FileName = AnyFileName\r
19e3aa7a
YZ
3433 if FMPCapsule:\r
3434 if not CapsuleObj.ImageFile:\r
9e47e6f9 3435 CapsuleObj.ImageFile.append(myCapsuleAnyFile)\r
19e3aa7a 3436 else:\r
9e47e6f9 3437 CapsuleObj.VendorCodeFile.append(myCapsuleAnyFile)\r
19e3aa7a 3438 else:\r
9e47e6f9 3439 CapsuleObj.CapsuleDataList.append(myCapsuleAnyFile)\r
b36d134f 3440 return True\r
f7496d71 3441\r
9e47e6f9 3442 ## _GetAfileStatement() method\r
2bc3256c
LG
3443 #\r
3444 # Get Afile for capsule\r
3445 #\r
3446 # @param self The object pointer\r
3447 # @param CapsuleObj for whom Afile is got\r
3448 # @retval True Successfully find a Afile statement\r
3449 # @retval False Not able to find a Afile statement\r
3450 #\r
9e47e6f9
CJ
3451 def _GetAfileStatement(self, CapsuleObj):\r
3452 if not self._IsKeyword("APPEND"):\r
2bc3256c
LG
3453 return False\r
3454\r
9e47e6f9 3455 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3456 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
2bc3256c 3457\r
9e47e6f9 3458 if not self._GetNextToken():\r
ca957eb5 3459 raise Warning.Expected("Afile name", self.FileName, self.CurrentLineNumber)\r
f7496d71 3460\r
9e47e6f9 3461 AfileName = self._Token\r
2bc3256c 3462 AfileBaseName = os.path.basename(AfileName)\r
f7496d71 3463\r
5a264f28 3464 if os.path.splitext(AfileBaseName)[1] not in {".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"}:\r
91fa33ee 3465 raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \\r
2bc3256c 3466 self.FileName, self.CurrentLineNumber)\r
f7496d71 3467\r
2bc3256c
LG
3468 if not os.path.isabs(AfileName):\r
3469 AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName)\r
9e47e6f9 3470 self._VerifyFile(AfileName)\r
2bc3256c
LG
3471 else:\r
3472 if not os.path.exists(AfileName):\r
3473 raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber)\r
3474 else:\r
3475 pass\r
3476\r
9e47e6f9
CJ
3477 myCapsuleAfile = CapsuleAfile()\r
3478 myCapsuleAfile.FileName = AfileName\r
3479 CapsuleObj.CapsuleDataList.append(myCapsuleAfile)\r
2bc3256c 3480 return True\r
b36d134f 3481\r
9e47e6f9 3482 ## _GetRule() method\r
30fdf114
LG
3483 #\r
3484 # Get Rule section contents and store its data into rule list of self.Profile\r
3485 #\r
3486 # @param self The object pointer\r
3487 # @retval True Successfully find a Rule\r
3488 # @retval False Not able to find a Rule\r
3489 #\r
9e47e6f9
CJ
3490 def _GetRule(self):\r
3491 if not self._GetNextToken():\r
30fdf114
LG
3492 return False\r
3493\r
9e47e6f9
CJ
3494 S = self._Token.upper()\r
3495 if S.startswith(TAB_SECTION_START) and not S.startswith("[RULE."):\r
df81077f 3496 self.SectionParser(S)\r
9e47e6f9 3497 self._UndoToken()\r
30fdf114 3498 return False\r
9e47e6f9
CJ
3499 self._UndoToken()\r
3500 if not self._IsToken("[Rule.", True):\r
30fdf114
LG
3501 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
3502 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9 3503 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
ca957eb5 3504 raise Warning.Expected("[Rule.]", self.FileName, self.CurrentLineNumber)\r
30fdf114 3505\r
9e47e6f9 3506 if not self._SkipToToken(TAB_SPLIT):\r
ca957eb5 3507 raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber)\r
30fdf114 3508\r
9e47e6f9 3509 Arch = self._SkippedChars.rstrip(TAB_SPLIT)\r
eece4292 3510 if Arch.upper() not in ARCH_SET_FULL:\r
30fdf114
LG
3511 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)\r
3512\r
9e47e6f9 3513 ModuleType = self._GetModuleType()\r
30fdf114
LG
3514\r
3515 TemplateName = ""\r
9e47e6f9
CJ
3516 if self._IsToken(TAB_SPLIT):\r
3517 if not self._GetNextWord():\r
ca957eb5 3518 raise Warning.Expected("template name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3519 TemplateName = self._Token\r
30fdf114 3520\r
9e47e6f9 3521 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 3522 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 3523\r
9e47e6f9 3524 RuleObj = self._GetRuleFileStatements()\r
30fdf114
LG
3525 RuleObj.Arch = Arch.upper()\r
3526 RuleObj.ModuleType = ModuleType\r
3527 RuleObj.TemplateName = TemplateName\r
9e47e6f9 3528 if TemplateName == '':\r
30fdf114 3529 self.Profile.RuleDict['RULE' + \\r
9e47e6f9 3530 TAB_SPLIT + \\r
30fdf114 3531 Arch.upper() + \\r
9e47e6f9 3532 TAB_SPLIT + \\r
30fdf114 3533 ModuleType.upper() ] = RuleObj\r
9e47e6f9 3534 else:\r
30fdf114 3535 self.Profile.RuleDict['RULE' + \\r
9e47e6f9 3536 TAB_SPLIT + \\r
30fdf114 3537 Arch.upper() + \\r
9e47e6f9 3538 TAB_SPLIT + \\r
30fdf114 3539 ModuleType.upper() + \\r
9e47e6f9 3540 TAB_SPLIT + \\r
30fdf114 3541 TemplateName.upper() ] = RuleObj\r
30fdf114
LG
3542 return True\r
3543\r
9e47e6f9 3544 ## _GetModuleType() method\r
30fdf114
LG
3545 #\r
3546 # Return the module type\r
3547 #\r
3548 # @param self The object pointer\r
3549 # @retval string module type\r
3550 #\r
9e47e6f9
CJ
3551 def _GetModuleType(self):\r
3552 if not self._GetNextWord():\r
ca957eb5 3553 raise Warning.Expected("Module type", self.FileName, self.CurrentLineNumber)\r
5a264f28
CJ
3554 if self._Token.upper() not in {\r
3555 SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM,\r
3556 SUP_MODULE_DXE_CORE, SUP_MODULE_DXE_DRIVER,\r
3557 SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_DXE_SMM_DRIVER,\r
3558 SUP_MODULE_DXE_RUNTIME_DRIVER, SUP_MODULE_UEFI_DRIVER,\r
3559 SUP_MODULE_UEFI_APPLICATION, SUP_MODULE_USER_DEFINED,\r
3560 TAB_DEFAULT, SUP_MODULE_BASE,\r
3561 EDK_COMPONENT_TYPE_SECURITY_CORE,\r
3562 EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER,\r
3563 EDK_COMPONENT_TYPE_PIC_PEIM,\r
3564 EDK_COMPONENT_TYPE_RELOCATABLE_PEIM, "PE32_PEIM",\r
3565 EDK_COMPONENT_TYPE_BS_DRIVER, EDK_COMPONENT_TYPE_RT_DRIVER,\r
3566 EDK_COMPONENT_TYPE_SAL_RT_DRIVER,\r
3567 EDK_COMPONENT_TYPE_APPLICATION, "ACPITABLE",\r
3568 SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE,\r
3569 SUP_MODULE_MM_CORE_STANDALONE}:\r
9e47e6f9
CJ
3570 raise Warning("Unknown Module type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3571 return self._Token\r
30fdf114 3572\r
9e47e6f9 3573 ## _GetFileExtension() method\r
30fdf114
LG
3574 #\r
3575 # Return the file extension\r
3576 #\r
3577 # @param self The object pointer\r
3578 # @retval string file name extension\r
3579 #\r
9e47e6f9
CJ
3580 def _GetFileExtension(self):\r
3581 if not self._IsToken(TAB_SPLIT):\r
ca957eb5 3582 raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3583\r
3584 Ext = ""\r
9e47e6f9
CJ
3585 if self._GetNextToken():\r
3586 if FileExtensionPattern.match(self._Token):\r
3587 Ext = self._Token\r
3588 return TAB_SPLIT + Ext\r
30fdf114 3589 else:\r
9e47e6f9 3590 raise Warning("Unknown file extension '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3591\r
3592 else:\r
ca957eb5 3593 raise Warning.Expected("file extension", self.FileName, self.CurrentLineNumber)\r
30fdf114 3594\r
9e47e6f9 3595 ## _GetRuleFileStatement() method\r
30fdf114
LG
3596 #\r
3597 # Get rule contents\r
3598 #\r
3599 # @param self The object pointer\r
3600 # @retval Rule Rule object\r
3601 #\r
9e47e6f9
CJ
3602 def _GetRuleFileStatements(self):\r
3603 if not self._IsKeyword("FILE"):\r
ca957eb5 3604 raise Warning.Expected("FILE", self.FileName, self.CurrentLineNumber)\r
30fdf114 3605\r
9e47e6f9 3606 if not self._GetNextWord():\r
ca957eb5 3607 raise Warning.Expected("FFS type", self.FileName, self.CurrentLineNumber)\r
30fdf114 3608\r
9e47e6f9 3609 Type = self._Token.strip().upper()\r
5a264f28
CJ
3610 if Type not in {"RAW", "FREEFORM", SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM,\r
3611 "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE, EDK_COMPONENT_TYPE_APPLICATION,\r
3612 "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE, SUP_MODULE_MM_STANDALONE,\r
3613 SUP_MODULE_MM_CORE_STANDALONE}:\r
9e47e6f9 3614 raise Warning("Unknown FV type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114 3615\r
9e47e6f9 3616 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3617 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 3618\r
9e47e6f9
CJ
3619 if not self._IsKeyword("$(NAMED_GUID)"):\r
3620 if not self._GetNextWord():\r
ca957eb5 3621 raise Warning.Expected("$(NAMED_GUID)", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3622 if self._Token == 'PCD':\r
3623 if not self._IsToken("("):\r
ca957eb5 3624 raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3625 PcdPair = self._GetNextPcdSettings()\r
3626 if not self._IsToken(")"):\r
ca957eb5 3627 raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3628 self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'\r
f7496d71 3629\r
9e47e6f9 3630 NameGuid = self._Token\r
30fdf114
LG
3631\r
3632 KeepReloc = None\r
9e47e6f9
CJ
3633 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
3634 if self._FileCouldHaveRelocFlag(Type):\r
3635 if self._Token == 'RELOCS_STRIPPED':\r
30fdf114
LG
3636 KeepReloc = False\r
3637 else:\r
3638 KeepReloc = True\r
3639 else:\r
3640 raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3641\r
3642 KeyStringList = []\r
9e47e6f9
CJ
3643 if self._GetNextToken():\r
3644 if TokenFindPattern.match(self._Token):\r
3645 KeyStringList.append(self._Token)\r
3646 if self._IsToken(TAB_COMMA_SPLIT):\r
3647 while self._GetNextToken():\r
3648 if not TokenFindPattern.match(self._Token):\r
ca957eb5 3649 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3650 KeyStringList.append(self._Token)\r
30fdf114 3651\r
9e47e6f9 3652 if not self._IsToken(TAB_COMMA_SPLIT):\r
30fdf114
LG
3653 break\r
3654\r
3655 else:\r
9e47e6f9 3656 self._UndoToken()\r
30fdf114
LG
3657\r
3658\r
3659 Fixed = False\r
9e47e6f9 3660 if self._IsKeyword("Fixed", True):\r
30fdf114
LG
3661 Fixed = True\r
3662\r
3663 CheckSum = False\r
9e47e6f9 3664 if self._IsKeyword("CheckSum", True):\r
30fdf114
LG
3665 CheckSum = True\r
3666\r
3667 AlignValue = ""\r
9e47e6f9
CJ
3668 if self._GetAlignment():\r
3669 if self._Token not in ALIGNMENTS:\r
3670 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
52302d4d 3671 #For FFS, Auto is default option same to ""\r
9e47e6f9
CJ
3672 if not self._Token == "Auto":\r
3673 AlignValue = self._Token\r
30fdf114 3674\r
9e47e6f9 3675 if self._IsToken("{"):\r
30fdf114 3676 # Complex file rule expected\r
9e47e6f9
CJ
3677 NewRule = RuleComplexFile()\r
3678 NewRule.FvFileType = Type\r
3679 NewRule.NameGuid = NameGuid\r
3680 NewRule.Alignment = AlignValue\r
3681 NewRule.CheckSum = CheckSum\r
3682 NewRule.Fixed = Fixed\r
3683 NewRule.KeyStringList = KeyStringList\r
4231a819 3684 if KeepReloc is not None:\r
9e47e6f9 3685 NewRule.KeepReloc = KeepReloc\r
30fdf114
LG
3686\r
3687 while True:\r
9e47e6f9
CJ
3688 IsEncapsulate = self._GetRuleEncapsulationSection(NewRule)\r
3689 IsLeaf = self._GetEfiSection(NewRule)\r
30fdf114
LG
3690 if not IsEncapsulate and not IsLeaf:\r
3691 break\r
3692\r
ea98a825 3693 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 3694 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 3695\r
9e47e6f9 3696 return NewRule\r
30fdf114 3697\r
30fdf114
LG
3698 else:\r
3699 # Simple file rule expected\r
9e47e6f9 3700 if not self._GetNextWord():\r
ca957eb5 3701 raise Warning.Expected("leaf section type", self.FileName, self.CurrentLineNumber)\r
30fdf114 3702\r
9e47e6f9 3703 SectionName = self._Token\r
30fdf114 3704\r
5a264f28
CJ
3705 if SectionName not in {\r
3706 "COMPAT16", BINARY_FILE_TYPE_PE32,\r
3707 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE",\r
3708 "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,\r
3709 BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",\r
3710 BINARY_FILE_TYPE_SMM_DEPEX}:\r
30fdf114
LG
3711 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)\r
3712\r
3713\r
9e47e6f9 3714 if self._IsKeyword("Fixed", True):\r
30fdf114
LG
3715 Fixed = True\r
3716\r
9e47e6f9 3717 if self._IsKeyword("CheckSum", True):\r
30fdf114
LG
3718 CheckSum = True\r
3719\r
52302d4d 3720 SectAlignment = ""\r
9e47e6f9
CJ
3721 if self._GetAlignment():\r
3722 if self._Token not in ALIGNMENTS:\r
3723 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3724 if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE):\r
52302d4d 3725 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3726 SectAlignment = self._Token\r
52302d4d
LG
3727\r
3728 Ext = None\r
9e47e6f9
CJ
3729 if self._IsToken(TAB_VALUE_SPLIT):\r
3730 Ext = self._GetFileExtension()\r
3731 elif not self._GetNextToken():\r
ca957eb5 3732 raise Warning.Expected("File name", self.FileName, self.CurrentLineNumber)\r
30fdf114 3733\r
9e47e6f9
CJ
3734 NewRule = RuleSimpleFile()\r
3735 NewRule.SectionType = SectionName\r
3736 NewRule.FvFileType = Type\r
3737 NewRule.NameGuid = NameGuid\r
3738 NewRule.Alignment = AlignValue\r
3739 NewRule.SectAlignment = SectAlignment\r
3740 NewRule.CheckSum = CheckSum\r
3741 NewRule.Fixed = Fixed\r
3742 NewRule.KeyStringList = KeyStringList\r
4231a819 3743 if KeepReloc is not None:\r
9e47e6f9
CJ
3744 NewRule.KeepReloc = KeepReloc\r
3745 NewRule.FileExtension = Ext\r
3746 NewRule.FileName = self._Token\r
3747 return NewRule\r
30fdf114 3748\r
9e47e6f9 3749 ## _GetEfiSection() method\r
30fdf114
LG
3750 #\r
3751 # Get section list for Rule\r
3752 #\r
3753 # @param self The object pointer\r
3754 # @param Obj for whom section is got\r
3755 # @retval True Successfully find section statement\r
3756 # @retval False Not able to find section statement\r
3757 #\r
9e47e6f9 3758 def _GetEfiSection(self, Obj):\r
30fdf114 3759 OldPos = self.GetFileBufferPos()\r
9e47e6f9 3760 if not self._GetNextWord():\r
30fdf114 3761 return False\r
9e47e6f9 3762 SectionName = self._Token\r
30fdf114 3763\r
5a264f28
CJ
3764 if SectionName not in {\r
3765 "COMPAT16", BINARY_FILE_TYPE_PE32,\r
3766 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE, "FV_IMAGE",\r
3767 "RAW",BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI,\r
3768 BINARY_FILE_TYPE_PEI_DEPEX, "VERSION", "SUBTYPE_GUID",\r
3769 BINARY_FILE_TYPE_SMM_DEPEX, BINARY_FILE_TYPE_GUID}:\r
9e47e6f9 3770 self._UndoToken()\r
30fdf114
LG
3771 return False\r
3772\r
3773 if SectionName == "FV_IMAGE":\r
9e47e6f9
CJ
3774 FvImageSectionObj = FvImageSection()\r
3775 if self._IsKeyword("FV_IMAGE"):\r
30fdf114 3776 pass\r
9e47e6f9
CJ
3777 if self._IsToken("{"):\r
3778 FvObj = FV()\r
3779 self._GetDefineStatements(FvObj)\r
3780 self._GetBlockStatement(FvObj)\r
3781 self._GetSetStatements(FvObj)\r
3782 self._GetFvAlignment(FvObj)\r
3783 self._GetFvAttributes(FvObj)\r
3784 self._GetAprioriSection(FvObj)\r
3785 self._GetAprioriSection(FvObj)\r
30fdf114
LG
3786\r
3787 while True:\r
9e47e6f9
CJ
3788 IsInf = self._GetInfStatement(FvObj)\r
3789 IsFile = self._GetFileStatement(FvObj)\r
30fdf114
LG
3790 if not IsInf and not IsFile:\r
3791 break\r
3792\r
ea98a825 3793 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 3794 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3795 FvImageSectionObj.Fv = FvObj\r
3796 FvImageSectionObj.FvName = None\r
3797\r
3798 else:\r
9e47e6f9 3799 if not self._IsKeyword(BINARY_FILE_TYPE_FV):\r
ca957eb5 3800 raise Warning.Expected("'FV'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3801 FvImageSectionObj.FvFileType = self._Token\r
3802\r
3803 if self._GetAlignment():\r
3804 if self._Token not in ALIGNMENT_NOAUTO:\r
3805 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3806 FvImageSectionObj.Alignment = self._Token\r
3807\r
3808 if self._IsToken(TAB_VALUE_SPLIT):\r
3809 FvImageSectionObj.FvFileExtension = self._GetFileExtension()\r
3810 elif self._GetNextToken():\r
5a264f28 3811 if self._Token not in {\r
ea98a825 3812 T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32,\r
5a264f28
CJ
3813 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE,\r
3814 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\r
3815 BINARY_FILE_TYPE_UI, "VERSION",\r
3816 BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,\r
3817 BINARY_FILE_TYPE_SMM_DEPEX}:\r
9e47e6f9 3818 FvImageSectionObj.FvFileName = self._Token\r
30fdf114 3819 else:\r
9e47e6f9 3820 self._UndoToken()\r
30fdf114 3821 else:\r
ca957eb5 3822 raise Warning.Expected("FV file name", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3823\r
3824 Obj.SectionList.append(FvImageSectionObj)\r
3825 return True\r
3826\r
9e47e6f9 3827 EfiSectionObj = EfiSection()\r
30fdf114
LG
3828 EfiSectionObj.SectionType = SectionName\r
3829\r
9e47e6f9 3830 if not self._GetNextToken():\r
ca957eb5 3831 raise Warning.Expected("file type", self.FileName, self.CurrentLineNumber)\r
30fdf114 3832\r
9e47e6f9
CJ
3833 if self._Token == "STRING":\r
3834 if not self._RuleSectionCouldHaveString(EfiSectionObj.SectionType):\r
30fdf114
LG
3835 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3836\r
9e47e6f9 3837 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3838 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 3839\r
9e47e6f9 3840 if not self._GetNextToken():\r
ca957eb5 3841 raise Warning.Expected("Quoted String", self.FileName, self.CurrentLineNumber)\r
30fdf114 3842\r
9e47e6f9
CJ
3843 if self._GetStringData():\r
3844 EfiSectionObj.StringData = self._Token\r
30fdf114 3845\r
9e47e6f9
CJ
3846 if self._IsKeyword("BUILD_NUM"):\r
3847 if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):\r
30fdf114
LG
3848 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3849\r
9e47e6f9 3850 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3851 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3852 if not self._GetNextToken():\r
ca957eb5 3853 raise Warning.Expected("Build number", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3854 EfiSectionObj.BuildNum = self._Token\r
30fdf114
LG
3855\r
3856 else:\r
9e47e6f9
CJ
3857 EfiSectionObj.FileType = self._Token\r
3858 self._CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)\r
30fdf114 3859\r
9e47e6f9
CJ
3860 if self._IsKeyword("Optional"):\r
3861 if not self._RuleSectionCouldBeOptional(EfiSectionObj.SectionType):\r
30fdf114
LG
3862 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3863 EfiSectionObj.Optional = True\r
3864\r
9e47e6f9
CJ
3865 if self._IsKeyword("BUILD_NUM"):\r
3866 if not self._RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):\r
30fdf114
LG
3867 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)\r
3868\r
9e47e6f9 3869 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 3870 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3871 if not self._GetNextToken():\r
ca957eb5 3872 raise Warning.Expected("Build number", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3873 EfiSectionObj.BuildNum = self._Token\r
30fdf114 3874\r
9e47e6f9
CJ
3875 if self._GetAlignment():\r
3876 if self._Token not in ALIGNMENTS:\r
3877 raise Warning("Incorrect alignment '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
3878 if self._Token == 'Auto' and (not SectionName == BINARY_FILE_TYPE_PE32) and (not SectionName == BINARY_FILE_TYPE_TE):\r
52302d4d 3879 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3880 EfiSectionObj.Alignment = self._Token\r
30fdf114 3881\r
9e47e6f9
CJ
3882 if self._IsKeyword('RELOCS_STRIPPED') or self._IsKeyword('RELOCS_RETAINED'):\r
3883 if self._SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):\r
3884 if self._Token == 'RELOCS_STRIPPED':\r
30fdf114
LG
3885 EfiSectionObj.KeepReloc = False\r
3886 else:\r
3887 EfiSectionObj.KeepReloc = True\r
4231a819 3888 if Obj.KeepReloc is not None and Obj.KeepReloc != EfiSectionObj.KeepReloc:\r
30fdf114
LG
3889 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)\r
3890 else:\r
3891 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)\r
3892\r
3893\r
9e47e6f9
CJ
3894 if self._IsToken(TAB_VALUE_SPLIT):\r
3895 EfiSectionObj.FileExtension = self._GetFileExtension()\r
3896 elif self._GetNextToken():\r
5a264f28 3897 if self._Token not in {\r
ea98a825 3898 T_CHAR_BRACE_R, "COMPAT16", BINARY_FILE_TYPE_PE32,\r
5a264f28
CJ
3899 BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_TE,\r
3900 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX,\r
3901 BINARY_FILE_TYPE_UI, "VERSION",\r
3902 BINARY_FILE_TYPE_PEI_DEPEX, BINARY_FILE_TYPE_GUID,\r
3903 BINARY_FILE_TYPE_SMM_DEPEX}:\r
f7496d71 3904\r
9e47e6f9
CJ
3905 if self._Token.startswith('PCD'):\r
3906 self._UndoToken()\r
3907 self._GetNextWord()\r
f7496d71 3908\r
9e47e6f9
CJ
3909 if self._Token == 'PCD':\r
3910 if not self._IsToken("("):\r
ca957eb5 3911 raise Warning.Expected("'('", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
3912 PcdPair = self._GetNextPcdSettings()\r
3913 if not self._IsToken(")"):\r
ca957eb5 3914 raise Warning.Expected("')'", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 3915 self._Token = 'PCD('+PcdPair[1]+TAB_SPLIT+PcdPair[0]+')'\r
f7496d71 3916\r
9e47e6f9 3917 EfiSectionObj.FileName = self._Token\r
f7496d71 3918\r
30fdf114 3919 else:\r
9e47e6f9 3920 self._UndoToken()\r
30fdf114 3921 else:\r
ca957eb5 3922 raise Warning.Expected("section file name", self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
3923\r
3924 Obj.SectionList.append(EfiSectionObj)\r
3925 return True\r
3926\r
9e47e6f9 3927 ## _RuleSectionCouldBeOptional() method\r
30fdf114
LG
3928 #\r
3929 # Get whether a section could be optional\r
3930 #\r
30fdf114
LG
3931 # @param SectionType The section type to check\r
3932 # @retval True section could be optional\r
3933 # @retval False section never optional\r
3934 #\r
5bcf1d56 3935 @staticmethod\r
9e47e6f9 3936 def _RuleSectionCouldBeOptional(SectionType):\r
5a264f28 3937 if SectionType in {BINARY_FILE_TYPE_DXE_DEPEX, BINARY_FILE_TYPE_UI, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX, "RAW", BINARY_FILE_TYPE_SMM_DEPEX}:\r
30fdf114
LG
3938 return True\r
3939 else:\r
3940 return False\r
3941\r
9e47e6f9 3942 ## _RuleSectionCouldHaveBuildNum() method\r
30fdf114
LG
3943 #\r
3944 # Get whether a section could have build number information\r
3945 #\r
30fdf114
LG
3946 # @param SectionType The section type to check\r
3947 # @retval True section could have build number information\r
3948 # @retval False section never have build number information\r
3949 #\r
5bcf1d56 3950 @staticmethod\r
9e47e6f9 3951 def _RuleSectionCouldHaveBuildNum(SectionType):\r
5a264f28 3952 if SectionType == "VERSION":\r
30fdf114
LG
3953 return True\r
3954 else:\r
3955 return False\r
3956\r
9e47e6f9 3957 ## _RuleSectionCouldHaveString() method\r
30fdf114
LG
3958 #\r
3959 # Get whether a section could have string\r
3960 #\r
30fdf114
LG
3961 # @param SectionType The section type to check\r
3962 # @retval True section could have string\r
3963 # @retval False section never have string\r
3964 #\r
5bcf1d56 3965 @staticmethod\r
9e47e6f9 3966 def _RuleSectionCouldHaveString(SectionType):\r
5a264f28 3967 if SectionType in {BINARY_FILE_TYPE_UI, "VERSION"}:\r
30fdf114
LG
3968 return True\r
3969 else:\r
3970 return False\r
3971\r
9e47e6f9 3972 ## _CheckRuleSectionFileType() method\r
30fdf114
LG
3973 #\r
3974 # Get whether a section matches a file type\r
3975 #\r
3976 # @param self The object pointer\r
3977 # @param SectionType The section type to check\r
3978 # @param FileType The file type to check\r
3979 #\r
9e47e6f9 3980 def _CheckRuleSectionFileType(self, SectionType, FileType):\r
ca957eb5 3981 WarningString = "Incorrect section file type '%s'"\r
30fdf114 3982 if SectionType == "COMPAT16":\r
5a264f28 3983 if FileType not in {"COMPAT16", "SEC_COMPAT16"}:\r
ca957eb5 3984 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 3985 elif SectionType == BINARY_FILE_TYPE_PE32:\r
5a264f28 3986 if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_PE32"}:\r
ca957eb5 3987 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 3988 elif SectionType == BINARY_FILE_TYPE_PIC:\r
5a264f28 3989 if FileType not in {BINARY_FILE_TYPE_PIC, BINARY_FILE_TYPE_PIC}:\r
ca957eb5 3990 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 3991 elif SectionType == BINARY_FILE_TYPE_TE:\r
5a264f28 3992 if FileType not in {BINARY_FILE_TYPE_TE, "SEC_TE"}:\r
ca957eb5 3993 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
30fdf114 3994 elif SectionType == "RAW":\r
5a264f28 3995 if FileType not in {BINARY_FILE_TYPE_BIN, "SEC_BIN", "RAW", "ASL", "ACPI"}:\r
ca957eb5 3996 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 3997 elif SectionType == BINARY_FILE_TYPE_DXE_DEPEX or SectionType == BINARY_FILE_TYPE_SMM_DEPEX:\r
5a264f28 3998 if FileType not in {BINARY_FILE_TYPE_DXE_DEPEX, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX}:\r
ca957eb5 3999 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 4000 elif SectionType == BINARY_FILE_TYPE_UI:\r
5a264f28 4001 if FileType not in {BINARY_FILE_TYPE_UI, "SEC_UI"}:\r
ca957eb5 4002 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
30fdf114 4003 elif SectionType == "VERSION":\r
5a264f28 4004 if FileType not in {"VERSION", "SEC_VERSION"}:\r
ca957eb5 4005 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 4006 elif SectionType == BINARY_FILE_TYPE_PEI_DEPEX:\r
5a264f28 4007 if FileType not in {BINARY_FILE_TYPE_PEI_DEPEX, "SEC_PEI_DEPEX"}:\r
ca957eb5 4008 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
91fa33ee 4009 elif SectionType == BINARY_FILE_TYPE_GUID:\r
5a264f28 4010 if FileType not in {BINARY_FILE_TYPE_PE32, "SEC_GUID"}:\r
ca957eb5 4011 raise Warning(WarningString % FileType, self.FileName, self.CurrentLineNumber)\r
30fdf114 4012\r
9e47e6f9 4013 ## _GetRuleEncapsulationSection() method\r
30fdf114
LG
4014 #\r
4015 # Get encapsulation section for Rule\r
4016 #\r
4017 # @param self The object pointer\r
9e47e6f9 4018 # @param theRule for whom section is got\r
30fdf114
LG
4019 # @retval True Successfully find section statement\r
4020 # @retval False Not able to find section statement\r
4021 #\r
9e47e6f9
CJ
4022 def _GetRuleEncapsulationSection(self, theRule):\r
4023 if self._IsKeyword("COMPRESS"):\r
30fdf114 4024 Type = "PI_STD"\r
9e47e6f9
CJ
4025 if self._IsKeyword("PI_STD") or self._IsKeyword("PI_NONE"):\r
4026 Type = self._Token\r
30fdf114 4027\r
9e47e6f9 4028 if not self._IsToken("{"):\r
ca957eb5 4029 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
30fdf114 4030\r
9e47e6f9 4031 CompressSectionObj = CompressSection()\r
30fdf114
LG
4032\r
4033 CompressSectionObj.CompType = Type\r
4034 # Recursive sections...\r
4035 while True:\r
9e47e6f9
CJ
4036 IsEncapsulate = self._GetRuleEncapsulationSection(CompressSectionObj)\r
4037 IsLeaf = self._GetEfiSection(CompressSectionObj)\r
30fdf114
LG
4038 if not IsEncapsulate and not IsLeaf:\r
4039 break\r
4040\r
ea98a825 4041 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 4042 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4043 theRule.SectionList.append(CompressSectionObj)\r
30fdf114
LG
4044\r
4045 return True\r
4046\r
9e47e6f9 4047 elif self._IsKeyword("GUIDED"):\r
30fdf114 4048 GuidValue = None\r
9e47e6f9
CJ
4049 if self._GetNextGuid():\r
4050 GuidValue = self._Token\r
30fdf114 4051\r
9e47e6f9
CJ
4052 if self._IsKeyword("$(NAMED_GUID)"):\r
4053 GuidValue = self._Token\r
30fdf114 4054\r
9e47e6f9 4055 AttribDict = self._GetGuidAttrib()\r
30fdf114 4056\r
9e47e6f9 4057 if not self._IsToken("{"):\r
ca957eb5 4058 raise Warning.ExpectedCurlyOpen(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4059 GuidSectionObj = GuidSection()\r
30fdf114
LG
4060 GuidSectionObj.NameGuid = GuidValue\r
4061 GuidSectionObj.SectionType = "GUIDED"\r
4062 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]\r
4063 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]\r
25918452 4064 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]\r
30fdf114
LG
4065\r
4066 # Efi sections...\r
4067 while True:\r
9e47e6f9
CJ
4068 IsEncapsulate = self._GetRuleEncapsulationSection(GuidSectionObj)\r
4069 IsLeaf = self._GetEfiSection(GuidSectionObj)\r
30fdf114
LG
4070 if not IsEncapsulate and not IsLeaf:\r
4071 break\r
4072\r
ea98a825 4073 if not self._IsToken(T_CHAR_BRACE_R):\r
ca957eb5 4074 raise Warning.ExpectedCurlyClose(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4075 theRule.SectionList.append(GuidSectionObj)\r
30fdf114
LG
4076\r
4077 return True\r
4078\r
4079 return False\r
4080\r
9e47e6f9 4081 ## _GetVtf() method\r
30fdf114
LG
4082 #\r
4083 # Get VTF section contents and store its data into VTF list of self.Profile\r
4084 #\r
4085 # @param self The object pointer\r
4086 # @retval True Successfully find a VTF\r
4087 # @retval False Not able to find a VTF\r
4088 #\r
9e47e6f9 4089 def _GetVtf(self):\r
5a264f28 4090 HW_ARCH_SET = {TAB_ARCH_IA32, TAB_ARCH_X64, TAB_ARCH_IPF, TAB_ARCH_ARM, TAB_ARCH_AARCH64}\r
9e47e6f9 4091 if not self._GetNextToken():\r
30fdf114
LG
4092 return False\r
4093\r
9e47e6f9
CJ
4094 S = self._Token.upper()\r
4095 if S.startswith(TAB_SECTION_START) and not S.startswith("[VTF."):\r
df81077f 4096 self.SectionParser(S)\r
9e47e6f9 4097 self._UndoToken()\r
30fdf114
LG
4098 return False\r
4099\r
9e47e6f9
CJ
4100 self._UndoToken()\r
4101 if not self._IsToken("[VTF.", True):\r
30fdf114
LG
4102 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
4103 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \\r
9e47e6f9 4104 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)\r
ca957eb5 4105 raise Warning.Expected("[VTF.]", self.FileName, self.CurrentLineNumber)\r
30fdf114 4106\r
9e47e6f9 4107 if not self._SkipToToken(TAB_SPLIT):\r
ca957eb5 4108 raise Warning.Expected("'.'", self.FileName, self.CurrentLineNumber)\r
30fdf114 4109\r
9e47e6f9 4110 Arch = self._SkippedChars.rstrip(TAB_SPLIT).upper()\r
5a264f28 4111 if Arch not in HW_ARCH_SET:\r
30fdf114
LG
4112 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)\r
4113\r
9e47e6f9 4114 if not self._GetNextWord():\r
ca957eb5 4115 raise Warning.Expected("VTF name", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4116 Name = self._Token.upper()\r
30fdf114 4117\r
9e47e6f9 4118 VtfObj = Vtf()\r
30fdf114
LG
4119 VtfObj.UiName = Name\r
4120 VtfObj.KeyArch = Arch\r
4121\r
9e47e6f9
CJ
4122 if self._IsToken(TAB_COMMA_SPLIT):\r
4123 if not self._GetNextWord():\r
ca957eb5 4124 raise Warning.Expected("Arch list", self.FileName, self.CurrentLineNumber)\r
5a264f28 4125 if self._Token.upper() not in HW_ARCH_SET:\r
9e47e6f9
CJ
4126 raise Warning("Unknown Arch '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
4127 VtfObj.ArchList = self._Token.upper()\r
30fdf114 4128\r
9e47e6f9 4129 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 4130 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 4131\r
9e47e6f9
CJ
4132 if self._IsKeyword("IA32_RST_BIN"):\r
4133 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4134 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4135\r
9e47e6f9 4136 if not self._GetNextToken():\r
ca957eb5 4137 raise Warning.Expected("Reset file", self.FileName, self.CurrentLineNumber)\r
30fdf114 4138\r
9e47e6f9
CJ
4139 VtfObj.ResetBin = self._Token\r
4140 if VtfObj.ResetBin.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4141 #check for file path\r
4142 ErrorCode, ErrorInfo = PathClass(NormPath(VtfObj.ResetBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4143 if ErrorCode != 0:\r
4144 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 4145\r
9e47e6f9 4146 while self._GetComponentStatement(VtfObj):\r
30fdf114
LG
4147 pass\r
4148\r
4149 self.Profile.VtfList.append(VtfObj)\r
4150 return True\r
4151\r
9e47e6f9 4152 ## _GetComponentStatement() method\r
30fdf114
LG
4153 #\r
4154 # Get components in VTF\r
4155 #\r
4156 # @param self The object pointer\r
4157 # @param VtfObj for whom component is got\r
4158 # @retval True Successfully find a component\r
4159 # @retval False Not able to find a component\r
4160 #\r
9e47e6f9
CJ
4161 def _GetComponentStatement(self, VtfObj):\r
4162 if not self._IsKeyword("COMP_NAME"):\r
30fdf114
LG
4163 return False\r
4164\r
9e47e6f9 4165 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4166 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4167\r
9e47e6f9 4168 if not self._GetNextWord():\r
ca957eb5 4169 raise Warning.Expected("Component Name", self.FileName, self.CurrentLineNumber)\r
30fdf114 4170\r
9e47e6f9
CJ
4171 CompStatementObj = ComponentStatement()\r
4172 CompStatementObj.CompName = self._Token\r
30fdf114 4173\r
9e47e6f9 4174 if not self._IsKeyword("COMP_LOC"):\r
ca957eb5 4175 raise Warning.Expected("COMP_LOC", self.FileName, self.CurrentLineNumber)\r
30fdf114 4176\r
9e47e6f9 4177 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4178 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
4179\r
4180 CompStatementObj.CompLoc = ""\r
9e47e6f9
CJ
4181 if self._GetNextWord():\r
4182 CompStatementObj.CompLoc = self._Token\r
4183 if self._IsToken(TAB_VALUE_SPLIT):\r
4184 if not self._GetNextWord():\r
ca957eb5 4185 raise Warning.Expected("Region Name", self.FileName, self.CurrentLineNumber)\r
30fdf114 4186\r
5a264f28 4187 if self._Token not in {"F", "N", "S"}: #, "H", "L", "PH", "PL"): not support\r
9e47e6f9 4188 raise Warning("Unknown location type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114 4189\r
9e47e6f9 4190 CompStatementObj.FilePos = self._Token\r
30fdf114
LG
4191 else:\r
4192 self.CurrentLineNumber += 1\r
4193 self.CurrentOffsetWithinLine = 0\r
4194\r
9e47e6f9 4195 if not self._IsKeyword("COMP_TYPE"):\r
ca957eb5 4196 raise Warning.Expected("COMP_TYPE", self.FileName, self.CurrentLineNumber)\r
30fdf114 4197\r
9e47e6f9 4198 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4199 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4200\r
9e47e6f9 4201 if not self._GetNextToken():\r
ca957eb5 4202 raise Warning.Expected("Component type", self.FileName, self.CurrentLineNumber)\r
5a264f28 4203 if self._Token not in {"FIT", "PAL_B", "PAL_A", "OEM"}:\r
9e47e6f9
CJ
4204 if not self._Token.startswith("0x") or len(self._Token) < 3 or len(self._Token) > 4 or \\r
4205 not self._Token[2] in hexdigits or not self._Token[-1] in hexdigits:\r
4206 raise Warning("Unknown location type '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
4207 CompStatementObj.CompType = self._Token\r
30fdf114 4208\r
9e47e6f9 4209 if not self._IsKeyword("COMP_VER"):\r
ca957eb5 4210 raise Warning.Expected("COMP_VER", self.FileName, self.CurrentLineNumber)\r
30fdf114 4211\r
9e47e6f9 4212 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4213 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4214\r
9e47e6f9 4215 if not self._GetNextToken():\r
ca957eb5 4216 raise Warning.Expected("Component version", self.FileName, self.CurrentLineNumber)\r
30fdf114 4217\r
9e47e6f9
CJ
4218 Pattern = compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', DOTALL)\r
4219 if Pattern.match(self._Token) is None:\r
4220 raise Warning("Unknown version format '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
4221 CompStatementObj.CompVer = self._Token\r
30fdf114 4222\r
9e47e6f9 4223 if not self._IsKeyword("COMP_CS"):\r
ca957eb5 4224 raise Warning.Expected("COMP_CS", self.FileName, self.CurrentLineNumber)\r
30fdf114 4225\r
9e47e6f9 4226 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4227 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4228\r
9e47e6f9 4229 if not self._GetNextToken():\r
ca957eb5 4230 raise Warning.Expected("Component CS", self.FileName, self.CurrentLineNumber)\r
5a264f28 4231 if self._Token not in {"1", "0"}:\r
ca957eb5 4232 raise Warning("Unknown Component CS '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4233 CompStatementObj.CompCs = self._Token\r
30fdf114
LG
4234\r
4235\r
9e47e6f9 4236 if not self._IsKeyword("COMP_BIN"):\r
ca957eb5 4237 raise Warning.Expected("COMP_BIN", self.FileName, self.CurrentLineNumber)\r
30fdf114 4238\r
9e47e6f9 4239 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4240 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4241\r
9e47e6f9 4242 if not self._GetNextToken():\r
ca957eb5 4243 raise Warning.Expected("Component file", self.FileName, self.CurrentLineNumber)\r
30fdf114 4244\r
9e47e6f9
CJ
4245 CompStatementObj.CompBin = self._Token\r
4246 if CompStatementObj.CompBin != '-' and CompStatementObj.CompBin.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4247 #check for file path\r
4248 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4249 if ErrorCode != 0:\r
4250 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 4251\r
9e47e6f9 4252 if not self._IsKeyword("COMP_SYM"):\r
ca957eb5 4253 raise Warning.Expected("COMP_SYM", self.FileName, self.CurrentLineNumber)\r
30fdf114 4254\r
9e47e6f9 4255 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4256 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4257\r
9e47e6f9 4258 if not self._GetNextToken():\r
ca957eb5 4259 raise Warning.Expected("Component symbol file", self.FileName, self.CurrentLineNumber)\r
30fdf114 4260\r
9e47e6f9
CJ
4261 CompStatementObj.CompSym = self._Token\r
4262 if CompStatementObj.CompSym != '-' and CompStatementObj.CompSym.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4263 #check for file path\r
4264 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompSym), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4265 if ErrorCode != 0:\r
4266 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114 4267\r
9e47e6f9 4268 if not self._IsKeyword("COMP_SIZE"):\r
ca957eb5 4269 raise Warning.Expected("COMP_SIZE", self.FileName, self.CurrentLineNumber)\r
30fdf114 4270\r
9e47e6f9 4271 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4272 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
30fdf114 4273\r
9e47e6f9
CJ
4274 if self._IsToken("-"):\r
4275 CompStatementObj.CompSize = self._Token\r
4276 elif self._GetNextDecimalNumber():\r
4277 CompStatementObj.CompSize = self._Token\r
4278 elif self._GetNextHexNumber():\r
4279 CompStatementObj.CompSize = self._Token\r
30fdf114 4280 else:\r
9e47e6f9 4281 raise Warning("Unknown size '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114
LG
4282\r
4283 VtfObj.ComponentStatementList.append(CompStatementObj)\r
4284 return True\r
4285\r
9e47e6f9 4286 ## _GetOptionRom() method\r
30fdf114
LG
4287 #\r
4288 # Get OptionROM section contents and store its data into OptionROM list of self.Profile\r
4289 #\r
4290 # @param self The object pointer\r
4291 # @retval True Successfully find a OptionROM\r
4292 # @retval False Not able to find a OptionROM\r
4293 #\r
9e47e6f9
CJ
4294 def _GetOptionRom(self):\r
4295 if not self._GetNextToken():\r
30fdf114
LG
4296 return False\r
4297\r
9e47e6f9
CJ
4298 S = self._Token.upper()\r
4299 if S.startswith(TAB_SECTION_START) and not S.startswith("[OPTIONROM."):\r
df81077f 4300 self.SectionParser(S)\r
9e47e6f9 4301 self._UndoToken()\r
df81077f 4302 return False\r
f7496d71 4303\r
9e47e6f9
CJ
4304 self._UndoToken()\r
4305 if not self._IsToken("[OptionRom.", True):\r
4306 raise Warning("Unknown Keyword '%s'" % self._Token, self.FileName, self.CurrentLineNumber)\r
30fdf114 4307\r
9e47e6f9 4308 OptRomName = self._GetUiName()\r
30fdf114 4309\r
9e47e6f9 4310 if not self._IsToken(TAB_SECTION_END):\r
ca957eb5 4311 raise Warning.ExpectedBracketClose(self.FileName, self.CurrentLineNumber)\r
30fdf114 4312\r
9e47e6f9 4313 OptRomObj = OPTIONROM(OptRomName)\r
30fdf114
LG
4314 self.Profile.OptRomDict[OptRomName] = OptRomObj\r
4315\r
4316 while True:\r
9e47e6f9
CJ
4317 isInf = self._GetOptRomInfStatement(OptRomObj)\r
4318 isFile = self._GetOptRomFileStatement(OptRomObj)\r
30fdf114
LG
4319 if not isInf and not isFile:\r
4320 break\r
f7496d71 4321\r
30fdf114
LG
4322 return True\r
4323\r
9e47e6f9 4324 ## _GetOptRomInfStatement() method\r
30fdf114
LG
4325 #\r
4326 # Get INF statements\r
4327 #\r
4328 # @param self The object pointer\r
4329 # @param Obj for whom inf statement is got\r
4330 # @retval True Successfully find inf statement\r
4331 # @retval False Not able to find inf statement\r
4332 #\r
9e47e6f9
CJ
4333 def _GetOptRomInfStatement(self, Obj):\r
4334 if not self._IsKeyword("INF"):\r
30fdf114
LG
4335 return False\r
4336\r
9e47e6f9
CJ
4337 ffsInf = OptRomInfStatement()\r
4338 self._GetInfOptions(ffsInf)\r
30fdf114 4339\r
9e47e6f9 4340 if not self._GetNextToken():\r
ca957eb5 4341 raise Warning.Expected("INF file path", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
4342 ffsInf.InfFileName = self._Token\r
4343 if ffsInf.InfFileName.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4344 #check for file path\r
4345 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4346 if ErrorCode != 0:\r
4347 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4348\r
4349 if not ffsInf.InfFileName in self.Profile.InfList:\r
4350 self.Profile.InfList.append(ffsInf.InfFileName)\r
d0acc87a
LG
4351 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)\r
4352 self.Profile.InfFileLineList.append(FileLineTuple)\r
2502b735
YZ
4353 if ffsInf.UseArch:\r
4354 if ffsInf.UseArch not in self.Profile.InfDict:\r
4355 self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]\r
4356 else:\r
4357 self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)\r
4358 else:\r
4359 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)\r
30fdf114 4360\r
f7496d71 4361\r
9e47e6f9 4362 self._GetOptRomOverrides (ffsInf)\r
f7496d71 4363\r
30fdf114
LG
4364 Obj.FfsList.append(ffsInf)\r
4365 return True\r
4366\r
9e47e6f9 4367 ## _GetOptRomOverrides() method\r
30fdf114
LG
4368 #\r
4369 # Get overrides for OptROM INF & FILE\r
4370 #\r
4371 # @param self The object pointer\r
4372 # @param FfsInfObj for whom overrides is got\r
4373 #\r
9e47e6f9
CJ
4374 def _GetOptRomOverrides(self, Obj):\r
4375 if self._IsToken('{'):\r
4376 Overrides = OverrideAttribs()\r
fd171542 4377 while True:\r
9e47e6f9
CJ
4378 if self._IsKeyword("PCI_VENDOR_ID"):\r
4379 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4380 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4381 if not self._GetNextHexNumber():\r
ca957eb5 4382 raise Warning.Expected("Hex vendor id", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4383 Overrides.PciVendorId = self._Token\r
fd171542 4384 continue\r
4385\r
9e47e6f9
CJ
4386 if self._IsKeyword("PCI_CLASS_CODE"):\r
4387 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4388 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4389 if not self._GetNextHexNumber():\r
ca957eb5 4390 raise Warning.Expected("Hex class code", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4391 Overrides.PciClassCode = self._Token\r
fd171542 4392 continue\r
4393\r
9e47e6f9
CJ
4394 if self._IsKeyword("PCI_DEVICE_ID"):\r
4395 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4396 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
f157f973
TP
4397 # Get a list of PCI IDs\r
4398 Overrides.PciDeviceId = ""\r
5b9639e6
TP
4399 while (self._GetNextHexNumber()):\r
4400 Overrides.PciDeviceId = "{} {}".format(Overrides.PciDeviceId, self._Token)\r
f157f973
TP
4401 if not Overrides.PciDeviceId:\r
4402 raise Warning.Expected("one or more Hex device ids", self.FileName, self.CurrentLineNumber)\r
fd171542 4403 continue\r
4404\r
9e47e6f9
CJ
4405 if self._IsKeyword("PCI_REVISION"):\r
4406 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4407 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4408 if not self._GetNextHexNumber():\r
ca957eb5 4409 raise Warning.Expected("Hex revision", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4410 Overrides.PciRevision = self._Token\r
fd171542 4411 continue\r
4412\r
9e47e6f9
CJ
4413 if self._IsKeyword("PCI_COMPRESS"):\r
4414 if not self._IsToken(TAB_EQUAL_SPLIT):\r
ca957eb5 4415 raise Warning.ExpectedEquals(self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4416 if not self._GetNextToken():\r
ca957eb5 4417 raise Warning.Expected("TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4418 Overrides.NeedCompress = self._Token.upper() == 'TRUE'\r
fd171542 4419 continue\r
4420\r
ea98a825 4421 if self._IsToken(T_CHAR_BRACE_R):\r
fd171542 4422 break\r
4423 else:\r
4424 EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)\r
4425\r
30fdf114 4426 Obj.OverrideAttribs = Overrides\r
f7496d71 4427\r
9e47e6f9 4428 ## _GetOptRomFileStatement() method\r
30fdf114
LG
4429 #\r
4430 # Get FILE statements\r
4431 #\r
4432 # @param self The object pointer\r
4433 # @param Obj for whom FILE statement is got\r
4434 # @retval True Successfully find FILE statement\r
4435 # @retval False Not able to find FILE statement\r
4436 #\r
9e47e6f9
CJ
4437 def _GetOptRomFileStatement(self, Obj):\r
4438 if not self._IsKeyword("FILE"):\r
30fdf114
LG
4439 return False\r
4440\r
9e47e6f9 4441 FfsFileObj = OptRomFileStatement()\r
30fdf114 4442\r
9e47e6f9 4443 if not self._IsKeyword("EFI") and not self._IsKeyword(BINARY_FILE_TYPE_BIN):\r
ca957eb5 4444 raise Warning.Expected("Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber)\r
9e47e6f9 4445 FfsFileObj.FileType = self._Token\r
30fdf114 4446\r
9e47e6f9 4447 if not self._GetNextToken():\r
ca957eb5 4448 raise Warning.Expected("File path", self.FileName, self.CurrentLineNumber)\r
9e47e6f9
CJ
4449 FfsFileObj.FileName = self._Token\r
4450 if FfsFileObj.FileName.replace(TAB_WORKSPACE, '').find('$') == -1:\r
6310ffd7 4451 #check for file path\r
4452 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()\r
4453 if ErrorCode != 0:\r
4454 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
30fdf114
LG
4455\r
4456 if FfsFileObj.FileType == 'EFI':\r
9e47e6f9 4457 self._GetOptRomOverrides(FfsFileObj)\r
f7496d71 4458\r
30fdf114
LG
4459 Obj.FfsList.append(FfsFileObj)\r
4460\r
4461 return True\r
fd171542 4462\r
9e47e6f9 4463 ## _GetCapInFd() method\r
fd171542 4464 #\r
4465 # Get Cap list contained in FD\r
4466 #\r
4467 # @param self The object pointer\r
4468 # @param FdName FD name\r
4469 # @retval CapList List of Capsule in FD\r
4470 #\r
9e47e6f9 4471 def _GetCapInFd (self, FdName):\r
fd171542 4472 CapList = []\r
9eb87141 4473 if FdName.upper() in self.Profile.FdDict:\r
fd171542 4474 FdObj = self.Profile.FdDict[FdName.upper()]\r
4475 for elementRegion in FdObj.RegionList:\r
4476 if elementRegion.RegionType == 'CAPSULE':\r
4477 for elementRegionData in elementRegion.RegionDataList:\r
4478 if elementRegionData.endswith(".cap"):\r
4479 continue\r
4231a819 4480 if elementRegionData is not None and elementRegionData.upper() not in CapList:\r
fd171542 4481 CapList.append(elementRegionData.upper())\r
4482 return CapList\r
4483\r
9e47e6f9 4484 ## _GetReferencedFdCapTuple() method\r
fd171542 4485 #\r
4486 # Get FV and FD list referenced by a capsule image\r
4487 #\r
4488 # @param self The object pointer\r
4489 # @param CapObj Capsule section to be searched\r
4490 # @param RefFdList referenced FD by section\r
4491 # @param RefFvList referenced FV by section\r
4492 #\r
9e47e6f9
CJ
4493 def _GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):\r
4494 for CapsuleDataObj in CapObj.CapsuleDataList:\r
4231a819 4495 if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName is not None and CapsuleDataObj.FvName.upper() not in RefFvList:\r
fd171542 4496 RefFvList.append (CapsuleDataObj.FvName.upper())\r
4231a819 4497 elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName is not None and CapsuleDataObj.FdName.upper() not in RefFdList:\r
f7496d71 4498 RefFdList.append (CapsuleDataObj.FdName.upper())\r
4231a819 4499 elif CapsuleDataObj.Ffs is not None:\r
9e47e6f9 4500 if isinstance(CapsuleDataObj.Ffs, FileStatement):\r
4231a819 4501 if CapsuleDataObj.Ffs.FvName is not None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:\r
b36d134f 4502 RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())\r
4231a819 4503 elif CapsuleDataObj.Ffs.FdName is not None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:\r
b36d134f
LG
4504 RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())\r
4505 else:\r
9e47e6f9 4506 self._GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)\r
fd171542 4507\r
9e47e6f9 4508 ## _GetFvInFd() method\r
30fdf114
LG
4509 #\r
4510 # Get FV list contained in FD\r
4511 #\r
4512 # @param self The object pointer\r
4513 # @param FdName FD name\r
4514 # @retval FvList list of FV in FD\r
4515 #\r
9e47e6f9 4516 def _GetFvInFd (self, FdName):\r
30fdf114 4517 FvList = []\r
9eb87141 4518 if FdName.upper() in self.Profile.FdDict:\r
30fdf114
LG
4519 FdObj = self.Profile.FdDict[FdName.upper()]\r
4520 for elementRegion in FdObj.RegionList:\r
91fa33ee 4521 if elementRegion.RegionType == BINARY_FILE_TYPE_FV:\r
30fdf114 4522 for elementRegionData in elementRegion.RegionDataList:\r
fd171542 4523 if elementRegionData.endswith(".fv"):\r
4524 continue\r
4231a819 4525 if elementRegionData is not None and elementRegionData.upper() not in FvList:\r
30fdf114
LG
4526 FvList.append(elementRegionData.upper())\r
4527 return FvList\r
4528\r
9e47e6f9 4529 ## _GetReferencedFdFvTuple() method\r
30fdf114
LG
4530 #\r
4531 # Get FD and FV list referenced by a FFS file\r
4532 #\r
4533 # @param self The object pointer\r
4534 # @param FfsFile contains sections to be searched\r
4535 # @param RefFdList referenced FD by section\r
4536 # @param RefFvList referenced FV by section\r
4537 #\r
9e47e6f9 4538 def _GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):\r
30fdf114 4539 for FfsObj in FvObj.FfsList:\r
9e47e6f9 4540 if isinstance(FfsObj, FileStatement):\r
4231a819 4541 if FfsObj.FvName is not None and FfsObj.FvName.upper() not in RefFvList:\r
30fdf114 4542 RefFvList.append(FfsObj.FvName.upper())\r
4231a819 4543 elif FfsObj.FdName is not None and FfsObj.FdName.upper() not in RefFdList:\r
30fdf114
LG
4544 RefFdList.append(FfsObj.FdName.upper())\r
4545 else:\r
9e47e6f9 4546 self._GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)\r
30fdf114 4547\r
9e47e6f9 4548 ## _GetReferencedFdFvTupleFromSection() method\r
30fdf114
LG
4549 #\r
4550 # Get FD and FV list referenced by a FFS section\r
4551 #\r
4552 # @param self The object pointer\r
4553 # @param FfsFile contains sections to be searched\r
4554 # @param FdList referenced FD by section\r
4555 # @param FvList referenced FV by section\r
4556 #\r
9e47e6f9 4557 def _GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):\r
5a264f28 4558 SectionStack = list(FfsFile.SectionList)\r
30fdf114
LG
4559 while SectionStack != []:\r
4560 SectionObj = SectionStack.pop()\r
9e47e6f9 4561 if isinstance(SectionObj, FvImageSection):\r
4231a819 4562 if SectionObj.FvName is not None and SectionObj.FvName.upper() not in FvList:\r
30fdf114 4563 FvList.append(SectionObj.FvName.upper())\r
4231a819 4564 if SectionObj.Fv is not None and SectionObj.Fv.UiFvName is not None and SectionObj.Fv.UiFvName.upper() not in FvList:\r
30fdf114 4565 FvList.append(SectionObj.Fv.UiFvName.upper())\r
9e47e6f9 4566 self._GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)\r
30fdf114 4567\r
9e47e6f9 4568 if isinstance(SectionObj, CompressSection) or isinstance(SectionObj, GuidSection):\r
30fdf114
LG
4569 SectionStack.extend(SectionObj.SectionList)\r
4570\r
4571 ## CycleReferenceCheck() method\r
4572 #\r
4573 # Check whether cycle reference exists in FDF\r
4574 #\r
4575 # @param self The object pointer\r
4576 # @retval True cycle reference exists\r
4577 # @retval False Not exists cycle reference\r
4578 #\r
4579 def CycleReferenceCheck(self):\r
fd171542 4580 #\r
4581 # Check the cycle between FV and FD image\r
4582 #\r
4583 MaxLength = len (self.Profile.FvDict)\r
9eb87141 4584 for FvName in self.Profile.FvDict:\r
fd171542 4585 LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName\r
5a264f28
CJ
4586 RefFvStack = set(FvName)\r
4587 FdAnalyzedList = set()\r
f7496d71 4588\r
fd171542 4589 Index = 0\r
9e47e6f9 4590 while RefFvStack and Index < MaxLength:\r
fd171542 4591 Index = Index + 1\r
4592 FvNameFromStack = RefFvStack.pop()\r
9eb87141 4593 if FvNameFromStack.upper() in self.Profile.FvDict:\r
fd171542 4594 FvObj = self.Profile.FvDict[FvNameFromStack.upper()]\r
4595 else:\r
4596 continue\r
30fdf114 4597\r
fd171542 4598 RefFdList = []\r
4599 RefFvList = []\r
9e47e6f9 4600 self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)\r
30fdf114 4601\r
fd171542 4602 for RefFdName in RefFdList:\r
4603 if RefFdName in FdAnalyzedList:\r
30fdf114
LG
4604 continue\r
4605\r
fd171542 4606 LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)\r
9e47e6f9 4607 FvInFdList = self._GetFvInFd(RefFdName)\r
fd171542 4608 if FvInFdList != []:\r
4609 for FvNameInFd in FvInFdList:\r
ccaa7754 4610 LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd)\r
fd171542 4611 if FvNameInFd not in RefFvStack:\r
5a264f28 4612 RefFvStack.add(FvNameInFd)\r
fd171542 4613\r
4614 if FvName in RefFvStack or FvNameFromStack in RefFvStack:\r
4615 EdkLogger.info(LogStr)\r
4616 return True\r
5a264f28 4617 FdAnalyzedList.add(RefFdName)\r
30fdf114 4618\r
fd171542 4619 for RefFvName in RefFvList:\r
4620 LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)\r
4621 if RefFvName not in RefFvStack:\r
5a264f28 4622 RefFvStack.add(RefFvName)\r
fd171542 4623\r
4624 if FvName in RefFvStack or FvNameFromStack in RefFvStack:\r
4625 EdkLogger.info(LogStr)\r
4626 return True\r
4627\r
4628 #\r
4629 # Check the cycle between Capsule and FD image\r
4630 #\r
4631 MaxLength = len (self.Profile.CapsuleDict)\r
9eb87141 4632 for CapName in self.Profile.CapsuleDict:\r
fd171542 4633 #\r
4634 # Capsule image to be checked.\r
4635 #\r
4636 LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName\r
5a264f28
CJ
4637 RefCapStack = {CapName}\r
4638 FdAnalyzedList = set()\r
4639 FvAnalyzedList = set()\r
f7496d71 4640\r
fd171542 4641 Index = 0\r
5a264f28 4642 while RefCapStack and Index < MaxLength:\r
fd171542 4643 Index = Index + 1\r
4644 CapNameFromStack = RefCapStack.pop()\r
9eb87141 4645 if CapNameFromStack.upper() in self.Profile.CapsuleDict:\r
fd171542 4646 CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]\r
4647 else:\r
4648 continue\r
4649\r
4650 RefFvList = []\r
4651 RefFdList = []\r
9e47e6f9 4652 self._GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)\r
fd171542 4653\r
4654 FvListLength = 0\r
4655 FdListLength = 0\r
4656 while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):\r
30fdf114
LG
4657 for RefFdName in RefFdList:\r
4658 if RefFdName in FdAnalyzedList:\r
4659 continue\r
4660\r
fd171542 4661 LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)\r
5a264f28
CJ
4662 for CapNameInFd in self._GetCapInFd(RefFdName):\r
4663 LogStr += "FD %s contains Capsule %s\n" % (RefFdName, CapNameInFd)\r
4664 if CapNameInFd not in RefCapStack:\r
4665 RefCapStack.append(CapNameInFd)\r
4666\r
4667 if CapName in RefCapStack or CapNameFromStack in RefCapStack:\r
4668 EdkLogger.info(LogStr)\r
4669 return True\r
4670\r
4671 for FvNameInFd in self._GetFvInFd(RefFdName):\r
4672 LogStr += "FD %s contains FV %s\n" % (RefFdName, FvNameInFd)\r
4673 if FvNameInFd not in RefFvList:\r
4674 RefFvList.append(FvNameInFd)\r
4675\r
4676 FdAnalyzedList.add(RefFdName)\r
fd171542 4677 #\r
4678 # the number of the parsed FV and FD image\r
4679 #\r
4680 FvListLength = len (RefFvList)\r
4681 FdListLength = len (RefFdList)\r
30fdf114 4682 for RefFvName in RefFvList:\r
fd171542 4683 if RefFvName in FvAnalyzedList:\r
4684 continue\r
4685 LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)\r
9eb87141 4686 if RefFvName.upper() in self.Profile.FvDict:\r
fd171542 4687 FvObj = self.Profile.FvDict[RefFvName.upper()]\r
4688 else:\r
4689 continue\r
9e47e6f9 4690 self._GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)\r
5a264f28 4691 FvAnalyzedList.add(RefFvName)\r
30fdf114 4692\r
fd171542 4693 return False\r
30fdf114 4694\r
c17956e0
DL
4695 def GetAllIncludedFile (self):\r
4696 global AllIncludeFileList\r
4697 return AllIncludeFileList\r
4698\r
30fdf114 4699if __name__ == "__main__":\r
b36d134f
LG
4700 import sys\r
4701 try:\r
4702 test_file = sys.argv[1]\r
5b0671c1 4703 except IndexError as v:\r
72443dd2 4704 print("Usage: %s filename" % sys.argv[0])\r
b36d134f
LG
4705 sys.exit(1)\r
4706\r
4707 parser = FdfParser(test_file)\r
30fdf114
LG
4708 try:\r
4709 parser.ParseFile()\r
4710 parser.CycleReferenceCheck()\r
5b0671c1 4711 except Warning as X:\r
72443dd2 4712 print(str(X))\r
30fdf114 4713 else:\r
72443dd2 4714 print("Success!")\r
30fdf114 4715\r