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