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