]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/FdfParser.py
BaseTools: Update the FV region name as upper letter
[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).upper())
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).upper())
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 self.__VerifyFile(AnyFileName)
3439
3440 return AnyFileName
3441
3442 ## __GetAnyFileStatement() method
3443 #
3444 # Get AnyFile for capsule
3445 #
3446 # @param self The object pointer
3447 # @param CapsuleObj for whom AnyFile is got
3448 # @retval True Successfully find a Anyfile statement
3449 # @retval False Not able to find a AnyFile statement
3450 #
3451 def __GetAnyFileStatement(self, CapsuleObj):
3452 AnyFileName = self.__ParseRawFileStatement()
3453 if not AnyFileName:
3454 return False
3455
3456 CapsuleAnyFile = CapsuleData.CapsuleAnyFile()
3457 CapsuleAnyFile.FileName = AnyFileName
3458 CapsuleObj.CapsuleDataList.append(CapsuleAnyFile)
3459 return True
3460
3461 ## __GetAfileStatement() method
3462 #
3463 # Get Afile for capsule
3464 #
3465 # @param self The object pointer
3466 # @param CapsuleObj for whom Afile is got
3467 # @retval True Successfully find a Afile statement
3468 # @retval False Not able to find a Afile statement
3469 #
3470 def __GetAfileStatement(self, CapsuleObj):
3471
3472 if not self.__IsKeyword("APPEND"):
3473 return False
3474
3475 if not self.__IsToken("="):
3476 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3477
3478 if not self.__GetNextToken():
3479 raise Warning("expected Afile name", self.FileName, self.CurrentLineNumber)
3480
3481 AfileName = self.__Token
3482 AfileBaseName = os.path.basename(AfileName)
3483
3484 if os.path.splitext(AfileBaseName)[1] not in [".bin",".BIN",".Bin",".dat",".DAT",".Dat",".data",".DATA",".Data"]:
3485 raise Warning('invalid binary file type, should be one of "bin","BIN","Bin","dat","DAT","Dat","data","DATA","Data"', \
3486 self.FileName, self.CurrentLineNumber)
3487
3488 if not os.path.isabs(AfileName):
3489 AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName)
3490 self.__VerifyFile(AfileName)
3491 else:
3492 if not os.path.exists(AfileName):
3493 raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber)
3494 else:
3495 pass
3496
3497 CapsuleAfile = CapsuleData.CapsuleAfile()
3498 CapsuleAfile.FileName = AfileName
3499 CapsuleObj.CapsuleDataList.append(CapsuleAfile)
3500 return True
3501
3502 ## __GetRule() method
3503 #
3504 # Get Rule section contents and store its data into rule list of self.Profile
3505 #
3506 # @param self The object pointer
3507 # @retval True Successfully find a Rule
3508 # @retval False Not able to find a Rule
3509 #
3510 def __GetRule(self):
3511
3512 if not self.__GetNextToken():
3513 return False
3514
3515 S = self.__Token.upper()
3516 if S.startswith("[") and not S.startswith("[RULE."):
3517 self.SectionParser(S)
3518 self.__UndoToken()
3519 return False
3520 self.__UndoToken()
3521 if not self.__IsToken("[Rule.", True):
3522 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
3523 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3524 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3525 raise Warning("expected [Rule.]", self.FileName, self.CurrentLineNumber)
3526
3527 if not self.__SkipToToken("."):
3528 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
3529
3530 Arch = self.__SkippedChars.rstrip(".")
3531 if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "AARCH64", "COMMON"):
3532 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
3533
3534 ModuleType = self.__GetModuleType()
3535
3536 TemplateName = ""
3537 if self.__IsToken("."):
3538 if not self.__GetNextWord():
3539 raise Warning("expected template name", self.FileName, self.CurrentLineNumber)
3540 TemplateName = self.__Token
3541
3542 if not self.__IsToken( "]"):
3543 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
3544
3545 RuleObj = self.__GetRuleFileStatements()
3546 RuleObj.Arch = Arch.upper()
3547 RuleObj.ModuleType = ModuleType
3548 RuleObj.TemplateName = TemplateName
3549 if TemplateName == '' :
3550 self.Profile.RuleDict['RULE' + \
3551 '.' + \
3552 Arch.upper() + \
3553 '.' + \
3554 ModuleType.upper() ] = RuleObj
3555 else :
3556 self.Profile.RuleDict['RULE' + \
3557 '.' + \
3558 Arch.upper() + \
3559 '.' + \
3560 ModuleType.upper() + \
3561 '.' + \
3562 TemplateName.upper() ] = RuleObj
3563 # self.Profile.RuleList.append(rule)
3564 return True
3565
3566 ## __GetModuleType() method
3567 #
3568 # Return the module type
3569 #
3570 # @param self The object pointer
3571 # @retval string module type
3572 #
3573 def __GetModuleType(self):
3574
3575 if not self.__GetNextWord():
3576 raise Warning("expected Module type", self.FileName, self.CurrentLineNumber)
3577 if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \
3578 "DXE_DRIVER", "DXE_SAL_DRIVER", \
3579 "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \
3580 "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \
3581 "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \
3582 "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE"):
3583 raise Warning("Unknown Module type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3584 return self.__Token
3585
3586 ## __GetFileExtension() method
3587 #
3588 # Return the file extension
3589 #
3590 # @param self The object pointer
3591 # @retval string file name extension
3592 #
3593 def __GetFileExtension(self):
3594 if not self.__IsToken("."):
3595 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
3596
3597 Ext = ""
3598 if self.__GetNextToken():
3599 Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)')
3600 if Pattern.match(self.__Token):
3601 Ext = self.__Token
3602 return '.' + Ext
3603 else:
3604 raise Warning("Unknown file extension '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3605
3606 else:
3607 raise Warning("expected file extension", self.FileName, self.CurrentLineNumber)
3608
3609 ## __GetRuleFileStatement() method
3610 #
3611 # Get rule contents
3612 #
3613 # @param self The object pointer
3614 # @retval Rule Rule object
3615 #
3616 def __GetRuleFileStatements(self):
3617
3618 if not self.__IsKeyword("FILE"):
3619 raise Warning("expected FILE", self.FileName, self.CurrentLineNumber)
3620
3621 if not self.__GetNextWord():
3622 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)
3623
3624 Type = self.__Token.strip().upper()
3625 if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\
3626 "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE"):
3627 raise Warning("Unknown FV type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3628
3629 if not self.__IsToken("="):
3630 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3631
3632 if not self.__IsKeyword("$(NAMED_GUID)"):
3633 if not self.__GetNextWord():
3634 raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber)
3635 if self.__Token == 'PCD':
3636 if not self.__IsToken( "("):
3637 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
3638 PcdPair = self.__GetNextPcdName()
3639 if not self.__IsToken( ")"):
3640 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
3641 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
3642
3643 NameGuid = self.__Token
3644
3645 KeepReloc = None
3646 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
3647 if self.__FileCouldHaveRelocFlag(Type):
3648 if self.__Token == 'RELOCS_STRIPPED':
3649 KeepReloc = False
3650 else:
3651 KeepReloc = True
3652 else:
3653 raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3654
3655 KeyStringList = []
3656 if self.__GetNextToken():
3657 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
3658 if Pattern.match(self.__Token):
3659 KeyStringList.append(self.__Token)
3660 if self.__IsToken(","):
3661 while self.__GetNextToken():
3662 if not Pattern.match(self.__Token):
3663 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
3664 KeyStringList.append(self.__Token)
3665
3666 if not self.__IsToken(","):
3667 break
3668
3669 else:
3670 self.__UndoToken()
3671
3672
3673 Fixed = False
3674 if self.__IsKeyword("Fixed", True):
3675 Fixed = True
3676
3677 CheckSum = False
3678 if self.__IsKeyword("CheckSum", True):
3679 CheckSum = True
3680
3681 AlignValue = ""
3682 if self.__GetAlignment():
3683 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3684 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3685 #For FFS, Auto is default option same to ""
3686 if not self.__Token == "Auto":
3687 AlignValue = self.__Token
3688
3689 if self.__IsToken("{"):
3690 # Complex file rule expected
3691 Rule = RuleComplexFile.RuleComplexFile()
3692 Rule.FvFileType = Type
3693 Rule.NameGuid = NameGuid
3694 Rule.Alignment = AlignValue
3695 Rule.CheckSum = CheckSum
3696 Rule.Fixed = Fixed
3697 Rule.KeyStringList = KeyStringList
3698 if KeepReloc != None:
3699 Rule.KeepReloc = KeepReloc
3700
3701 while True:
3702 IsEncapsulate = self.__GetRuleEncapsulationSection(Rule)
3703 IsLeaf = self.__GetEfiSection(Rule)
3704 if not IsEncapsulate and not IsLeaf:
3705 break
3706
3707 if not self.__IsToken("}"):
3708 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
3709
3710 return Rule
3711
3712 else:
3713 # Simple file rule expected
3714 if not self.__GetNextWord():
3715 raise Warning("expected leaf section type", self.FileName, self.CurrentLineNumber)
3716
3717 SectionName = self.__Token
3718
3719 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3720 "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"):
3721 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)
3722
3723
3724 if self.__IsKeyword("Fixed", True):
3725 Fixed = True
3726
3727 if self.__IsKeyword("CheckSum", True):
3728 CheckSum = True
3729
3730 SectAlignment = ""
3731 if self.__GetAlignment():
3732 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3733 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3734 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
3735 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
3736 SectAlignment = self.__Token
3737
3738 Ext = None
3739 if self.__IsToken('|'):
3740 Ext = self.__GetFileExtension()
3741 elif not self.__GetNextToken():
3742 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
3743
3744 Rule = RuleSimpleFile.RuleSimpleFile()
3745 Rule.SectionType = SectionName
3746 Rule.FvFileType = Type
3747 Rule.NameGuid = NameGuid
3748 Rule.Alignment = AlignValue
3749 Rule.SectAlignment = SectAlignment
3750 Rule.CheckSum = CheckSum
3751 Rule.Fixed = Fixed
3752 Rule.KeyStringList = KeyStringList
3753 if KeepReloc != None:
3754 Rule.KeepReloc = KeepReloc
3755 Rule.FileExtension = Ext
3756 Rule.FileName = self.__Token
3757 return Rule
3758
3759 ## __GetEfiSection() method
3760 #
3761 # Get section list for Rule
3762 #
3763 # @param self The object pointer
3764 # @param Obj for whom section is got
3765 # @retval True Successfully find section statement
3766 # @retval False Not able to find section statement
3767 #
3768 def __GetEfiSection(self, Obj):
3769
3770 OldPos = self.GetFileBufferPos()
3771 if not self.__GetNextWord():
3772 return False
3773 SectionName = self.__Token
3774
3775 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3776 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3777 self.__UndoToken()
3778 return False
3779
3780 if SectionName == "FV_IMAGE":
3781 FvImageSectionObj = FvImageSection.FvImageSection()
3782 if self.__IsKeyword("FV_IMAGE"):
3783 pass
3784 if self.__IsToken( "{"):
3785 FvObj = Fv.FV()
3786 self.__GetDefineStatements(FvObj)
3787 self.__GetBlockStatement(FvObj)
3788 self.__GetSetStatements(FvObj)
3789 self.__GetFvAlignment(FvObj)
3790 self.__GetFvAttributes(FvObj)
3791 self.__GetAprioriSection(FvObj)
3792 self.__GetAprioriSection(FvObj)
3793
3794 while True:
3795 IsInf = self.__GetInfStatement(FvObj)
3796 IsFile = self.__GetFileStatement(FvObj)
3797 if not IsInf and not IsFile:
3798 break
3799
3800 if not self.__IsToken( "}"):
3801 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
3802 FvImageSectionObj.Fv = FvObj
3803 FvImageSectionObj.FvName = None
3804
3805 else:
3806 if not self.__IsKeyword("FV"):
3807 raise Warning("expected 'FV'", self.FileName, self.CurrentLineNumber)
3808 FvImageSectionObj.FvFileType = self.__Token
3809
3810 if self.__GetAlignment():
3811 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3812 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3813 FvImageSectionObj.Alignment = self.__Token
3814
3815 if self.__IsToken('|'):
3816 FvImageSectionObj.FvFileExtension = self.__GetFileExtension()
3817 elif self.__GetNextToken():
3818 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3819 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3820 FvImageSectionObj.FvFileName = self.__Token
3821 else:
3822 self.__UndoToken()
3823 else:
3824 raise Warning("expected FV file name", self.FileName, self.CurrentLineNumber)
3825
3826 Obj.SectionList.append(FvImageSectionObj)
3827 return True
3828
3829 EfiSectionObj = EfiSection.EfiSection()
3830 EfiSectionObj.SectionType = SectionName
3831
3832 if not self.__GetNextToken():
3833 raise Warning("expected file type", self.FileName, self.CurrentLineNumber)
3834
3835 if self.__Token == "STRING":
3836 if not self.__RuleSectionCouldHaveString(EfiSectionObj.SectionType):
3837 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3838
3839 if not self.__IsToken('='):
3840 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3841
3842 if not self.__GetNextToken():
3843 raise Warning("expected Quoted String", self.FileName, self.CurrentLineNumber)
3844
3845 if self.__GetStringData():
3846 EfiSectionObj.StringData = self.__Token
3847
3848 if self.__IsKeyword("BUILD_NUM"):
3849 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
3850 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3851
3852 if not self.__IsToken("="):
3853 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3854 if not self.__GetNextToken():
3855 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)
3856 EfiSectionObj.BuildNum = self.__Token
3857
3858 else:
3859 EfiSectionObj.FileType = self.__Token
3860 self.__CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)
3861
3862 if self.__IsKeyword("Optional"):
3863 if not self.__RuleSectionCouldBeOptional(EfiSectionObj.SectionType):
3864 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3865 EfiSectionObj.Optional = True
3866
3867 if self.__IsKeyword("BUILD_NUM"):
3868 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
3869 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3870
3871 if not self.__IsToken("="):
3872 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3873 if not self.__GetNextToken():
3874 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)
3875 EfiSectionObj.BuildNum = self.__Token
3876
3877 if self.__GetAlignment():
3878 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3879 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3880 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
3881 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
3882 EfiSectionObj.Alignment = self.__Token
3883
3884 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
3885 if self.__SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):
3886 if self.__Token == 'RELOCS_STRIPPED':
3887 EfiSectionObj.KeepReloc = False
3888 else:
3889 EfiSectionObj.KeepReloc = True
3890 if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc:
3891 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
3892 else:
3893 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
3894
3895
3896 if self.__IsToken('|'):
3897 EfiSectionObj.FileExtension = self.__GetFileExtension()
3898 elif self.__GetNextToken():
3899 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3900 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3901
3902 if self.__Token.startswith('PCD'):
3903 self.__UndoToken()
3904 self.__GetNextWord()
3905
3906 if self.__Token == 'PCD':
3907 if not self.__IsToken( "("):
3908 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
3909 PcdPair = self.__GetNextPcdName()
3910 if not self.__IsToken( ")"):
3911 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
3912 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
3913
3914 EfiSectionObj.FileName = self.__Token
3915
3916 else:
3917 self.__UndoToken()
3918 else:
3919 raise Warning("expected section file name", self.FileName, self.CurrentLineNumber)
3920
3921 Obj.SectionList.append(EfiSectionObj)
3922 return True
3923
3924 ## __RuleSectionCouldBeOptional() method
3925 #
3926 # Get whether a section could be optional
3927 #
3928 # @param self The object pointer
3929 # @param SectionType The section type to check
3930 # @retval True section could be optional
3931 # @retval False section never optional
3932 #
3933 def __RuleSectionCouldBeOptional(self, SectionType):
3934 if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"):
3935 return True
3936 else:
3937 return False
3938
3939 ## __RuleSectionCouldHaveBuildNum() method
3940 #
3941 # Get whether a section could have build number information
3942 #
3943 # @param self The object pointer
3944 # @param SectionType The section type to check
3945 # @retval True section could have build number information
3946 # @retval False section never have build number information
3947 #
3948 def __RuleSectionCouldHaveBuildNum(self, SectionType):
3949 if SectionType in ("VERSION"):
3950 return True
3951 else:
3952 return False
3953
3954 ## __RuleSectionCouldHaveString() method
3955 #
3956 # Get whether a section could have string
3957 #
3958 # @param self The object pointer
3959 # @param SectionType The section type to check
3960 # @retval True section could have string
3961 # @retval False section never have string
3962 #
3963 def __RuleSectionCouldHaveString(self, SectionType):
3964 if SectionType in ("UI", "VERSION"):
3965 return True
3966 else:
3967 return False
3968
3969 ## __CheckRuleSectionFileType() method
3970 #
3971 # Get whether a section matches a file type
3972 #
3973 # @param self The object pointer
3974 # @param SectionType The section type to check
3975 # @param FileType The file type to check
3976 #
3977 def __CheckRuleSectionFileType(self, SectionType, FileType):
3978 if SectionType == "COMPAT16":
3979 if FileType not in ("COMPAT16", "SEC_COMPAT16"):
3980 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3981 elif SectionType == "PE32":
3982 if FileType not in ("PE32", "SEC_PE32"):
3983 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3984 elif SectionType == "PIC":
3985 if FileType not in ("PIC", "PIC"):
3986 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3987 elif SectionType == "TE":
3988 if FileType not in ("TE", "SEC_TE"):
3989 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3990 elif SectionType == "RAW":
3991 if FileType not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"):
3992 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3993 elif SectionType == "DXE_DEPEX" or SectionType == "SMM_DEPEX":
3994 if FileType not in ("DXE_DEPEX", "SEC_DXE_DEPEX", "SMM_DEPEX"):
3995 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3996 elif SectionType == "UI":
3997 if FileType not in ("UI", "SEC_UI"):
3998 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3999 elif SectionType == "VERSION":
4000 if FileType not in ("VERSION", "SEC_VERSION"):
4001 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
4002 elif SectionType == "PEI_DEPEX":
4003 if FileType not in ("PEI_DEPEX", "SEC_PEI_DEPEX"):
4004 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
4005 elif SectionType == "GUID":
4006 if FileType not in ("PE32", "SEC_GUID"):
4007 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
4008
4009 ## __GetRuleEncapsulationSection() method
4010 #
4011 # Get encapsulation section for Rule
4012 #
4013 # @param self The object pointer
4014 # @param Rule for whom section is got
4015 # @retval True Successfully find section statement
4016 # @retval False Not able to find section statement
4017 #
4018 def __GetRuleEncapsulationSection(self, Rule):
4019
4020 if self.__IsKeyword( "COMPRESS"):
4021 Type = "PI_STD"
4022 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
4023 Type = self.__Token
4024
4025 if not self.__IsToken("{"):
4026 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
4027
4028 CompressSectionObj = CompressSection.CompressSection()
4029
4030 CompressSectionObj.CompType = Type
4031 # Recursive sections...
4032 while True:
4033 IsEncapsulate = self.__GetRuleEncapsulationSection(CompressSectionObj)
4034 IsLeaf = self.__GetEfiSection(CompressSectionObj)
4035 if not IsEncapsulate and not IsLeaf:
4036 break
4037
4038 if not self.__IsToken( "}"):
4039 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
4040 Rule.SectionList.append(CompressSectionObj)
4041
4042 return True
4043
4044 elif self.__IsKeyword( "GUIDED"):
4045 GuidValue = None
4046 if self.__GetNextGuid():
4047 GuidValue = self.__Token
4048
4049 if self.__IsKeyword( "$(NAMED_GUID)"):
4050 GuidValue = self.__Token
4051
4052 AttribDict = self.__GetGuidAttrib()
4053
4054 if not self.__IsToken("{"):
4055 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
4056 GuidSectionObj = GuidSection.GuidSection()
4057 GuidSectionObj.NameGuid = GuidValue
4058 GuidSectionObj.SectionType = "GUIDED"
4059 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
4060 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
4061 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]
4062
4063 # Efi sections...
4064 while True:
4065 IsEncapsulate = self.__GetRuleEncapsulationSection(GuidSectionObj)
4066 IsLeaf = self.__GetEfiSection(GuidSectionObj)
4067 if not IsEncapsulate and not IsLeaf:
4068 break
4069
4070 if not self.__IsToken( "}"):
4071 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
4072 Rule.SectionList.append(GuidSectionObj)
4073
4074 return True
4075
4076 return False
4077
4078 ## __GetVtf() method
4079 #
4080 # Get VTF section contents and store its data into VTF list of self.Profile
4081 #
4082 # @param self The object pointer
4083 # @retval True Successfully find a VTF
4084 # @retval False Not able to find a VTF
4085 #
4086 def __GetVtf(self):
4087
4088 if not self.__GetNextToken():
4089 return False
4090
4091 S = self.__Token.upper()
4092 if S.startswith("[") and not S.startswith("[VTF."):
4093 self.SectionParser(S)
4094 self.__UndoToken()
4095 return False
4096
4097 self.__UndoToken()
4098 if not self.__IsToken("[VTF.", True):
4099 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
4100 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
4101 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
4102 raise Warning("expected [VTF.]", self.FileName, self.CurrentLineNumber)
4103
4104 if not self.__SkipToToken("."):
4105 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
4106
4107 Arch = self.__SkippedChars.rstrip(".").upper()
4108 if Arch not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
4109 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
4110
4111 if not self.__GetNextWord():
4112 raise Warning("expected VTF name", self.FileName, self.CurrentLineNumber)
4113 Name = self.__Token.upper()
4114
4115 VtfObj = Vtf.Vtf()
4116 VtfObj.UiName = Name
4117 VtfObj.KeyArch = Arch
4118
4119 if self.__IsToken(","):
4120 if not self.__GetNextWord():
4121 raise Warning("expected Arch list", self.FileName, self.CurrentLineNumber)
4122 if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
4123 raise Warning("Unknown Arch '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
4124 VtfObj.ArchList = self.__Token.upper()
4125
4126 if not self.__IsToken( "]"):
4127 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
4128
4129 if self.__IsKeyword("IA32_RST_BIN"):
4130 if not self.__IsToken("="):
4131 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4132
4133 if not self.__GetNextToken():
4134 raise Warning("expected Reset file", self.FileName, self.CurrentLineNumber)
4135
4136 VtfObj.ResetBin = self.__Token
4137 if VtfObj.ResetBin.replace('$(WORKSPACE)', '').find('$') == -1:
4138 #check for file path
4139 ErrorCode, ErrorInfo = PathClass(NormPath(VtfObj.ResetBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()
4140 if ErrorCode != 0:
4141 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
4142
4143 while self.__GetComponentStatement(VtfObj):
4144 pass
4145
4146 self.Profile.VtfList.append(VtfObj)
4147 return True
4148
4149 ## __GetComponentStatement() method
4150 #
4151 # Get components in VTF
4152 #
4153 # @param self The object pointer
4154 # @param VtfObj for whom component is got
4155 # @retval True Successfully find a component
4156 # @retval False Not able to find a component
4157 #
4158 def __GetComponentStatement(self, VtfObj):
4159
4160 if not self.__IsKeyword("COMP_NAME"):
4161 return False
4162
4163 if not self.__IsToken("="):
4164 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4165
4166 if not self.__GetNextWord():
4167 raise Warning("expected Component Name", self.FileName, self.CurrentLineNumber)
4168
4169 CompStatementObj = ComponentStatement.ComponentStatement()
4170 CompStatementObj.CompName = self.__Token
4171
4172 if not self.__IsKeyword("COMP_LOC"):
4173 raise Warning("expected COMP_LOC", self.FileName, self.CurrentLineNumber)
4174
4175 if not self.__IsToken("="):
4176 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4177
4178 CompStatementObj.CompLoc = ""
4179 if self.__GetNextWord():
4180 CompStatementObj.CompLoc = self.__Token
4181 if self.__IsToken('|'):
4182 if not self.__GetNextWord():
4183 raise Warning("Expected Region Name", self.FileName, self.CurrentLineNumber)
4184
4185 if self.__Token not in ("F", "N", "S"): #, "H", "L", "PH", "PL"): not support
4186 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
4187
4188 CompStatementObj.FilePos = self.__Token
4189 else:
4190 self.CurrentLineNumber += 1
4191 self.CurrentOffsetWithinLine = 0
4192
4193 if not self.__IsKeyword("COMP_TYPE"):
4194 raise Warning("expected COMP_TYPE", self.FileName, self.CurrentLineNumber)
4195
4196 if not self.__IsToken("="):
4197 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4198
4199 if not self.__GetNextToken():
4200 raise Warning("expected Component type", self.FileName, self.CurrentLineNumber)
4201 if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"):
4202 if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \
4203 not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]):
4204 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
4205 CompStatementObj.CompType = self.__Token
4206
4207 if not self.__IsKeyword("COMP_VER"):
4208 raise Warning("expected COMP_VER", self.FileName, self.CurrentLineNumber)
4209
4210 if not self.__IsToken("="):
4211 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4212
4213 if not self.__GetNextToken():
4214 raise Warning("expected Component version", self.FileName, self.CurrentLineNumber)
4215
4216 Pattern = re.compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', re.DOTALL)
4217 if Pattern.match(self.__Token) == None:
4218 raise Warning("Unknown version format '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
4219 CompStatementObj.CompVer = self.__Token
4220
4221 if not self.__IsKeyword("COMP_CS"):
4222 raise Warning("expected COMP_CS", self.FileName, self.CurrentLineNumber)
4223
4224 if not self.__IsToken("="):
4225 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4226
4227 if not self.__GetNextToken():
4228 raise Warning("expected Component CS", self.FileName, self.CurrentLineNumber)
4229 if self.__Token not in ("1", "0"):
4230 raise Warning("Unknown Component CS '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
4231 CompStatementObj.CompCs = self.__Token
4232
4233
4234 if not self.__IsKeyword("COMP_BIN"):
4235 raise Warning("expected COMP_BIN", self.FileName, self.CurrentLineNumber)
4236
4237 if not self.__IsToken("="):
4238 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4239
4240 if not self.__GetNextToken():
4241 raise Warning("expected Component file", self.FileName, self.CurrentLineNumber)
4242
4243 CompStatementObj.CompBin = self.__Token
4244 if CompStatementObj.CompBin != '-' and CompStatementObj.CompBin.replace('$(WORKSPACE)', '').find('$') == -1:
4245 #check for file path
4246 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()
4247 if ErrorCode != 0:
4248 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
4249
4250 if not self.__IsKeyword("COMP_SYM"):
4251 raise Warning("expected COMP_SYM", self.FileName, self.CurrentLineNumber)
4252
4253 if not self.__IsToken("="):
4254 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4255
4256 if not self.__GetNextToken():
4257 raise Warning("expected Component symbol file", self.FileName, self.CurrentLineNumber)
4258
4259 CompStatementObj.CompSym = self.__Token
4260 if CompStatementObj.CompSym != '-' and CompStatementObj.CompSym.replace('$(WORKSPACE)', '').find('$') == -1:
4261 #check for file path
4262 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompSym), GenFdsGlobalVariable.WorkSpaceDir).Validate()
4263 if ErrorCode != 0:
4264 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
4265
4266 if not self.__IsKeyword("COMP_SIZE"):
4267 raise Warning("expected COMP_SIZE", self.FileName, self.CurrentLineNumber)
4268
4269 if not self.__IsToken("="):
4270 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4271
4272 if self.__IsToken("-"):
4273 CompStatementObj.CompSize = self.__Token
4274 elif self.__GetNextDecimalNumber():
4275 CompStatementObj.CompSize = self.__Token
4276 elif self.__GetNextHexNumber():
4277 CompStatementObj.CompSize = self.__Token
4278 else:
4279 raise Warning("Unknown size '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
4280
4281 VtfObj.ComponentStatementList.append(CompStatementObj)
4282 return True
4283
4284 ## __GetOptionRom() method
4285 #
4286 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
4287 #
4288 # @param self The object pointer
4289 # @retval True Successfully find a OptionROM
4290 # @retval False Not able to find a OptionROM
4291 #
4292 def __GetOptionRom(self):
4293
4294 if not self.__GetNextToken():
4295 return False
4296
4297 S = self.__Token.upper()
4298 if S.startswith("[") and not S.startswith("[OPTIONROM."):
4299 self.SectionParser(S)
4300 self.__UndoToken()
4301 return False
4302
4303 self.__UndoToken()
4304 if not self.__IsToken("[OptionRom.", True):
4305 raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
4306
4307 OptRomName = self.__GetUiName()
4308
4309 if not self.__IsToken( "]"):
4310 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
4311
4312 OptRomObj = OptionRom.OPTIONROM()
4313 OptRomObj.DriverName = OptRomName
4314 self.Profile.OptRomDict[OptRomName] = OptRomObj
4315
4316 while True:
4317 isInf = self.__GetOptRomInfStatement(OptRomObj)
4318 isFile = self.__GetOptRomFileStatement(OptRomObj)
4319 if not isInf and not isFile:
4320 break
4321
4322 return True
4323
4324 ## __GetOptRomInfStatement() method
4325 #
4326 # Get INF statements
4327 #
4328 # @param self The object pointer
4329 # @param Obj for whom inf statement is got
4330 # @retval True Successfully find inf statement
4331 # @retval False Not able to find inf statement
4332 #
4333 def __GetOptRomInfStatement(self, Obj):
4334
4335 if not self.__IsKeyword( "INF"):
4336 return False
4337
4338 ffsInf = OptRomInfStatement.OptRomInfStatement()
4339 self.__GetInfOptions( ffsInf)
4340
4341 if not self.__GetNextToken():
4342 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)
4343 ffsInf.InfFileName = self.__Token
4344 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:
4345 #check for file path
4346 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
4347 if ErrorCode != 0:
4348 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
4349
4350 if not ffsInf.InfFileName in self.Profile.InfList:
4351 self.Profile.InfList.append(ffsInf.InfFileName)
4352 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
4353 self.Profile.InfFileLineList.append(FileLineTuple)
4354
4355
4356 self.__GetOptRomOverrides (ffsInf)
4357
4358 Obj.FfsList.append(ffsInf)
4359 return True
4360
4361 ## __GetOptRomOverrides() method
4362 #
4363 # Get overrides for OptROM INF & FILE
4364 #
4365 # @param self The object pointer
4366 # @param FfsInfObj for whom overrides is got
4367 #
4368 def __GetOptRomOverrides(self, Obj):
4369 if self.__IsToken('{'):
4370 Overrides = OptionRom.OverrideAttribs()
4371 while True:
4372 if self.__IsKeyword( "PCI_VENDOR_ID"):
4373 if not self.__IsToken( "="):
4374 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4375 if not self.__GetNextHexNumber():
4376 raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber)
4377 Overrides.PciVendorId = self.__Token
4378 continue
4379
4380 if self.__IsKeyword( "PCI_CLASS_CODE"):
4381 if not self.__IsToken( "="):
4382 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4383 if not self.__GetNextHexNumber():
4384 raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber)
4385 Overrides.PciClassCode = self.__Token
4386 continue
4387
4388 if self.__IsKeyword( "PCI_DEVICE_ID"):
4389 if not self.__IsToken( "="):
4390 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4391 if not self.__GetNextHexNumber():
4392 raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber)
4393
4394 Overrides.PciDeviceId = self.__Token
4395 continue
4396
4397 if self.__IsKeyword( "PCI_REVISION"):
4398 if not self.__IsToken( "="):
4399 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4400 if not self.__GetNextHexNumber():
4401 raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber)
4402 Overrides.PciRevision = self.__Token
4403 continue
4404
4405 if self.__IsKeyword( "PCI_COMPRESS"):
4406 if not self.__IsToken( "="):
4407 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4408 if not self.__GetNextToken():
4409 raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)
4410 Overrides.NeedCompress = self.__Token.upper() == 'TRUE'
4411 continue
4412
4413 if self.__IsToken( "}"):
4414 break
4415 else:
4416 EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)
4417
4418 Obj.OverrideAttribs = Overrides
4419
4420 ## __GetOptRomFileStatement() method
4421 #
4422 # Get FILE statements
4423 #
4424 # @param self The object pointer
4425 # @param Obj for whom FILE statement is got
4426 # @retval True Successfully find FILE statement
4427 # @retval False Not able to find FILE statement
4428 #
4429 def __GetOptRomFileStatement(self, Obj):
4430
4431 if not self.__IsKeyword( "FILE"):
4432 return False
4433
4434 FfsFileObj = OptRomFileStatement.OptRomFileStatement()
4435
4436 if not self.__IsKeyword("EFI") and not self.__IsKeyword("BIN"):
4437 raise Warning("expected Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber)
4438 FfsFileObj.FileType = self.__Token
4439
4440 if not self.__GetNextToken():
4441 raise Warning("expected File path", self.FileName, self.CurrentLineNumber)
4442 FfsFileObj.FileName = self.__Token
4443 if FfsFileObj.FileName.replace('$(WORKSPACE)', '').find('$') == -1:
4444 #check for file path
4445 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
4446 if ErrorCode != 0:
4447 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
4448
4449 if FfsFileObj.FileType == 'EFI':
4450 self.__GetOptRomOverrides(FfsFileObj)
4451
4452 Obj.FfsList.append(FfsFileObj)
4453
4454 return True
4455
4456 ## __GetCapInFd() method
4457 #
4458 # Get Cap list contained in FD
4459 #
4460 # @param self The object pointer
4461 # @param FdName FD name
4462 # @retval CapList List of Capsule in FD
4463 #
4464 def __GetCapInFd (self, FdName):
4465
4466 CapList = []
4467 if FdName.upper() in self.Profile.FdDict.keys():
4468 FdObj = self.Profile.FdDict[FdName.upper()]
4469 for elementRegion in FdObj.RegionList:
4470 if elementRegion.RegionType == 'CAPSULE':
4471 for elementRegionData in elementRegion.RegionDataList:
4472 if elementRegionData.endswith(".cap"):
4473 continue
4474 if elementRegionData != None and elementRegionData.upper() not in CapList:
4475 CapList.append(elementRegionData.upper())
4476 return CapList
4477
4478 ## __GetReferencedFdCapTuple() method
4479 #
4480 # Get FV and FD list referenced by a capsule image
4481 #
4482 # @param self The object pointer
4483 # @param CapObj Capsule section to be searched
4484 # @param RefFdList referenced FD by section
4485 # @param RefFvList referenced FV by section
4486 #
4487 def __GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):
4488
4489 for CapsuleDataObj in CapObj.CapsuleDataList :
4490 if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName != None and CapsuleDataObj.FvName.upper() not in RefFvList:
4491 RefFvList.append (CapsuleDataObj.FvName.upper())
4492 elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName != None and CapsuleDataObj.FdName.upper() not in RefFdList:
4493 RefFdList.append (CapsuleDataObj.FdName.upper())
4494 elif CapsuleDataObj.Ffs != None:
4495 if isinstance(CapsuleDataObj.Ffs, FfsFileStatement.FileStatement):
4496 if CapsuleDataObj.Ffs.FvName != None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:
4497 RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())
4498 elif CapsuleDataObj.Ffs.FdName != None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:
4499 RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())
4500 else:
4501 self.__GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)
4502
4503 ## __GetFvInFd() method
4504 #
4505 # Get FV list contained in FD
4506 #
4507 # @param self The object pointer
4508 # @param FdName FD name
4509 # @retval FvList list of FV in FD
4510 #
4511 def __GetFvInFd (self, FdName):
4512
4513 FvList = []
4514 if FdName.upper() in self.Profile.FdDict.keys():
4515 FdObj = self.Profile.FdDict[FdName.upper()]
4516 for elementRegion in FdObj.RegionList:
4517 if elementRegion.RegionType == 'FV':
4518 for elementRegionData in elementRegion.RegionDataList:
4519 if elementRegionData.endswith(".fv"):
4520 continue
4521 if elementRegionData != None and elementRegionData.upper() not in FvList:
4522 FvList.append(elementRegionData.upper())
4523 return FvList
4524
4525 ## __GetReferencedFdFvTuple() method
4526 #
4527 # Get FD and FV list referenced by a FFS file
4528 #
4529 # @param self The object pointer
4530 # @param FfsFile contains sections to be searched
4531 # @param RefFdList referenced FD by section
4532 # @param RefFvList referenced FV by section
4533 #
4534 def __GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):
4535
4536 for FfsObj in FvObj.FfsList:
4537 if isinstance(FfsObj, FfsFileStatement.FileStatement):
4538 if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList:
4539 RefFvList.append(FfsObj.FvName.upper())
4540 elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList:
4541 RefFdList.append(FfsObj.FdName.upper())
4542 else:
4543 self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)
4544
4545 ## __GetReferencedFdFvTupleFromSection() method
4546 #
4547 # Get FD and FV list referenced by a FFS section
4548 #
4549 # @param self The object pointer
4550 # @param FfsFile contains sections to be searched
4551 # @param FdList referenced FD by section
4552 # @param FvList referenced FV by section
4553 #
4554 def __GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):
4555
4556 SectionStack = []
4557 SectionStack.extend(FfsFile.SectionList)
4558 while SectionStack != []:
4559 SectionObj = SectionStack.pop()
4560 if isinstance(SectionObj, FvImageSection.FvImageSection):
4561 if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList:
4562 FvList.append(SectionObj.FvName.upper())
4563 if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList:
4564 FvList.append(SectionObj.Fv.UiFvName.upper())
4565 self.__GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)
4566
4567 if isinstance(SectionObj, CompressSection.CompressSection) or isinstance(SectionObj, GuidSection.GuidSection):
4568 SectionStack.extend(SectionObj.SectionList)
4569
4570 ## CycleReferenceCheck() method
4571 #
4572 # Check whether cycle reference exists in FDF
4573 #
4574 # @param self The object pointer
4575 # @retval True cycle reference exists
4576 # @retval False Not exists cycle reference
4577 #
4578 def CycleReferenceCheck(self):
4579 #
4580 # Check the cycle between FV and FD image
4581 #
4582 MaxLength = len (self.Profile.FvDict)
4583 for FvName in self.Profile.FvDict.keys():
4584 LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName
4585 RefFvStack = []
4586 RefFvStack.append(FvName)
4587 FdAnalyzedList = []
4588
4589 Index = 0
4590 while RefFvStack != [] and Index < MaxLength:
4591 Index = Index + 1
4592 FvNameFromStack = RefFvStack.pop()
4593 if FvNameFromStack.upper() in self.Profile.FvDict.keys():
4594 FvObj = self.Profile.FvDict[FvNameFromStack.upper()]
4595 else:
4596 continue
4597
4598 RefFdList = []
4599 RefFvList = []
4600 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
4601
4602 for RefFdName in RefFdList:
4603 if RefFdName in FdAnalyzedList:
4604 continue
4605
4606 LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)
4607 FvInFdList = self.__GetFvInFd(RefFdName)
4608 if FvInFdList != []:
4609 for FvNameInFd in FvInFdList:
4610 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)
4611 if FvNameInFd not in RefFvStack:
4612 RefFvStack.append(FvNameInFd)
4613
4614 if FvName in RefFvStack or FvNameFromStack in RefFvStack:
4615 EdkLogger.info(LogStr)
4616 return True
4617 FdAnalyzedList.append(RefFdName)
4618
4619 for RefFvName in RefFvList:
4620 LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)
4621 if RefFvName not in RefFvStack:
4622 RefFvStack.append(RefFvName)
4623
4624 if FvName in RefFvStack or FvNameFromStack in RefFvStack:
4625 EdkLogger.info(LogStr)
4626 return True
4627
4628 #
4629 # Check the cycle between Capsule and FD image
4630 #
4631 MaxLength = len (self.Profile.CapsuleDict)
4632 for CapName in self.Profile.CapsuleDict.keys():
4633 #
4634 # Capsule image to be checked.
4635 #
4636 LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4637 RefCapStack = []
4638 RefCapStack.append(CapName)
4639 FdAnalyzedList = []
4640 FvAnalyzedList = []
4641
4642 Index = 0
4643 while RefCapStack != [] and Index < MaxLength:
4644 Index = Index + 1
4645 CapNameFromStack = RefCapStack.pop()
4646 if CapNameFromStack.upper() in self.Profile.CapsuleDict.keys():
4647 CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]
4648 else:
4649 continue
4650
4651 RefFvList = []
4652 RefFdList = []
4653 self.__GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)
4654
4655 FvListLength = 0
4656 FdListLength = 0
4657 while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):
4658 for RefFdName in RefFdList:
4659 if RefFdName in FdAnalyzedList:
4660 continue
4661
4662 LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)
4663 CapInFdList = self.__GetCapInFd(RefFdName)
4664 if CapInFdList != []:
4665 for CapNameInFd in CapInFdList:
4666 LogStr += "FD %s contains Capsule %s\n" % (RefFdName,CapNameInFd)
4667 if CapNameInFd not in RefCapStack:
4668 RefCapStack.append(CapNameInFd)
4669
4670 if CapName in RefCapStack or CapNameFromStack in RefCapStack:
4671 EdkLogger.info(LogStr)
4672 return True
4673
4674 FvInFdList = self.__GetFvInFd(RefFdName)
4675 if FvInFdList != []:
4676 for FvNameInFd in FvInFdList:
4677 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)
4678 if FvNameInFd not in RefFvList:
4679 RefFvList.append(FvNameInFd)
4680
4681 FdAnalyzedList.append(RefFdName)
4682 #
4683 # the number of the parsed FV and FD image
4684 #
4685 FvListLength = len (RefFvList)
4686 FdListLength = len (RefFdList)
4687 for RefFvName in RefFvList:
4688 if RefFvName in FvAnalyzedList:
4689 continue
4690 LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)
4691 if RefFvName.upper() in self.Profile.FvDict.keys():
4692 FvObj = self.Profile.FvDict[RefFvName.upper()]
4693 else:
4694 continue
4695 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
4696 FvAnalyzedList.append(RefFvName)
4697
4698 return False
4699
4700 if __name__ == "__main__":
4701 import sys
4702 try:
4703 test_file = sys.argv[1]
4704 except IndexError, v:
4705 print "Usage: %s filename" % sys.argv[0]
4706 sys.exit(1)
4707
4708 parser = FdfParser(test_file)
4709 try:
4710 parser.ParseFile()
4711 parser.CycleReferenceCheck()
4712 except Warning, X:
4713 print str(X)
4714 else:
4715 print "Success!"
4716