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