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