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