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