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