]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/FdfParser.py
BaseTools: report error if source module INF is only list in FDF file
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FdfParser.py
1 ## @file
2 # parse FDF file
3 #
4 # Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
5 # Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
6 #
7 # This program and the accompanying materials
8 # are licensed and made available under the terms and conditions of the BSD License
9 # which accompanies this distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
11 #
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 #
15
16 ##
17 # Import Modules
18 #
19 import re
20
21 import Fd
22 import Region
23 import Fv
24 import AprioriSection
25 import FfsInfStatement
26 import FfsFileStatement
27 import VerSection
28 import UiSection
29 import FvImageSection
30 import DataSection
31 import DepexSection
32 import CompressSection
33 import GuidSection
34 import Capsule
35 import CapsuleData
36 import Rule
37 import RuleComplexFile
38 import RuleSimpleFile
39 import EfiSection
40 import Vtf
41 import ComponentStatement
42 import OptionRom
43 import OptRomInfStatement
44 import OptRomFileStatement
45
46 from GenFdsGlobalVariable import GenFdsGlobalVariable
47 from Common.BuildToolError import *
48 from Common import EdkLogger
49 from Common.Misc import PathClass
50 from Common.String import NormPath
51 import Common.GlobalData as GlobalData
52 from Common.Expression import *
53 from Common import GlobalData
54 from Common.String import ReplaceMacro
55
56 from Common.Misc import tdict
57
58 import Common.LongFilePathOs as os
59 from Common.LongFilePathSupport import OpenLongFilePath as open
60
61 ##define T_CHAR_SPACE ' '
62 ##define T_CHAR_NULL '\0'
63 ##define T_CHAR_CR '\r'
64 ##define T_CHAR_TAB '\t'
65 ##define T_CHAR_LF '\n'
66 ##define T_CHAR_SLASH '/'
67 ##define T_CHAR_BACKSLASH '\\'
68 ##define T_CHAR_DOUBLE_QUOTE '\"'
69 ##define T_CHAR_SINGLE_QUOTE '\''
70 ##define T_CHAR_STAR '*'
71 ##define T_CHAR_HASH '#'
72
73 (T_CHAR_SPACE, T_CHAR_NULL, T_CHAR_CR, T_CHAR_TAB, T_CHAR_LF, T_CHAR_SLASH, \
74 T_CHAR_BACKSLASH, T_CHAR_DOUBLE_QUOTE, T_CHAR_SINGLE_QUOTE, T_CHAR_STAR, T_CHAR_HASH) = \
75 (' ', '\0', '\r', '\t', '\n', '/', '\\', '\"', '\'', '*', '#')
76
77 SEPERATOR_TUPLE = ('=', '|', ',', '{', '}')
78
79 RegionSizePattern = re.compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
80 RegionSizeGuidPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*\|\s*(?P<size>\w+\.\w+)\s*")
81 RegionOffsetPcdPattern = re.compile("\s*(?P<base>\w+\.\w+)\s*$")
82 ShortcutPcdPattern = re.compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
83
84 AllIncludeFileList = []
85
86 # Get the closest parent
87 def GetParentAtLine (Line):
88 for Profile in AllIncludeFileList:
89 if Profile.IsLineInFile(Line):
90 return Profile
91 return None
92
93 # Check include loop
94 def IsValidInclude (File, Line):
95 for Profile in AllIncludeFileList:
96 if Profile.IsLineInFile(Line) and Profile.FileName == File:
97 return False
98
99 return True
100
101 def GetRealFileLine (File, Line):
102
103 InsertedLines = 0
104 for Profile in AllIncludeFileList:
105 if Profile.IsLineInFile(Line):
106 return Profile.GetLineInFile(Line)
107 elif Line >= Profile.InsertStartLineNumber and Profile.Level == 1:
108 InsertedLines += Profile.GetTotalLines()
109
110 return (File, Line - InsertedLines)
111
112 ## The exception class that used to report error messages when parsing FDF
113 #
114 # Currently the "ToolName" is set to be "FDF Parser".
115 #
116 class Warning (Exception):
117 ## The constructor
118 #
119 # @param self The object pointer
120 # @param Str The message to record
121 # @param File The FDF name
122 # @param Line The Line number that error occurs
123 #
124 def __init__(self, Str, File = None, Line = None):
125
126 FileLineTuple = GetRealFileLine(File, Line)
127 self.FileName = FileLineTuple[0]
128 self.LineNumber = FileLineTuple[1]
129 self.OriginalLineNumber = Line
130 self.Message = Str
131 self.ToolName = 'FdfParser'
132
133 def __str__(self):
134 return self.Message
135
136 ## The MACRO class that used to record macro value data when parsing include file
137 #
138 #
139 class MacroProfile :
140 ## The constructor
141 #
142 # @param self The object pointer
143 # @param FileName The file that to be parsed
144 #
145 def __init__(self, FileName, Line):
146 self.FileName = FileName
147 self.DefinedAtLine = Line
148 self.MacroName = None
149 self.MacroValue = None
150
151 ## The Include file content class that used to record file data when parsing include file
152 #
153 # May raise Exception when opening file.
154 #
155 class IncludeFileProfile :
156 ## The constructor
157 #
158 # @param self The object pointer
159 # @param FileName The file that to be parsed
160 #
161 def __init__(self, FileName):
162 self.FileName = FileName
163 self.FileLinesList = []
164 try:
165 fsock = open(FileName, "rb", 0)
166 try:
167 self.FileLinesList = fsock.readlines()
168 finally:
169 fsock.close()
170
171 except:
172 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)
173
174 self.InsertStartLineNumber = None
175 self.InsertAdjust = 0
176 self.IncludeFileList = []
177 self.Level = 1 # first level include file
178
179 def GetTotalLines(self):
180 TotalLines = self.InsertAdjust + len(self.FileLinesList)
181
182 for Profile in self.IncludeFileList:
183 TotalLines += Profile.GetTotalLines()
184
185 return TotalLines
186
187 def IsLineInFile(self, Line):
188 if Line >= self.InsertStartLineNumber and Line < self.InsertStartLineNumber + self.GetTotalLines():
189 return True
190
191 return False
192
193 def GetLineInFile(self, Line):
194 if not self.IsLineInFile (Line):
195 return (self.FileName, -1)
196
197 InsertedLines = self.InsertStartLineNumber
198
199 for Profile in self.IncludeFileList:
200 if Profile.IsLineInFile(Line):
201 return Profile.GetLineInFile(Line)
202 elif Line >= Profile.InsertStartLineNumber:
203 InsertedLines += Profile.GetTotalLines()
204
205 return (self.FileName, Line - InsertedLines + 1)
206
207
208
209 ## The FDF content class that used to record file data when parsing FDF
210 #
211 # May raise Exception when opening file.
212 #
213 class FileProfile :
214 ## The constructor
215 #
216 # @param self The object pointer
217 # @param FileName The file that to be parsed
218 #
219 def __init__(self, FileName):
220 self.FileLinesList = []
221 try:
222 fsock = open(FileName, "rb", 0)
223 try:
224 self.FileLinesList = fsock.readlines()
225 finally:
226 fsock.close()
227
228 except:
229 EdkLogger.error("FdfParser", FILE_OPEN_FAILURE, ExtraData=FileName)
230
231
232 self.PcdDict = {}
233 self.InfList = []
234 self.InfDict = {'ArchTBD':[]}
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 ## SectionParser() method
1402 #
1403 # Parse the file section info
1404 # Exception will be raised if syntax error found
1405 #
1406 # @param self The object pointer
1407 # @param section The section string
1408
1409 def SectionParser(self, section):
1410 S = section.upper()
1411 if not S.startswith("[DEFINES") and not S.startswith("[FD.") and not S.startswith("[FV.") and not S.startswith("[CAPSULE.") \
1412 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM.") and not S.startswith('[FMPPAYLOAD.'):
1413 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self.FileName, self.CurrentLineNumber)
1414
1415 ## __GetDefines() method
1416 #
1417 # Get Defines section contents and store its data into AllMacrosList
1418 #
1419 # @param self The object pointer
1420 # @retval True Successfully find a Defines
1421 # @retval False Not able to find a Defines
1422 #
1423 def __GetDefines(self):
1424
1425 if not self.__GetNextToken():
1426 return False
1427
1428 S = self.__Token.upper()
1429 if S.startswith("[") and not S.startswith("[DEFINES"):
1430 self.SectionParser(S)
1431 self.__UndoToken()
1432 return False
1433
1434 self.__UndoToken()
1435 if not self.__IsToken("[DEFINES", True):
1436 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1437 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1438 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1439 raise Warning("expected [DEFINES", self.FileName, self.CurrentLineNumber)
1440
1441 if not self.__IsToken( "]"):
1442 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
1443
1444 while self.__GetNextWord():
1445 # handle the SET statement
1446 if self.__Token == 'SET':
1447 self.__UndoToken()
1448 self.__GetSetStatement(None)
1449 continue
1450
1451 Macro = self.__Token
1452
1453 if not self.__IsToken("="):
1454 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1455 if not self.__GetNextToken() or self.__Token.startswith('['):
1456 raise Warning("expected MACRO value", self.FileName, self.CurrentLineNumber)
1457 Value = self.__Token
1458
1459 return False
1460
1461 ## __GetFd() method
1462 #
1463 # Get FD section contents and store its data into FD dictionary of self.Profile
1464 #
1465 # @param self The object pointer
1466 # @retval True Successfully find a FD
1467 # @retval False Not able to find a FD
1468 #
1469 def __GetFd(self):
1470
1471 if not self.__GetNextToken():
1472 return False
1473
1474 S = self.__Token.upper()
1475 if S.startswith("[") and not S.startswith("[FD."):
1476 if not S.startswith("[FV.") and not S.startswith('[FMPPAYLOAD.') and not S.startswith("[CAPSULE.") \
1477 and not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
1478 raise Warning("Unknown section", self.FileName, self.CurrentLineNumber)
1479 self.__UndoToken()
1480 return False
1481
1482 self.__UndoToken()
1483 if not self.__IsToken("[FD.", True):
1484 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1485 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1486 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1487 raise Warning("expected [FD.]", self.FileName, self.CurrentLineNumber)
1488
1489 FdName = self.__GetUiName()
1490 if FdName == "":
1491 if len (self.Profile.FdDict) == 0:
1492 FdName = GenFdsGlobalVariable.PlatformName
1493 if FdName == "" and GlobalData.gActivePlatform:
1494 FdName = GlobalData.gActivePlatform.PlatformName
1495 self.Profile.FdNameNotSet = True
1496 else:
1497 raise Warning("expected FdName in [FD.] section", self.FileName, self.CurrentLineNumber)
1498 self.CurrentFdName = FdName.upper()
1499
1500 if self.CurrentFdName in self.Profile.FdDict:
1501 raise Warning("Unexpected the same FD name", self.FileName, self.CurrentLineNumber)
1502
1503 if not self.__IsToken( "]"):
1504 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
1505
1506 FdObj = Fd.FD()
1507 FdObj.FdUiName = self.CurrentFdName
1508 self.Profile.FdDict[self.CurrentFdName] = FdObj
1509
1510 if len (self.Profile.FdDict) > 1 and self.Profile.FdNameNotSet:
1511 raise Warning("expected all FDs have their name", self.FileName, self.CurrentLineNumber)
1512
1513 Status = self.__GetCreateFile(FdObj)
1514 if not Status:
1515 raise Warning("FD name error", self.FileName, self.CurrentLineNumber)
1516
1517 while self.__GetTokenStatements(FdObj):
1518 pass
1519 for Attr in ("BaseAddress", "Size", "ErasePolarity"):
1520 if getattr(FdObj, Attr) == None:
1521 self.__GetNextToken()
1522 raise Warning("Keyword %s missing" % Attr, self.FileName, self.CurrentLineNumber)
1523
1524 if not FdObj.BlockSizeList:
1525 FdObj.BlockSizeList.append((1, FdObj.Size, None))
1526
1527 self.__GetDefineStatements(FdObj)
1528
1529 self.__GetSetStatements(FdObj)
1530
1531 if not self.__GetRegionLayout(FdObj):
1532 raise Warning("expected region layout", self.FileName, self.CurrentLineNumber)
1533
1534 while self.__GetRegionLayout(FdObj):
1535 pass
1536 return True
1537
1538 ## __GetUiName() method
1539 #
1540 # Return the UI name of a section
1541 #
1542 # @param self The object pointer
1543 # @retval FdName UI name
1544 #
1545 def __GetUiName(self):
1546 Name = ""
1547 if self.__GetNextWord():
1548 Name = self.__Token
1549
1550 return Name
1551
1552 ## __GetCreateFile() method
1553 #
1554 # Return the output file name of object
1555 #
1556 # @param self The object pointer
1557 # @param Obj object whose data will be stored in file
1558 # @retval FdName UI name
1559 #
1560 def __GetCreateFile(self, Obj):
1561
1562 if self.__IsKeyword( "CREATE_FILE"):
1563 if not self.__IsToken( "="):
1564 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1565
1566 if not self.__GetNextToken():
1567 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)
1568
1569 FileName = self.__Token
1570 Obj.CreateFileName = FileName
1571
1572 return True
1573
1574 ## __GetTokenStatements() method
1575 #
1576 # Get token statements
1577 #
1578 # @param self The object pointer
1579 # @param Obj for whom token statement is got
1580 #
1581 def __GetTokenStatements(self, Obj):
1582 if self.__IsKeyword( "BaseAddress"):
1583 if not self.__IsToken( "="):
1584 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1585
1586 if not self.__GetNextHexNumber():
1587 raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber)
1588
1589 Obj.BaseAddress = self.__Token
1590
1591 if self.__IsToken( "|"):
1592 pcdPair = self.__GetNextPcdName()
1593 Obj.BaseAddressPcd = pcdPair
1594 self.Profile.PcdDict[pcdPair] = Obj.BaseAddress
1595 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1596 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
1597 return True
1598
1599 if self.__IsKeyword( "Size"):
1600 if not self.__IsToken( "="):
1601 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1602
1603 if not self.__GetNextHexNumber():
1604 raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber)
1605
1606 Size = self.__Token
1607 if self.__IsToken( "|"):
1608 pcdPair = self.__GetNextPcdName()
1609 Obj.SizePcd = pcdPair
1610 self.Profile.PcdDict[pcdPair] = Size
1611 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1612 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
1613 Obj.Size = long(Size, 0)
1614 return True
1615
1616 if self.__IsKeyword( "ErasePolarity"):
1617 if not self.__IsToken( "="):
1618 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1619
1620 if not self.__GetNextToken():
1621 raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber)
1622
1623 if self.__Token != "1" and self.__Token != "0":
1624 raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)
1625
1626 Obj.ErasePolarity = self.__Token
1627 return True
1628
1629 return self.__GetBlockStatements(Obj)
1630
1631 ## __GetAddressStatements() method
1632 #
1633 # Get address statements
1634 #
1635 # @param self The object pointer
1636 # @param Obj for whom address statement is got
1637 # @retval True Successfully find
1638 # @retval False Not able to find
1639 #
1640 def __GetAddressStatements(self, Obj):
1641
1642 if self.__IsKeyword("BsBaseAddress"):
1643 if not self.__IsToken( "="):
1644 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1645
1646 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1647 raise Warning("expected address", self.FileName, self.CurrentLineNumber)
1648
1649 BsAddress = long(self.__Token, 0)
1650 Obj.BsBaseAddress = BsAddress
1651
1652 if self.__IsKeyword("RtBaseAddress"):
1653 if not self.__IsToken( "="):
1654 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1655
1656 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1657 raise Warning("expected address", self.FileName, self.CurrentLineNumber)
1658
1659 RtAddress = long(self.__Token, 0)
1660 Obj.RtBaseAddress = RtAddress
1661
1662 ## __GetBlockStatements() method
1663 #
1664 # Get block statements
1665 #
1666 # @param self The object pointer
1667 # @param Obj for whom block statement is got
1668 #
1669 def __GetBlockStatements(self, Obj):
1670 IsBlock = False
1671 while self.__GetBlockStatement(Obj):
1672 IsBlock = True
1673
1674 Item = Obj.BlockSizeList[-1]
1675 if Item[0] == None or Item[1] == None:
1676 raise Warning("expected block statement", self.FileName, self.CurrentLineNumber)
1677 return IsBlock
1678
1679 ## __GetBlockStatement() method
1680 #
1681 # Get block statement
1682 #
1683 # @param self The object pointer
1684 # @param Obj for whom block statement is got
1685 # @retval True Successfully find
1686 # @retval False Not able to find
1687 #
1688 def __GetBlockStatement(self, Obj):
1689 if not self.__IsKeyword( "BlockSize"):
1690 return False
1691
1692 if not self.__IsToken( "="):
1693 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1694
1695 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():
1696 raise Warning("expected Hex or Integer block size", self.FileName, self.CurrentLineNumber)
1697
1698 BlockSize = self.__Token
1699 BlockSizePcd = None
1700 if self.__IsToken( "|"):
1701 PcdPair = self.__GetNextPcdName()
1702 BlockSizePcd = PcdPair
1703 self.Profile.PcdDict[PcdPair] = BlockSize
1704 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1705 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
1706 BlockSize = long(BlockSize, 0)
1707
1708 BlockNumber = None
1709 if self.__IsKeyword( "NumBlocks"):
1710 if not self.__IsToken( "="):
1711 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1712
1713 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1714 raise Warning("expected block numbers", self.FileName, self.CurrentLineNumber)
1715
1716 BlockNumber = long(self.__Token, 0)
1717
1718 Obj.BlockSizeList.append((BlockSize, BlockNumber, BlockSizePcd))
1719 return True
1720
1721 ## __GetDefineStatements() method
1722 #
1723 # Get define statements
1724 #
1725 # @param self The object pointer
1726 # @param Obj for whom define statement is got
1727 # @retval True Successfully find
1728 # @retval False Not able to find
1729 #
1730 def __GetDefineStatements(self, Obj):
1731 while self.__GetDefineStatement( Obj):
1732 pass
1733
1734 ## __GetDefineStatement() method
1735 #
1736 # Get define statement
1737 #
1738 # @param self The object pointer
1739 # @param Obj for whom define statement is got
1740 # @retval True Successfully find
1741 # @retval False Not able to find
1742 #
1743 def __GetDefineStatement(self, Obj):
1744 if self.__IsKeyword("DEFINE"):
1745 self.__GetNextToken()
1746 Macro = self.__Token
1747 if not self.__IsToken( "="):
1748 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1749
1750 if not self.__GetNextToken():
1751 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
1752
1753 Value = self.__Token
1754 Macro = '$(' + Macro + ')'
1755 Obj.DefineVarDict[Macro] = Value
1756 return True
1757
1758 return False
1759
1760 ## __GetSetStatements() method
1761 #
1762 # Get set statements
1763 #
1764 # @param self The object pointer
1765 # @param Obj for whom set statement is got
1766 # @retval True Successfully find
1767 # @retval False Not able to find
1768 #
1769 def __GetSetStatements(self, Obj):
1770 while self.__GetSetStatement(Obj):
1771 pass
1772
1773 ## __GetSetStatement() method
1774 #
1775 # Get set statement
1776 #
1777 # @param self The object pointer
1778 # @param Obj for whom set statement is got
1779 # @retval True Successfully find
1780 # @retval False Not able to find
1781 #
1782 def __GetSetStatement(self, Obj):
1783 if self.__IsKeyword("SET"):
1784 PcdPair = self.__GetNextPcdName()
1785
1786 if not self.__IsToken( "="):
1787 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1788
1789 Value = self.__GetExpression()
1790 Value = self.__EvaluateConditional(Value, self.CurrentLineNumber, 'eval', True)
1791
1792 if Obj:
1793 Obj.SetVarDict[PcdPair] = Value
1794 self.Profile.PcdDict[PcdPair] = Value
1795 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1796 self.Profile.PcdFileLineDict[PcdPair] = FileLineTuple
1797 return True
1798
1799 return False
1800
1801 ## __CalcRegionExpr(self)
1802 #
1803 # Calculate expression for offset or size of a region
1804 #
1805 # @return: None if invalid expression
1806 # Calculated number if successfully
1807 #
1808 def __CalcRegionExpr(self):
1809 StartPos = self.GetFileBufferPos()
1810 Expr = ''
1811 PairCount = 0
1812 while not self.__EndOfFile():
1813 CurCh = self.__CurrentChar()
1814 if CurCh == '(':
1815 PairCount += 1
1816 elif CurCh == ')':
1817 PairCount -= 1
1818
1819 if CurCh in '|\r\n' and PairCount == 0:
1820 break
1821 Expr += CurCh
1822 self.__GetOneChar()
1823 try:
1824 return long(
1825 ValueExpression(Expr,
1826 self.__CollectMacroPcd()
1827 )(True),0)
1828 except Exception:
1829 self.SetFileBufferPos(StartPos)
1830 return None
1831
1832 ## __GetRegionLayout() method
1833 #
1834 # Get region layout for FD
1835 #
1836 # @param self The object pointer
1837 # @param Fd for whom region is got
1838 # @retval True Successfully find
1839 # @retval False Not able to find
1840 #
1841 def __GetRegionLayout(self, Fd):
1842 Offset = self.__CalcRegionExpr()
1843 if Offset == None:
1844 return False
1845
1846 RegionObj = Region.Region()
1847 RegionObj.Offset = Offset
1848 Fd.RegionList.append(RegionObj)
1849
1850 if not self.__IsToken( "|"):
1851 raise Warning("expected '|'", self.FileName, self.CurrentLineNumber)
1852
1853 Size = self.__CalcRegionExpr()
1854 if Size == None:
1855 raise Warning("expected Region Size", self.FileName, self.CurrentLineNumber)
1856 RegionObj.Size = Size
1857
1858 if not self.__GetNextWord():
1859 return True
1860
1861 if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE", "INF"):
1862 #
1863 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1864 # Or it might be next region's offset described by an expression which starts with a PCD.
1865 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1866 #
1867 self.__UndoToken()
1868 IsRegionPcd = (RegionSizeGuidPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]) or
1869 RegionOffsetPcdPattern.match(self.__CurrentLine()[self.CurrentOffsetWithinLine:]))
1870 if IsRegionPcd:
1871 RegionObj.PcdOffset = self.__GetNextPcdName()
1872 self.Profile.PcdDict[RegionObj.PcdOffset] = "0x%08X" % (RegionObj.Offset + long(Fd.BaseAddress, 0))
1873 self.__PcdDict['%s.%s' % (RegionObj.PcdOffset[1], RegionObj.PcdOffset[0])] = "0x%x" % RegionObj.Offset
1874 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1875 self.Profile.PcdFileLineDict[RegionObj.PcdOffset] = FileLineTuple
1876 if self.__IsToken( "|"):
1877 RegionObj.PcdSize = self.__GetNextPcdName()
1878 self.Profile.PcdDict[RegionObj.PcdSize] = "0x%08X" % RegionObj.Size
1879 self.__PcdDict['%s.%s' % (RegionObj.PcdSize[1], RegionObj.PcdSize[0])] = "0x%x" % RegionObj.Size
1880 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1881 self.Profile.PcdFileLineDict[RegionObj.PcdSize] = FileLineTuple
1882
1883 if not self.__GetNextWord():
1884 return True
1885
1886 if self.__Token == "SET":
1887 self.__UndoToken()
1888 self.__GetSetStatements( RegionObj)
1889 if not self.__GetNextWord():
1890 return True
1891
1892 elif self.__Token == "FV":
1893 self.__UndoToken()
1894 self.__GetRegionFvType( RegionObj)
1895
1896 elif self.__Token == "CAPSULE":
1897 self.__UndoToken()
1898 self.__GetRegionCapType( RegionObj)
1899
1900 elif self.__Token == "FILE":
1901 self.__UndoToken()
1902 self.__GetRegionFileType(RegionObj)
1903
1904 elif self.__Token == "INF":
1905 self.__UndoToken()
1906 RegionObj.RegionType = "INF"
1907 while self.__IsKeyword("INF"):
1908 self.__UndoToken()
1909 ffsInf = self.__ParseInfStatement()
1910 if not ffsInf:
1911 break
1912 RegionObj.RegionDataList.append(ffsInf)
1913
1914 elif self.__Token == "DATA":
1915 self.__UndoToken()
1916 self.__GetRegionDataType(RegionObj)
1917 else:
1918 self.__UndoToken()
1919 if self.__GetRegionLayout(Fd):
1920 return True
1921 raise Warning("A valid region type was not found. "
1922 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
1923 self.FileName, self.CurrentLineNumber)
1924
1925 return True
1926
1927 ## __GetRegionFvType() method
1928 #
1929 # Get region fv data for region
1930 #
1931 # @param self The object pointer
1932 # @param RegionObj for whom region data is got
1933 #
1934 def __GetRegionFvType(self, RegionObj):
1935
1936 if not self.__IsKeyword( "FV"):
1937 raise Warning("expected Keyword 'FV'", self.FileName, self.CurrentLineNumber)
1938
1939 if not self.__IsToken( "="):
1940 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1941
1942 if not self.__GetNextToken():
1943 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
1944
1945 RegionObj.RegionType = "FV"
1946 RegionObj.RegionDataList.append((self.__Token).upper())
1947
1948 while self.__IsKeyword( "FV"):
1949
1950 if not self.__IsToken( "="):
1951 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1952
1953 if not self.__GetNextToken():
1954 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
1955
1956 RegionObj.RegionDataList.append((self.__Token).upper())
1957
1958 ## __GetRegionCapType() method
1959 #
1960 # Get region capsule data for region
1961 #
1962 # @param self The object pointer
1963 # @param RegionObj for whom region data is got
1964 #
1965 def __GetRegionCapType(self, RegionObj):
1966
1967 if not self.__IsKeyword("CAPSULE"):
1968 raise Warning("expected Keyword 'CAPSULE'", self.FileName, self.CurrentLineNumber)
1969
1970 if not self.__IsToken("="):
1971 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1972
1973 if not self.__GetNextToken():
1974 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)
1975
1976 RegionObj.RegionType = "CAPSULE"
1977 RegionObj.RegionDataList.append(self.__Token)
1978
1979 while self.__IsKeyword("CAPSULE"):
1980
1981 if not self.__IsToken("="):
1982 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1983
1984 if not self.__GetNextToken():
1985 raise Warning("expected CAPSULE name", self.FileName, self.CurrentLineNumber)
1986
1987 RegionObj.RegionDataList.append(self.__Token)
1988
1989 ## __GetRegionFileType() method
1990 #
1991 # Get region file data for region
1992 #
1993 # @param self The object pointer
1994 # @param RegionObj for whom region data is got
1995 #
1996 def __GetRegionFileType(self, RegionObj):
1997
1998 if not self.__IsKeyword( "FILE"):
1999 raise Warning("expected Keyword 'FILE'", self.FileName, self.CurrentLineNumber)
2000
2001 if not self.__IsToken( "="):
2002 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2003
2004 if not self.__GetNextToken():
2005 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
2006
2007 RegionObj.RegionType = "FILE"
2008 RegionObj.RegionDataList.append( self.__Token)
2009
2010 while self.__IsKeyword( "FILE"):
2011
2012 if not self.__IsToken( "="):
2013 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2014
2015 if not self.__GetNextToken():
2016 raise Warning("expected FILE name", self.FileName, self.CurrentLineNumber)
2017
2018 RegionObj.RegionDataList.append(self.__Token)
2019
2020 ## __GetRegionDataType() method
2021 #
2022 # Get region array data for region
2023 #
2024 # @param self The object pointer
2025 # @param RegionObj for whom region data is got
2026 #
2027 def __GetRegionDataType(self, RegionObj):
2028
2029 if not self.__IsKeyword( "DATA"):
2030 raise Warning("expected Region Data type", self.FileName, self.CurrentLineNumber)
2031
2032 if not self.__IsToken( "="):
2033 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2034
2035 if not self.__IsToken( "{"):
2036 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2037
2038 if not self.__GetNextHexNumber():
2039 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)
2040
2041 if len(self.__Token) > 18:
2042 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
2043
2044 # convert hex string value to byte hex string array
2045 AllString = self.__Token
2046 AllStrLen = len (AllString)
2047 DataString = ""
2048 while AllStrLen > 4:
2049 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","
2050 AllStrLen = AllStrLen - 2
2051 DataString = DataString + AllString[:AllStrLen] + ","
2052
2053 # byte value array
2054 if len (self.__Token) <= 4:
2055 while self.__IsToken(","):
2056 if not self.__GetNextHexNumber():
2057 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
2058 if len(self.__Token) > 4:
2059 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
2060 DataString += self.__Token
2061 DataString += ","
2062
2063 if not self.__IsToken( "}"):
2064 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2065
2066 DataString = DataString.rstrip(",")
2067 RegionObj.RegionType = "DATA"
2068 RegionObj.RegionDataList.append( DataString)
2069
2070 while self.__IsKeyword( "DATA"):
2071
2072 if not self.__IsToken( "="):
2073 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2074
2075 if not self.__IsToken( "{"):
2076 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2077
2078 if not self.__GetNextHexNumber():
2079 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)
2080
2081 if len(self.__Token) > 18:
2082 raise Warning("Hex string can't be converted to a valid UINT64 value", self.FileName, self.CurrentLineNumber)
2083
2084 # convert hex string value to byte hex string array
2085 AllString = self.__Token
2086 AllStrLen = len (AllString)
2087 DataString = ""
2088 while AllStrLen > 4:
2089 DataString = DataString + "0x" + AllString[AllStrLen - 2: AllStrLen] + ","
2090 AllStrLen = AllStrLen - 2
2091 DataString = DataString + AllString[:AllStrLen] + ","
2092
2093 # byte value array
2094 if len (self.__Token) <= 4:
2095 while self.__IsToken(","):
2096 if not self.__GetNextHexNumber():
2097 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
2098 if len(self.__Token) > 4:
2099 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
2100 DataString += self.__Token
2101 DataString += ","
2102
2103 if not self.__IsToken( "}"):
2104 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2105
2106 DataString = DataString.rstrip(",")
2107 RegionObj.RegionDataList.append( DataString)
2108
2109 ## __GetFv() method
2110 #
2111 # Get FV section contents and store its data into FV dictionary of self.Profile
2112 #
2113 # @param self The object pointer
2114 # @retval True Successfully find a FV
2115 # @retval False Not able to find a FV
2116 #
2117 def __GetFv(self):
2118 if not self.__GetNextToken():
2119 return False
2120
2121 S = self.__Token.upper()
2122 if S.startswith("[") and not S.startswith("[FV."):
2123 self.SectionParser(S)
2124 self.__UndoToken()
2125 return False
2126
2127 self.__UndoToken()
2128 if not self.__IsToken("[FV.", True):
2129 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
2130 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2131 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2132 raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2133
2134 FvName = self.__GetUiName()
2135 self.CurrentFvName = FvName.upper()
2136
2137 if not self.__IsToken( "]"):
2138 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
2139
2140 FvObj = Fv.FV()
2141 FvObj.UiFvName = self.CurrentFvName
2142 self.Profile.FvDict[self.CurrentFvName] = FvObj
2143
2144 Status = self.__GetCreateFile(FvObj)
2145 if not Status:
2146 raise Warning("FV name error", self.FileName, self.CurrentLineNumber)
2147
2148 self.__GetDefineStatements(FvObj)
2149
2150 self.__GetAddressStatements(FvObj)
2151
2152 FvObj.FvExtEntryTypeValue = []
2153 FvObj.FvExtEntryType = []
2154 FvObj.FvExtEntryData = []
2155 while True:
2156 self.__GetSetStatements(FvObj)
2157
2158 if not (self.__GetBlockStatement(FvObj) or self.__GetFvBaseAddress(FvObj) or
2159 self.__GetFvForceRebase(FvObj) or self.__GetFvAlignment(FvObj) or
2160 self.__GetFvAttributes(FvObj) or self.__GetFvNameGuid(FvObj) or
2161 self.__GetFvExtEntryStatement(FvObj) or self.__GetFvNameString(FvObj)):
2162 break
2163
2164 if FvObj.FvNameString == 'TRUE' and not FvObj.FvNameGuid:
2165 raise Warning("FvNameString found but FvNameGuid was not found", self.FileName, self.CurrentLineNumber)
2166
2167 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
2168 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
2169
2170 while True:
2171 isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
2172 isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
2173 if not isInf and not isFile:
2174 break
2175
2176 return True
2177
2178 ## __GetFvAlignment() method
2179 #
2180 # Get alignment for FV
2181 #
2182 # @param self The object pointer
2183 # @param Obj for whom alignment is got
2184 # @retval True Successfully find a alignment statement
2185 # @retval False Not able to find a alignment statement
2186 #
2187 def __GetFvAlignment(self, Obj):
2188
2189 if not self.__IsKeyword( "FvAlignment"):
2190 return False
2191
2192 if not self.__IsToken( "="):
2193 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2194
2195 if not self.__GetNextToken():
2196 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)
2197
2198 if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2199 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2200 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2201 "1G", "2G"):
2202 raise Warning("Unknown alignment value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2203 Obj.FvAlignment = self.__Token
2204 return True
2205
2206 ## __GetFvBaseAddress() method
2207 #
2208 # Get BaseAddress for FV
2209 #
2210 # @param self The object pointer
2211 # @param Obj for whom FvBaseAddress is got
2212 # @retval True Successfully find a FvBaseAddress statement
2213 # @retval False Not able to find a FvBaseAddress statement
2214 #
2215 def __GetFvBaseAddress(self, Obj):
2216
2217 if not self.__IsKeyword("FvBaseAddress"):
2218 return False
2219
2220 if not self.__IsToken( "="):
2221 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2222
2223 if not self.__GetNextToken():
2224 raise Warning("expected FV base address value", self.FileName, self.CurrentLineNumber)
2225
2226 IsValidBaseAddrValue = re.compile('^0[x|X][0-9a-fA-F]+')
2227
2228 if not IsValidBaseAddrValue.match(self.__Token.upper()):
2229 raise Warning("Unknown FV base address value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2230 Obj.FvBaseAddress = self.__Token
2231 return True
2232
2233 ## __GetFvForceRebase() method
2234 #
2235 # Get FvForceRebase for FV
2236 #
2237 # @param self The object pointer
2238 # @param Obj for whom FvForceRebase is got
2239 # @retval True Successfully find a FvForceRebase statement
2240 # @retval False Not able to find a FvForceRebase statement
2241 #
2242 def __GetFvForceRebase(self, Obj):
2243
2244 if not self.__IsKeyword("FvForceRebase"):
2245 return False
2246
2247 if not self.__IsToken( "="):
2248 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2249
2250 if not self.__GetNextToken():
2251 raise Warning("expected FvForceRebase value", self.FileName, self.CurrentLineNumber)
2252
2253 if self.__Token.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:
2254 raise Warning("Unknown FvForceRebase value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2255
2256 if self.__Token.upper() in ["TRUE", "1", "0X1", "0X01"]:
2257 Obj.FvForceRebase = True
2258 elif self.__Token.upper() in ["FALSE", "0", "0X0", "0X00"]:
2259 Obj.FvForceRebase = False
2260 else:
2261 Obj.FvForceRebase = None
2262
2263 return True
2264
2265
2266 ## __GetFvAttributes() method
2267 #
2268 # Get attributes for FV
2269 #
2270 # @param self The object pointer
2271 # @param Obj for whom attribute is got
2272 # @retval None
2273 #
2274 def __GetFvAttributes(self, FvObj):
2275 IsWordToken = False
2276 while self.__GetNextWord():
2277 IsWordToken = True
2278 name = self.__Token
2279 if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
2280 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2281 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2282 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2283 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2284 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT"):
2285 self.__UndoToken()
2286 return False
2287
2288 if not self.__IsToken( "="):
2289 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2290
2291 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
2292 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
2293
2294 FvObj.FvAttributeDict[name] = self.__Token
2295
2296 return IsWordToken
2297
2298 ## __GetFvNameGuid() method
2299 #
2300 # Get FV GUID for FV
2301 #
2302 # @param self The object pointer
2303 # @param Obj for whom GUID is got
2304 # @retval None
2305 #
2306 def __GetFvNameGuid(self, FvObj):
2307
2308 if not self.__IsKeyword( "FvNameGuid"):
2309 return False
2310
2311 if not self.__IsToken( "="):
2312 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2313
2314 if not self.__GetNextGuid():
2315 raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber)
2316
2317 FvObj.FvNameGuid = self.__Token
2318
2319 return True
2320
2321 def __GetFvNameString(self, FvObj):
2322
2323 if not self.__IsKeyword( "FvNameString"):
2324 return False
2325
2326 if not self.__IsToken( "="):
2327 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2328
2329 if not self.__GetNextToken() or self.__Token not in ('TRUE', 'FALSE'):
2330 raise Warning("expected TRUE or FALSE for FvNameString", self.FileName, self.CurrentLineNumber)
2331
2332 FvObj.FvNameString = self.__Token
2333
2334 return True
2335
2336 def __GetFvExtEntryStatement(self, FvObj):
2337
2338 if not self.__IsKeyword( "FV_EXT_ENTRY"):
2339 return False
2340
2341 if not self.__IsKeyword ("TYPE"):
2342 raise Warning("expected 'TYPE'", self.FileName, self.CurrentLineNumber)
2343
2344 if not self.__IsToken( "="):
2345 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2346
2347 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():
2348 raise Warning("expected Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber)
2349
2350 FvObj.FvExtEntryTypeValue += [self.__Token]
2351
2352 if not self.__IsToken( "{"):
2353 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2354
2355 if not self.__IsKeyword ("FILE") and not self.__IsKeyword ("DATA"):
2356 raise Warning("expected 'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber)
2357
2358 FvObj.FvExtEntryType += [self.__Token]
2359
2360 if self.__Token == 'DATA':
2361
2362 if not self.__IsToken( "="):
2363 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2364
2365 if not self.__IsToken( "{"):
2366 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2367
2368 if not self.__GetNextHexNumber():
2369 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)
2370
2371 if len(self.__Token) > 4:
2372 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
2373
2374 DataString = self.__Token
2375 DataString += ","
2376
2377 while self.__IsToken(","):
2378 if not self.__GetNextHexNumber():
2379 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
2380 if len(self.__Token) > 4:
2381 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
2382 DataString += self.__Token
2383 DataString += ","
2384
2385 if not self.__IsToken( "}"):
2386 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2387
2388 if not self.__IsToken( "}"):
2389 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2390
2391 DataString = DataString.rstrip(",")
2392 FvObj.FvExtEntryData += [DataString]
2393
2394 if self.__Token == 'FILE':
2395
2396 if not self.__IsToken( "="):
2397 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2398
2399 if not self.__GetNextToken():
2400 raise Warning("expected FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber)
2401
2402 FvObj.FvExtEntryData += [self.__Token]
2403
2404 if not self.__IsToken( "}"):
2405 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2406
2407 return True
2408
2409 ## __GetAprioriSection() method
2410 #
2411 # Get token statements
2412 #
2413 # @param self The object pointer
2414 # @param FvObj for whom apriori is got
2415 # @param MacroDict dictionary used to replace macro
2416 # @retval True Successfully find apriori statement
2417 # @retval False Not able to find apriori statement
2418 #
2419 def __GetAprioriSection(self, FvObj, MacroDict = {}):
2420
2421 if not self.__IsKeyword( "APRIORI"):
2422 return False
2423
2424 if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"):
2425 raise Warning("expected Apriori file type", self.FileName, self.CurrentLineNumber)
2426 AprType = self.__Token
2427
2428 if not self.__IsToken( "{"):
2429 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2430
2431 AprSectionObj = AprioriSection.AprioriSection()
2432 AprSectionObj.AprioriType = AprType
2433
2434 self.__GetDefineStatements(AprSectionObj)
2435 MacroDict.update(AprSectionObj.DefineVarDict)
2436
2437 while True:
2438 IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict)
2439 IsFile = self.__GetFileStatement( AprSectionObj)
2440 if not IsInf and not IsFile:
2441 break
2442
2443 if not self.__IsToken( "}"):
2444 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2445
2446 FvObj.AprioriSectionList.append(AprSectionObj)
2447 return True
2448
2449 def __ParseInfStatement(self):
2450 if not self.__IsKeyword("INF"):
2451 return None
2452
2453 ffsInf = FfsInfStatement.FfsInfStatement()
2454 self.__GetInfOptions(ffsInf)
2455
2456 if not self.__GetNextToken():
2457 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)
2458 ffsInf.InfFileName = self.__Token
2459
2460 ffsInf.CurrentLineNum = self.CurrentLineNumber
2461 ffsInf.CurrentLineContent = self.__CurrentLine()
2462
2463 #Replace $(SAPCE) with real space
2464 ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')
2465
2466 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:
2467 #do case sensitive check for file path
2468 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
2469 if ErrorCode != 0:
2470 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
2471
2472 if not ffsInf.InfFileName in self.Profile.InfList:
2473 self.Profile.InfList.append(ffsInf.InfFileName)
2474 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
2475 self.Profile.InfFileLineList.append(FileLineTuple)
2476 if ffsInf.UseArch:
2477 if ffsInf.UseArch not in self.Profile.InfDict:
2478 self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]
2479 else:
2480 self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)
2481 else:
2482 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)
2483
2484 if self.__IsToken('|'):
2485 if self.__IsKeyword('RELOCS_STRIPPED'):
2486 ffsInf.KeepReloc = False
2487 elif self.__IsKeyword('RELOCS_RETAINED'):
2488 ffsInf.KeepReloc = True
2489 else:
2490 raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2491 return ffsInf
2492
2493 ## __GetInfStatement() method
2494 #
2495 # Get INF statements
2496 #
2497 # @param self The object pointer
2498 # @param Obj for whom inf statement is got
2499 # @param MacroDict dictionary used to replace macro
2500 # @retval True Successfully find inf statement
2501 # @retval False Not able to find inf statement
2502 #
2503 def __GetInfStatement(self, Obj, ForCapsule=False, MacroDict={}):
2504 ffsInf = self.__ParseInfStatement()
2505 if not ffsInf:
2506 return False
2507
2508 if ForCapsule:
2509 capsuleFfs = CapsuleData.CapsuleFfs()
2510 capsuleFfs.Ffs = ffsInf
2511 Obj.CapsuleDataList.append(capsuleFfs)
2512 else:
2513 Obj.FfsList.append(ffsInf)
2514 return True
2515
2516 ## __GetInfOptions() method
2517 #
2518 # Get options for INF
2519 #
2520 # @param self The object pointer
2521 # @param FfsInfObj for whom option is got
2522 #
2523 def __GetInfOptions(self, FfsInfObj):
2524 if self.__IsKeyword("FILE_GUID"):
2525 if not self.__IsToken("="):
2526 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2527 if not self.__GetNextGuid():
2528 raise Warning("expected GUID value", self.FileName, self.CurrentLineNumber)
2529 FfsInfObj.OverrideGuid = self.__Token
2530
2531 if self.__IsKeyword( "RuleOverride"):
2532 if not self.__IsToken( "="):
2533 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2534 if not self.__GetNextToken():
2535 raise Warning("expected Rule name", self.FileName, self.CurrentLineNumber)
2536 FfsInfObj.Rule = self.__Token
2537
2538 if self.__IsKeyword( "VERSION"):
2539 if not self.__IsToken( "="):
2540 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2541 if not self.__GetNextToken():
2542 raise Warning("expected Version", self.FileName, self.CurrentLineNumber)
2543
2544 if self.__GetStringData():
2545 FfsInfObj.Version = self.__Token
2546
2547 if self.__IsKeyword( "UI"):
2548 if not self.__IsToken( "="):
2549 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2550 if not self.__GetNextToken():
2551 raise Warning("expected UI name", self.FileName, self.CurrentLineNumber)
2552
2553 if self.__GetStringData():
2554 FfsInfObj.Ui = self.__Token
2555
2556 if self.__IsKeyword( "USE"):
2557 if not self.__IsToken( "="):
2558 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2559 if not self.__GetNextToken():
2560 raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber)
2561 FfsInfObj.UseArch = self.__Token
2562
2563
2564 if self.__GetNextToken():
2565 p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2566 if p.match(self.__Token) and p.match(self.__Token).span()[1] == len(self.__Token):
2567 FfsInfObj.KeyStringList.append(self.__Token)
2568 if not self.__IsToken(","):
2569 return
2570 else:
2571 self.__UndoToken()
2572 return
2573
2574 while self.__GetNextToken():
2575 if not p.match(self.__Token):
2576 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
2577 FfsInfObj.KeyStringList.append(self.__Token)
2578
2579 if not self.__IsToken(","):
2580 break
2581
2582 ## __GetFileStatement() method
2583 #
2584 # Get FILE statements
2585 #
2586 # @param self The object pointer
2587 # @param Obj for whom FILE statement is got
2588 # @param MacroDict dictionary used to replace macro
2589 # @retval True Successfully find FILE statement
2590 # @retval False Not able to find FILE statement
2591 #
2592 def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}):
2593
2594 if not self.__IsKeyword( "FILE"):
2595 return False
2596
2597 if not self.__GetNextWord():
2598 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)
2599
2600 if ForCapsule and self.__Token == 'DATA':
2601 self.__UndoToken()
2602 self.__UndoToken()
2603 return False
2604
2605 FfsFileObj = FfsFileStatement.FileStatement()
2606 FfsFileObj.FvFileType = self.__Token
2607
2608 if not self.__IsToken( "="):
2609 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2610
2611 if not self.__GetNextGuid():
2612 if not self.__GetNextWord():
2613 raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber)
2614 if self.__Token == 'PCD':
2615 if not self.__IsToken( "("):
2616 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
2617 PcdPair = self.__GetNextPcdName()
2618 if not self.__IsToken( ")"):
2619 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
2620 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
2621
2622 FfsFileObj.NameGuid = self.__Token
2623
2624 self.__GetFilePart( FfsFileObj, MacroDict.copy())
2625
2626 if ForCapsule:
2627 capsuleFfs = CapsuleData.CapsuleFfs()
2628 capsuleFfs.Ffs = FfsFileObj
2629 Obj.CapsuleDataList.append(capsuleFfs)
2630 else:
2631 Obj.FfsList.append(FfsFileObj)
2632
2633 return True
2634
2635 ## __FileCouldHaveRelocFlag() method
2636 #
2637 # Check whether reloc strip flag can be set for a file type.
2638 #
2639 # @param self The object pointer
2640 # @param FileType The file type to check with
2641 # @retval True This type could have relocation strip flag
2642 # @retval False No way to have it
2643 #
2644
2645 def __FileCouldHaveRelocFlag (self, FileType):
2646 if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):
2647 return True
2648 else:
2649 return False
2650
2651 ## __SectionCouldHaveRelocFlag() method
2652 #
2653 # Check whether reloc strip flag can be set for a section type.
2654 #
2655 # @param self The object pointer
2656 # @param SectionType The section type to check with
2657 # @retval True This type could have relocation strip flag
2658 # @retval False No way to have it
2659 #
2660
2661 def __SectionCouldHaveRelocFlag (self, SectionType):
2662 if SectionType in ('TE', 'PE32'):
2663 return True
2664 else:
2665 return False
2666
2667 ## __GetFilePart() method
2668 #
2669 # Get components for FILE statement
2670 #
2671 # @param self The object pointer
2672 # @param FfsFileObj for whom component is got
2673 # @param MacroDict dictionary used to replace macro
2674 #
2675 def __GetFilePart(self, FfsFileObj, MacroDict = {}):
2676
2677 self.__GetFileOpts( FfsFileObj)
2678
2679 if not self.__IsToken("{"):
2680 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2681 if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType):
2682 if self.__Token == 'RELOCS_STRIPPED':
2683 FfsFileObj.KeepReloc = False
2684 else:
2685 FfsFileObj.KeepReloc = True
2686 else:
2687 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
2688
2689 if not self.__IsToken("{"):
2690 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2691
2692 if not self.__GetNextToken():
2693 raise Warning("expected File name or section data", self.FileName, self.CurrentLineNumber)
2694
2695 if self.__Token == "FV":
2696 if not self.__IsToken( "="):
2697 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2698 if not self.__GetNextToken():
2699 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
2700 FfsFileObj.FvName = self.__Token
2701
2702 elif self.__Token == "FD":
2703 if not self.__IsToken( "="):
2704 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2705 if not self.__GetNextToken():
2706 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)
2707 FfsFileObj.FdName = self.__Token
2708
2709 elif self.__Token in ("DEFINE", "APRIORI", "SECTION"):
2710 self.__UndoToken()
2711 self.__GetSectionData( FfsFileObj, MacroDict)
2712
2713 elif hasattr(FfsFileObj, 'FvFileType') and FfsFileObj.FvFileType == 'RAW':
2714 self.__UndoToken()
2715 self.__GetRAWData(FfsFileObj, MacroDict)
2716
2717 else:
2718 FfsFileObj.CurrentLineNum = self.CurrentLineNumber
2719 FfsFileObj.CurrentLineContent = self.__CurrentLine()
2720 FfsFileObj.FileName = self.__Token.replace('$(SPACE)', ' ')
2721 self.__VerifyFile(FfsFileObj.FileName)
2722
2723 if not self.__IsToken( "}"):
2724 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2725
2726 ## __GetRAWData() method
2727 #
2728 # Get RAW data for FILE statement
2729 #
2730 # @param self The object pointer
2731 # @param FfsFileObj for whom section is got
2732 # @param MacroDict dictionary used to replace macro
2733 #
2734 def __GetRAWData(self, FfsFileObj, MacroDict = {}):
2735 FfsFileObj.FileName = []
2736 FfsFileObj.SubAlignment = []
2737 while True:
2738 AlignValue = None
2739 if self.__GetAlignment():
2740 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2741 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2742 AlignValue = self.__Token
2743 if not self.__GetNextToken():
2744 raise Warning("expected Filename value", self.FileName, self.CurrentLineNumber)
2745
2746 FileName = self.__Token.replace('$(SPACE)', ' ')
2747 if FileName == '}':
2748 self.__UndoToken()
2749 raise Warning("expected Filename value", self.FileName, self.CurrentLineNumber)
2750
2751 self.__VerifyFile(FileName)
2752 File = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir)
2753 FfsFileObj.FileName.append(File.Path)
2754 FfsFileObj.SubAlignment.append(AlignValue)
2755
2756 if self.__IsToken( "}"):
2757 self.__UndoToken()
2758 break
2759
2760 if len(FfsFileObj.SubAlignment) == 1:
2761 FfsFileObj.SubAlignment = FfsFileObj.SubAlignment[0]
2762 if len(FfsFileObj.FileName) == 1:
2763 FfsFileObj.FileName = FfsFileObj.FileName[0]
2764
2765 ## __GetFileOpts() method
2766 #
2767 # Get options for FILE statement
2768 #
2769 # @param self The object pointer
2770 # @param FfsFileObj for whom options is got
2771 #
2772 def __GetFileOpts(self, FfsFileObj):
2773
2774 if self.__GetNextToken():
2775 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2776 if Pattern.match(self.__Token):
2777 FfsFileObj.KeyStringList.append(self.__Token)
2778 if self.__IsToken(","):
2779 while self.__GetNextToken():
2780 if not Pattern.match(self.__Token):
2781 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
2782 FfsFileObj.KeyStringList.append(self.__Token)
2783
2784 if not self.__IsToken(","):
2785 break
2786
2787 else:
2788 self.__UndoToken()
2789
2790 if self.__IsKeyword( "FIXED", True):
2791 FfsFileObj.Fixed = True
2792
2793 if self.__IsKeyword( "CHECKSUM", True):
2794 FfsFileObj.CheckSum = True
2795
2796 if self.__GetAlignment():
2797 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2798 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2799 #For FFS, Auto is default option same to ""
2800 if not self.__Token == "Auto":
2801 FfsFileObj.Alignment = self.__Token
2802
2803 ## __GetAlignment() method
2804 #
2805 # Return the alignment value
2806 #
2807 # @param self The object pointer
2808 # @retval True Successfully find alignment
2809 # @retval False Not able to find alignment
2810 #
2811 def __GetAlignment(self):
2812 if self.__IsKeyword( "Align", True):
2813 if not self.__IsToken( "="):
2814 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2815
2816 if not self.__GetNextToken():
2817 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)
2818 return True
2819
2820 return False
2821
2822 ## __GetFilePart() method
2823 #
2824 # Get section data for FILE statement
2825 #
2826 # @param self The object pointer
2827 # @param FfsFileObj for whom section is got
2828 # @param MacroDict dictionary used to replace macro
2829 #
2830 def __GetSectionData(self, FfsFileObj, MacroDict = {}):
2831 Dict = {}
2832 Dict.update(MacroDict)
2833
2834 self.__GetDefineStatements(FfsFileObj)
2835
2836 Dict.update(FfsFileObj.DefineVarDict)
2837 self.__GetAprioriSection(FfsFileObj, Dict.copy())
2838 self.__GetAprioriSection(FfsFileObj, Dict.copy())
2839
2840 while True:
2841 IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict)
2842 IsEncapSection = self.__GetEncapsulationSec(FfsFileObj)
2843 if not IsLeafSection and not IsEncapSection:
2844 break
2845
2846 ## __GetLeafSection() method
2847 #
2848 # Get leaf section for Obj
2849 #
2850 # @param self The object pointer
2851 # @param Obj for whom leaf section is got
2852 # @param MacroDict dictionary used to replace macro
2853 # @retval True Successfully find section statement
2854 # @retval False Not able to find section statement
2855 #
2856 def __GetLeafSection(self, Obj, MacroDict = {}):
2857
2858 OldPos = self.GetFileBufferPos()
2859
2860 if not self.__IsKeyword( "SECTION"):
2861 if len(Obj.SectionList) == 0:
2862 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)
2863 else:
2864 return False
2865
2866 AlignValue = None
2867 if self.__GetAlignment():
2868 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2869 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2870 AlignValue = self.__Token
2871
2872 BuildNum = None
2873 if self.__IsKeyword( "BUILD_NUM"):
2874 if not self.__IsToken( "="):
2875 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2876
2877 if not self.__GetNextToken():
2878 raise Warning("expected Build number value", self.FileName, self.CurrentLineNumber)
2879
2880 BuildNum = self.__Token
2881
2882 if self.__IsKeyword( "VERSION"):
2883 if AlignValue == 'Auto':
2884 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2885 if not self.__IsToken( "="):
2886 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2887 if not self.__GetNextToken():
2888 raise Warning("expected version", self.FileName, self.CurrentLineNumber)
2889 VerSectionObj = VerSection.VerSection()
2890 VerSectionObj.Alignment = AlignValue
2891 VerSectionObj.BuildNum = BuildNum
2892 if self.__GetStringData():
2893 VerSectionObj.StringData = self.__Token
2894 else:
2895 VerSectionObj.FileName = self.__Token
2896 Obj.SectionList.append(VerSectionObj)
2897
2898 elif self.__IsKeyword( "UI"):
2899 if AlignValue == 'Auto':
2900 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2901 if not self.__IsToken( "="):
2902 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2903 if not self.__GetNextToken():
2904 raise Warning("expected UI", self.FileName, self.CurrentLineNumber)
2905 UiSectionObj = UiSection.UiSection()
2906 UiSectionObj.Alignment = AlignValue
2907 if self.__GetStringData():
2908 UiSectionObj.StringData = self.__Token
2909 else:
2910 UiSectionObj.FileName = self.__Token
2911 Obj.SectionList.append(UiSectionObj)
2912
2913 elif self.__IsKeyword( "FV_IMAGE"):
2914 if AlignValue == 'Auto':
2915 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2916 if not self.__IsToken( "="):
2917 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2918 if not self.__GetNextToken():
2919 raise Warning("expected FV name or FV file path", self.FileName, self.CurrentLineNumber)
2920
2921 FvName = self.__Token
2922 FvObj = None
2923
2924 if self.__IsToken( "{"):
2925 FvObj = Fv.FV()
2926 FvObj.UiFvName = FvName.upper()
2927 self.__GetDefineStatements(FvObj)
2928 MacroDict.update(FvObj.DefineVarDict)
2929 self.__GetBlockStatement(FvObj)
2930 self.__GetSetStatements(FvObj)
2931 self.__GetFvAlignment(FvObj)
2932 self.__GetFvAttributes(FvObj)
2933 self.__GetAprioriSection(FvObj, MacroDict.copy())
2934 self.__GetAprioriSection(FvObj, MacroDict.copy())
2935
2936 while True:
2937 IsInf = self.__GetInfStatement(FvObj, MacroDict.copy())
2938 IsFile = self.__GetFileStatement(FvObj, MacroDict.copy())
2939 if not IsInf and not IsFile:
2940 break
2941
2942 if not self.__IsToken( "}"):
2943 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2944
2945 FvImageSectionObj = FvImageSection.FvImageSection()
2946 FvImageSectionObj.Alignment = AlignValue
2947 if FvObj != None:
2948 FvImageSectionObj.Fv = FvObj
2949 FvImageSectionObj.FvName = None
2950 else:
2951 FvImageSectionObj.FvName = FvName.upper()
2952 FvImageSectionObj.FvFileName = FvName
2953
2954 Obj.SectionList.append(FvImageSectionObj)
2955
2956 elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"):
2957 if AlignValue == 'Auto':
2958 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2959 DepexSectionObj = DepexSection.DepexSection()
2960 DepexSectionObj.Alignment = AlignValue
2961 DepexSectionObj.DepexType = self.__Token
2962
2963 if not self.__IsToken( "="):
2964 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2965 if not self.__IsToken( "{"):
2966 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2967 if not self.__SkipToToken( "}"):
2968 raise Warning("expected Depex expression ending '}'", self.FileName, self.CurrentLineNumber)
2969
2970 DepexSectionObj.Expression = self.__SkippedChars.rstrip('}')
2971 Obj.SectionList.append(DepexSectionObj)
2972
2973 else:
2974 if not self.__GetNextWord():
2975 raise Warning("expected section type", self.FileName, self.CurrentLineNumber)
2976
2977 # Encapsulation section appear, UndoToken and return
2978 if self.__Token == "COMPRESS" or self.__Token == "GUIDED":
2979 self.SetFileBufferPos(OldPos)
2980 return False
2981
2982 if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
2983 "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):
2984 raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2985 if AlignValue == 'Auto'and (not self.__Token == 'PE32') and (not self.__Token == 'TE'):
2986 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2987
2988 # DataSection
2989 DataSectionObj = DataSection.DataSection()
2990 DataSectionObj.Alignment = AlignValue
2991 DataSectionObj.SecType = self.__Token
2992
2993 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2994 if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType):
2995 if self.__Token == 'RELOCS_STRIPPED':
2996 DataSectionObj.KeepReloc = False
2997 else:
2998 DataSectionObj.KeepReloc = True
2999 else:
3000 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)
3001
3002 if self.__IsToken("="):
3003 if not self.__GetNextToken():
3004 raise Warning("expected section file path", self.FileName, self.CurrentLineNumber)
3005 DataSectionObj.SectFileName = self.__Token
3006 self.__VerifyFile(DataSectionObj.SectFileName)
3007 else:
3008 if not self.__GetCglSection(DataSectionObj):
3009 return False
3010
3011 Obj.SectionList.append(DataSectionObj)
3012
3013 return True
3014
3015 ## __VerifyFile
3016 #
3017 # Check if file exists or not:
3018 # If current phase if GenFds, the file must exist;
3019 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
3020 # @param FileName: File path to be verified.
3021 #
3022 def __VerifyFile(self, FileName):
3023 if FileName.replace('$(WORKSPACE)', '').find('$') != -1:
3024 return
3025 if not GlobalData.gAutoGenPhase or not self.__GetMacroValue("OUTPUT_DIRECTORY") in FileName:
3026 ErrorCode, ErrorInfo = PathClass(NormPath(FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
3027 if ErrorCode != 0:
3028 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
3029
3030 ## __GetCglSection() method
3031 #
3032 # Get compressed or GUIDed section for Obj
3033 #
3034 # @param self The object pointer
3035 # @param Obj for whom leaf section is got
3036 # @param AlignValue alignment value for complex section
3037 # @retval True Successfully find section statement
3038 # @retval False Not able to find section statement
3039 #
3040 def __GetCglSection(self, Obj, AlignValue = None):
3041
3042 if self.__IsKeyword( "COMPRESS"):
3043 type = "PI_STD"
3044 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
3045 type = self.__Token
3046
3047 if not self.__IsToken("{"):
3048 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
3049
3050 CompressSectionObj = CompressSection.CompressSection()
3051 CompressSectionObj.Alignment = AlignValue
3052 CompressSectionObj.CompType = type
3053 # Recursive sections...
3054 while True:
3055 IsLeafSection = self.__GetLeafSection(CompressSectionObj)
3056 IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj)
3057 if not IsLeafSection and not IsEncapSection:
3058 break
3059
3060
3061 if not self.__IsToken( "}"):
3062 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
3063 Obj.SectionList.append(CompressSectionObj)
3064
3065 # else:
3066 # raise Warning("Compress type not known")
3067
3068 return True
3069
3070 elif self.__IsKeyword( "GUIDED"):
3071 GuidValue = None
3072 if self.__GetNextGuid():
3073 GuidValue = self.__Token
3074
3075 AttribDict = self.__GetGuidAttrib()
3076 if not self.__IsToken("{"):
3077 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
3078 GuidSectionObj = GuidSection.GuidSection()
3079 GuidSectionObj.Alignment = AlignValue
3080 GuidSectionObj.NameGuid = GuidValue
3081 GuidSectionObj.SectionType = "GUIDED"
3082 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
3083 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
3084 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]
3085 # Recursive sections...
3086 while True:
3087 IsLeafSection = self.__GetLeafSection(GuidSectionObj)
3088 IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj)
3089 if not IsLeafSection and not IsEncapSection:
3090 break
3091
3092 if not self.__IsToken( "}"):
3093 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
3094 Obj.SectionList.append(GuidSectionObj)
3095
3096 return True
3097
3098 return False
3099
3100 ## __GetGuidAttri() method
3101 #
3102 # Get attributes for GUID section
3103 #
3104 # @param self The object pointer
3105 # @retval AttribDict Dictionary of key-value pair of section attributes
3106 #
3107 def __GetGuidAttrib(self):
3108
3109 AttribDict = {}
3110 AttribDict["PROCESSING_REQUIRED"] = "NONE"
3111 AttribDict["AUTH_STATUS_VALID"] = "NONE"
3112 AttribDict["EXTRA_HEADER_SIZE"] = -1
3113 while self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID") \
3114 or self.__IsKeyword("EXTRA_HEADER_SIZE"):
3115 AttribKey = self.__Token
3116
3117 if not self.__IsToken("="):
3118 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3119
3120 if not self.__GetNextToken():
3121 raise Warning("expected TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber)
3122 elif AttribKey == "EXTRA_HEADER_SIZE":
3123 Base = 10
3124 if self.__Token[0:2].upper() == "0X":
3125 Base = 16
3126 try:
3127 AttribDict[AttribKey] = int(self.__Token, Base)
3128 continue
3129 except ValueError:
3130 raise Warning("expected Number", self.FileName, self.CurrentLineNumber)
3131 elif self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
3132 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
3133 AttribDict[AttribKey] = self.__Token
3134
3135 return AttribDict
3136
3137 ## __GetEncapsulationSec() method
3138 #
3139 # Get encapsulation section for FILE
3140 #
3141 # @param self The object pointer
3142 # @param FfsFile for whom section is got
3143 # @retval True Successfully find section statement
3144 # @retval False Not able to find section statement
3145 #
3146 def __GetEncapsulationSec(self, FfsFileObj):
3147
3148 OldPos = self.GetFileBufferPos()
3149 if not self.__IsKeyword( "SECTION"):
3150 if len(FfsFileObj.SectionList) == 0:
3151 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)
3152 else:
3153 return False
3154
3155 AlignValue = None
3156 if self.__GetAlignment():
3157 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3158 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3159 AlignValue = self.__Token
3160
3161 if not self.__GetCglSection(FfsFileObj, AlignValue):
3162 self.SetFileBufferPos(OldPos)
3163 return False
3164 else:
3165 return True
3166
3167 def __GetFmp(self):
3168 if not self.__GetNextToken():
3169 return False
3170 S = self.__Token.upper()
3171 if S.startswith("[") and not S.startswith("[FMPPAYLOAD."):
3172 self.SectionParser(S)
3173 self.__UndoToken()
3174 return False
3175
3176 self.__UndoToken()
3177 self.__SkipToToken("[FMPPAYLOAD.", True)
3178 FmpUiName = self.__GetUiName().upper()
3179 if FmpUiName in self.Profile.FmpPayloadDict:
3180 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName, self.FileName, self.CurrentLineNumber)
3181
3182 FmpData = CapsuleData.CapsulePayload()
3183 FmpData.UiName = FmpUiName
3184
3185 if not self.__IsToken( "]"):
3186 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
3187
3188 if not self.__GetNextToken():
3189 raise Warning("The FMP payload section is empty!", self.FileName, self.CurrentLineNumber)
3190 FmpKeyList = ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE']
3191 while self.__Token in FmpKeyList:
3192 Name = self.__Token
3193 FmpKeyList.remove(Name)
3194 if not self.__IsToken("="):
3195 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3196 if Name == 'IMAGE_TYPE_ID':
3197 if not self.__GetNextGuid():
3198 raise Warning("expected GUID value for IMAGE_TYPE_ID", self.FileName, self.CurrentLineNumber)
3199 FmpData.ImageTypeId = self.__Token
3200 else:
3201 if not self.__GetNextToken():
3202 raise Warning("expected value of %s" % Name, self.FileName, self.CurrentLineNumber)
3203 Value = self.__Token
3204 if Name == 'IMAGE_HEADER_INIT_VERSION':
3205 FmpData.Version = Value
3206 elif Name == 'IMAGE_INDEX':
3207 FmpData.ImageIndex = Value
3208 elif Name == 'HARDWARE_INSTANCE':
3209 FmpData.HardwareInstance = Value
3210 if not self.__GetNextToken():
3211 break
3212 else:
3213 self.__UndoToken()
3214
3215 if FmpKeyList:
3216 raise Warning("Missing keywords %s in FMP payload section" % ', '.join(FmpKeyList), self.FileName, self.CurrentLineNumber)
3217 ImageFile = self.__ParseRawFileStatement()
3218 if not ImageFile:
3219 raise Warning("Missing image file in FMP payload section", self.FileName, self.CurrentLineNumber)
3220 FmpData.ImageFile = ImageFile
3221 VendorCodeFile = self.__ParseRawFileStatement()
3222 if VendorCodeFile:
3223 FmpData.VendorCodeFile = VendorCodeFile
3224 self.Profile.FmpPayloadDict[FmpUiName] = FmpData
3225 return True
3226
3227 ## __GetCapsule() method
3228 #
3229 # Get capsule section contents and store its data into capsule list of self.Profile
3230 #
3231 # @param self The object pointer
3232 # @retval True Successfully find a capsule
3233 # @retval False Not able to find a capsule
3234 #
3235 def __GetCapsule(self):
3236
3237 if not self.__GetNextToken():
3238 return False
3239
3240 S = self.__Token.upper()
3241 if S.startswith("[") and not S.startswith("[CAPSULE."):
3242 self.SectionParser(S)
3243 self.__UndoToken()
3244 return False
3245
3246 self.__UndoToken()
3247 if not self.__IsToken("[CAPSULE.", True):
3248 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
3249 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3250 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3251 raise Warning("expected [Capsule.]", self.FileName, self.CurrentLineNumber)
3252
3253 CapsuleObj = Capsule.Capsule()
3254
3255 CapsuleName = self.__GetUiName()
3256 if not CapsuleName:
3257 raise Warning("expected capsule name", self.FileName, self.CurrentLineNumber)
3258
3259 CapsuleObj.UiCapsuleName = CapsuleName.upper()
3260
3261 if not self.__IsToken( "]"):
3262 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
3263
3264 if self.__IsKeyword("CREATE_FILE"):
3265 if not self.__IsToken( "="):
3266 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3267
3268 if not self.__GetNextToken():
3269 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)
3270
3271 CapsuleObj.CreateFile = self.__Token
3272
3273 self.__GetCapsuleStatements(CapsuleObj)
3274 self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj
3275 return True
3276
3277 ## __GetCapsuleStatements() method
3278 #
3279 # Get statements for capsule
3280 #
3281 # @param self The object pointer
3282 # @param Obj for whom statements are got
3283 #
3284 def __GetCapsuleStatements(self, Obj):
3285 self.__GetCapsuleTokens(Obj)
3286 self.__GetDefineStatements(Obj)
3287 self.__GetSetStatements(Obj)
3288 self.__GetCapsuleData(Obj)
3289
3290 ## __GetCapsuleTokens() method
3291 #
3292 # Get token statements for capsule
3293 #
3294 # @param self The object pointer
3295 # @param Obj for whom token statements are got
3296 #
3297 def __GetCapsuleTokens(self, Obj):
3298 if not self.__GetNextToken():
3299 return False
3300 while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"):
3301 Name = self.__Token.strip()
3302 if not self.__IsToken("="):
3303 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3304 if not self.__GetNextToken():
3305 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
3306 if Name == 'CAPSULE_FLAGS':
3307 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
3308 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
3309 Value = self.__Token.strip()
3310 while self.__IsToken(","):
3311 Value += ','
3312 if not self.__GetNextToken():
3313 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
3314 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
3315 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
3316 Value += self.__Token.strip()
3317 elif Name == 'OEM_CAPSULE_FLAGS':
3318 Value = self.__Token.strip()
3319 if not Value.upper().startswith('0X'):
3320 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
3321 try:
3322 Value = int(Value, 0)
3323 except ValueError:
3324 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
3325 if not 0x0000 <= Value <= 0xFFFF:
3326 raise Warning("expected hex value between 0x0000 and 0xFFFF", self.FileName, self.CurrentLineNumber)
3327 Value = self.__Token.strip()
3328 else:
3329 Value = self.__Token.strip()
3330 Obj.TokensDict[Name] = Value
3331 if not self.__GetNextToken():
3332 return False
3333 self.__UndoToken()
3334
3335 ## __GetCapsuleData() method
3336 #
3337 # Get capsule data for capsule
3338 #
3339 # @param self The object pointer
3340 # @param Obj for whom capsule data are got
3341 #
3342 def __GetCapsuleData(self, Obj):
3343
3344 while True:
3345 IsInf = self.__GetInfStatement(Obj, True)
3346 IsFile = self.__GetFileStatement(Obj, True)
3347 IsFv = self.__GetFvStatement(Obj)
3348 IsFd = self.__GetFdStatement(Obj)
3349 IsAnyFile = self.__GetAnyFileStatement(Obj)
3350 IsAfile = self.__GetAfileStatement(Obj)
3351 IsFmp = self.__GetFmpStatement(Obj)
3352 if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile or IsAfile or IsFmp):
3353 break
3354
3355 ## __GetFvStatement() method
3356 #
3357 # Get FV for capsule
3358 #
3359 # @param self The object pointer
3360 # @param CapsuleObj for whom FV is got
3361 # @retval True Successfully find a FV statement
3362 # @retval False Not able to find a FV statement
3363 #
3364 def __GetFvStatement(self, CapsuleObj):
3365
3366 if not self.__IsKeyword("FV"):
3367 return False
3368
3369 if not self.__IsToken("="):
3370 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3371
3372 if not self.__GetNextToken():
3373 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
3374
3375 if self.__Token.upper() not in self.Profile.FvDict.keys():
3376 raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)
3377
3378 CapsuleFv = CapsuleData.CapsuleFv()
3379 CapsuleFv.FvName = self.__Token
3380 CapsuleObj.CapsuleDataList.append(CapsuleFv)
3381 return True
3382
3383 ## __GetFdStatement() method
3384 #
3385 # Get FD for capsule
3386 #
3387 # @param self The object pointer
3388 # @param CapsuleObj for whom FD is got
3389 # @retval True Successfully find a FD statement
3390 # @retval False Not able to find a FD statement
3391 #
3392 def __GetFdStatement(self, CapsuleObj):
3393
3394 if not self.__IsKeyword("FD"):
3395 return False
3396
3397 if not self.__IsToken("="):
3398 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3399
3400 if not self.__GetNextToken():
3401 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)
3402
3403 if self.__Token.upper() not in self.Profile.FdDict.keys():
3404 raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)
3405
3406 CapsuleFd = CapsuleData.CapsuleFd()
3407 CapsuleFd.FdName = self.__Token
3408 CapsuleObj.CapsuleDataList.append(CapsuleFd)
3409 return True
3410
3411 def __GetFmpStatement(self, CapsuleObj):
3412 if not self.__IsKeyword("FMP_PAYLOAD"):
3413 if not self.__IsKeyword("FMP"):
3414 return False
3415
3416 if not self.__IsKeyword("PAYLOAD"):
3417 self.__UndoToken()
3418 return False
3419
3420 if not self.__IsToken("="):
3421 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3422
3423 if not self.__GetNextToken():
3424 raise Warning("expected payload name after FMP_PAYLOAD =", self.FileName, self.CurrentLineNumber)
3425 Payload = self.__Token.upper()
3426 if Payload not in self.Profile.FmpPayloadDict:
3427 raise Warning("This FMP Payload does not exist: %s" % self.__Token, self.FileName, self.CurrentLineNumber)
3428 CapsuleObj.FmpPayloadList.append(self.Profile.FmpPayloadDict[Payload])
3429 return True
3430
3431 def __ParseRawFileStatement(self):
3432 if not self.__IsKeyword("FILE"):
3433 return None
3434
3435 if not self.__IsKeyword("DATA"):
3436 self.__UndoToken()
3437 return None
3438
3439 if not self.__IsToken("="):
3440 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3441
3442 if not self.__GetNextToken():
3443 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
3444
3445 AnyFileName = self.__Token
3446 self.__VerifyFile(AnyFileName)
3447
3448 return AnyFileName
3449
3450 ## __GetAnyFileStatement() method
3451 #
3452 # Get AnyFile for capsule
3453 #
3454 # @param self The object pointer
3455 # @param CapsuleObj for whom AnyFile is got
3456 # @retval True Successfully find a Anyfile statement
3457 # @retval False Not able to find a AnyFile statement
3458 #
3459 def __GetAnyFileStatement(self, CapsuleObj):
3460 AnyFileName = self.__ParseRawFileStatement()
3461 if not AnyFileName:
3462 return False
3463
3464 CapsuleAnyFile = CapsuleData.CapsuleAnyFile()
3465 CapsuleAnyFile.FileName = AnyFileName
3466 CapsuleObj.CapsuleDataList.append(CapsuleAnyFile)
3467 return True
3468
3469 ## __GetAfileStatement() method
3470 #
3471 # Get Afile for capsule
3472 #
3473 # @param self The object pointer
3474 # @param CapsuleObj for whom Afile is got
3475 # @retval True Successfully find a Afile statement
3476 # @retval False Not able to find a Afile statement
3477 #
3478 def __GetAfileStatement(self, CapsuleObj):
3479
3480 if not self.__IsKeyword("APPEND"):
3481 return False
3482
3483 if not self.__IsToken("="):
3484 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3485
3486 if not self.__GetNextToken():
3487 raise Warning("expected Afile name", self.FileName, self.CurrentLineNumber)
3488
3489 AfileName = self.__Token
3490 AfileBaseName = os.path.basename(AfileName)
3491
3492 if os.path.splitext(AfileBaseName)[1] not in [".bin",".BIN",".Bin",".dat",".DAT",".Dat",".data",".DATA",".Data"]:
3493 raise Warning('invalid binary file type, should be one of "bin","BIN","Bin","dat","DAT","Dat","data","DATA","Data"', \
3494 self.FileName, self.CurrentLineNumber)
3495
3496 if not os.path.isabs(AfileName):
3497 AfileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AfileName)
3498 self.__VerifyFile(AfileName)
3499 else:
3500 if not os.path.exists(AfileName):
3501 raise Warning('%s does not exist' % AfileName, self.FileName, self.CurrentLineNumber)
3502 else:
3503 pass
3504
3505 CapsuleAfile = CapsuleData.CapsuleAfile()
3506 CapsuleAfile.FileName = AfileName
3507 CapsuleObj.CapsuleDataList.append(CapsuleAfile)
3508 return True
3509
3510 ## __GetRule() method
3511 #
3512 # Get Rule section contents and store its data into rule list of self.Profile
3513 #
3514 # @param self The object pointer
3515 # @retval True Successfully find a Rule
3516 # @retval False Not able to find a Rule
3517 #
3518 def __GetRule(self):
3519
3520 if not self.__GetNextToken():
3521 return False
3522
3523 S = self.__Token.upper()
3524 if S.startswith("[") and not S.startswith("[RULE."):
3525 self.SectionParser(S)
3526 self.__UndoToken()
3527 return False
3528 self.__UndoToken()
3529 if not self.__IsToken("[Rule.", True):
3530 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
3531 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3532 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3533 raise Warning("expected [Rule.]", self.FileName, self.CurrentLineNumber)
3534
3535 if not self.__SkipToToken("."):
3536 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
3537
3538 Arch = self.__SkippedChars.rstrip(".")
3539 if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "AARCH64", "COMMON"):
3540 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
3541
3542 ModuleType = self.__GetModuleType()
3543
3544 TemplateName = ""
3545 if self.__IsToken("."):
3546 if not self.__GetNextWord():
3547 raise Warning("expected template name", self.FileName, self.CurrentLineNumber)
3548 TemplateName = self.__Token
3549
3550 if not self.__IsToken( "]"):
3551 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
3552
3553 RuleObj = self.__GetRuleFileStatements()
3554 RuleObj.Arch = Arch.upper()
3555 RuleObj.ModuleType = ModuleType
3556 RuleObj.TemplateName = TemplateName
3557 if TemplateName == '' :
3558 self.Profile.RuleDict['RULE' + \
3559 '.' + \
3560 Arch.upper() + \
3561 '.' + \
3562 ModuleType.upper() ] = RuleObj
3563 else :
3564 self.Profile.RuleDict['RULE' + \
3565 '.' + \
3566 Arch.upper() + \
3567 '.' + \
3568 ModuleType.upper() + \
3569 '.' + \
3570 TemplateName.upper() ] = RuleObj
3571 # self.Profile.RuleList.append(rule)
3572 return True
3573
3574 ## __GetModuleType() method
3575 #
3576 # Return the module type
3577 #
3578 # @param self The object pointer
3579 # @retval string module type
3580 #
3581 def __GetModuleType(self):
3582
3583 if not self.__GetNextWord():
3584 raise Warning("expected Module type", self.FileName, self.CurrentLineNumber)
3585 if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \
3586 "DXE_DRIVER", "DXE_SAL_DRIVER", \
3587 "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \
3588 "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \
3589 "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \
3590 "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE"):
3591 raise Warning("Unknown Module type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3592 return self.__Token
3593
3594 ## __GetFileExtension() method
3595 #
3596 # Return the file extension
3597 #
3598 # @param self The object pointer
3599 # @retval string file name extension
3600 #
3601 def __GetFileExtension(self):
3602 if not self.__IsToken("."):
3603 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
3604
3605 Ext = ""
3606 if self.__GetNextToken():
3607 Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)')
3608 if Pattern.match(self.__Token):
3609 Ext = self.__Token
3610 return '.' + Ext
3611 else:
3612 raise Warning("Unknown file extension '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3613
3614 else:
3615 raise Warning("expected file extension", self.FileName, self.CurrentLineNumber)
3616
3617 ## __GetRuleFileStatement() method
3618 #
3619 # Get rule contents
3620 #
3621 # @param self The object pointer
3622 # @retval Rule Rule object
3623 #
3624 def __GetRuleFileStatements(self):
3625
3626 if not self.__IsKeyword("FILE"):
3627 raise Warning("expected FILE", self.FileName, self.CurrentLineNumber)
3628
3629 if not self.__GetNextWord():
3630 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)
3631
3632 Type = self.__Token.strip().upper()
3633 if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\
3634 "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE"):
3635 raise Warning("Unknown FV type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3636
3637 if not self.__IsToken("="):
3638 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3639
3640 if not self.__IsKeyword("$(NAMED_GUID)"):
3641 if not self.__GetNextWord():
3642 raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber)
3643 if self.__Token == 'PCD':
3644 if not self.__IsToken( "("):
3645 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
3646 PcdPair = self.__GetNextPcdName()
3647 if not self.__IsToken( ")"):
3648 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
3649 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
3650
3651 NameGuid = self.__Token
3652
3653 KeepReloc = None
3654 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
3655 if self.__FileCouldHaveRelocFlag(Type):
3656 if self.__Token == 'RELOCS_STRIPPED':
3657 KeepReloc = False
3658 else:
3659 KeepReloc = True
3660 else:
3661 raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3662
3663 KeyStringList = []
3664 if self.__GetNextToken():
3665 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
3666 if Pattern.match(self.__Token):
3667 KeyStringList.append(self.__Token)
3668 if self.__IsToken(","):
3669 while self.__GetNextToken():
3670 if not Pattern.match(self.__Token):
3671 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
3672 KeyStringList.append(self.__Token)
3673
3674 if not self.__IsToken(","):
3675 break
3676
3677 else:
3678 self.__UndoToken()
3679
3680
3681 Fixed = False
3682 if self.__IsKeyword("Fixed", True):
3683 Fixed = True
3684
3685 CheckSum = False
3686 if self.__IsKeyword("CheckSum", True):
3687 CheckSum = True
3688
3689 AlignValue = ""
3690 if self.__GetAlignment():
3691 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3692 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3693 #For FFS, Auto is default option same to ""
3694 if not self.__Token == "Auto":
3695 AlignValue = self.__Token
3696
3697 if self.__IsToken("{"):
3698 # Complex file rule expected
3699 Rule = RuleComplexFile.RuleComplexFile()
3700 Rule.FvFileType = Type
3701 Rule.NameGuid = NameGuid
3702 Rule.Alignment = AlignValue
3703 Rule.CheckSum = CheckSum
3704 Rule.Fixed = Fixed
3705 Rule.KeyStringList = KeyStringList
3706 if KeepReloc != None:
3707 Rule.KeepReloc = KeepReloc
3708
3709 while True:
3710 IsEncapsulate = self.__GetRuleEncapsulationSection(Rule)
3711 IsLeaf = self.__GetEfiSection(Rule)
3712 if not IsEncapsulate and not IsLeaf:
3713 break
3714
3715 if not self.__IsToken("}"):
3716 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
3717
3718 return Rule
3719
3720 else:
3721 # Simple file rule expected
3722 if not self.__GetNextWord():
3723 raise Warning("expected leaf section type", self.FileName, self.CurrentLineNumber)
3724
3725 SectionName = self.__Token
3726
3727 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3728 "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"):
3729 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)
3730
3731
3732 if self.__IsKeyword("Fixed", True):
3733 Fixed = True
3734
3735 if self.__IsKeyword("CheckSum", True):
3736 CheckSum = True
3737
3738 SectAlignment = ""
3739 if self.__GetAlignment():
3740 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3741 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3742 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
3743 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
3744 SectAlignment = self.__Token
3745
3746 Ext = None
3747 if self.__IsToken('|'):
3748 Ext = self.__GetFileExtension()
3749 elif not self.__GetNextToken():
3750 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
3751
3752 Rule = RuleSimpleFile.RuleSimpleFile()
3753 Rule.SectionType = SectionName
3754 Rule.FvFileType = Type
3755 Rule.NameGuid = NameGuid
3756 Rule.Alignment = AlignValue
3757 Rule.SectAlignment = SectAlignment
3758 Rule.CheckSum = CheckSum
3759 Rule.Fixed = Fixed
3760 Rule.KeyStringList = KeyStringList
3761 if KeepReloc != None:
3762 Rule.KeepReloc = KeepReloc
3763 Rule.FileExtension = Ext
3764 Rule.FileName = self.__Token
3765 return Rule
3766
3767 ## __GetEfiSection() method
3768 #
3769 # Get section list for Rule
3770 #
3771 # @param self The object pointer
3772 # @param Obj for whom section is got
3773 # @retval True Successfully find section statement
3774 # @retval False Not able to find section statement
3775 #
3776 def __GetEfiSection(self, Obj):
3777
3778 OldPos = self.GetFileBufferPos()
3779 if not self.__GetNextWord():
3780 return False
3781 SectionName = self.__Token
3782
3783 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3784 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3785 self.__UndoToken()
3786 return False
3787
3788 if SectionName == "FV_IMAGE":
3789 FvImageSectionObj = FvImageSection.FvImageSection()
3790 if self.__IsKeyword("FV_IMAGE"):
3791 pass
3792 if self.__IsToken( "{"):
3793 FvObj = Fv.FV()
3794 self.__GetDefineStatements(FvObj)
3795 self.__GetBlockStatement(FvObj)
3796 self.__GetSetStatements(FvObj)
3797 self.__GetFvAlignment(FvObj)
3798 self.__GetFvAttributes(FvObj)
3799 self.__GetAprioriSection(FvObj)
3800 self.__GetAprioriSection(FvObj)
3801
3802 while True:
3803 IsInf = self.__GetInfStatement(FvObj)
3804 IsFile = self.__GetFileStatement(FvObj)
3805 if not IsInf and not IsFile:
3806 break
3807
3808 if not self.__IsToken( "}"):
3809 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
3810 FvImageSectionObj.Fv = FvObj
3811 FvImageSectionObj.FvName = None
3812
3813 else:
3814 if not self.__IsKeyword("FV"):
3815 raise Warning("expected 'FV'", self.FileName, self.CurrentLineNumber)
3816 FvImageSectionObj.FvFileType = self.__Token
3817
3818 if self.__GetAlignment():
3819 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3820 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3821 FvImageSectionObj.Alignment = self.__Token
3822
3823 if self.__IsToken('|'):
3824 FvImageSectionObj.FvFileExtension = self.__GetFileExtension()
3825 elif self.__GetNextToken():
3826 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3827 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3828 FvImageSectionObj.FvFileName = self.__Token
3829 else:
3830 self.__UndoToken()
3831 else:
3832 raise Warning("expected FV file name", self.FileName, self.CurrentLineNumber)
3833
3834 Obj.SectionList.append(FvImageSectionObj)
3835 return True
3836
3837 EfiSectionObj = EfiSection.EfiSection()
3838 EfiSectionObj.SectionType = SectionName
3839
3840 if not self.__GetNextToken():
3841 raise Warning("expected file type", self.FileName, self.CurrentLineNumber)
3842
3843 if self.__Token == "STRING":
3844 if not self.__RuleSectionCouldHaveString(EfiSectionObj.SectionType):
3845 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3846
3847 if not self.__IsToken('='):
3848 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3849
3850 if not self.__GetNextToken():
3851 raise Warning("expected Quoted String", self.FileName, self.CurrentLineNumber)
3852
3853 if self.__GetStringData():
3854 EfiSectionObj.StringData = self.__Token
3855
3856 if self.__IsKeyword("BUILD_NUM"):
3857 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
3858 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3859
3860 if not self.__IsToken("="):
3861 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3862 if not self.__GetNextToken():
3863 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)
3864 EfiSectionObj.BuildNum = self.__Token
3865
3866 else:
3867 EfiSectionObj.FileType = self.__Token
3868 self.__CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)
3869
3870 if self.__IsKeyword("Optional"):
3871 if not self.__RuleSectionCouldBeOptional(EfiSectionObj.SectionType):
3872 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3873 EfiSectionObj.Optional = True
3874
3875 if self.__IsKeyword("BUILD_NUM"):
3876 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
3877 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3878
3879 if not self.__IsToken("="):
3880 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3881 if not self.__GetNextToken():
3882 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)
3883 EfiSectionObj.BuildNum = self.__Token
3884
3885 if self.__GetAlignment():
3886 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3887 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3888 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
3889 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
3890 EfiSectionObj.Alignment = self.__Token
3891
3892 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
3893 if self.__SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):
3894 if self.__Token == 'RELOCS_STRIPPED':
3895 EfiSectionObj.KeepReloc = False
3896 else:
3897 EfiSectionObj.KeepReloc = True
3898 if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc:
3899 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
3900 else:
3901 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
3902
3903
3904 if self.__IsToken('|'):
3905 EfiSectionObj.FileExtension = self.__GetFileExtension()
3906 elif self.__GetNextToken():
3907 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3908 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3909
3910 if self.__Token.startswith('PCD'):
3911 self.__UndoToken()
3912 self.__GetNextWord()
3913
3914 if self.__Token == 'PCD':
3915 if not self.__IsToken( "("):
3916 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
3917 PcdPair = self.__GetNextPcdName()
3918 if not self.__IsToken( ")"):
3919 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
3920 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
3921
3922 EfiSectionObj.FileName = self.__Token
3923
3924 else:
3925 self.__UndoToken()
3926 else:
3927 raise Warning("expected section file name", self.FileName, self.CurrentLineNumber)
3928
3929 Obj.SectionList.append(EfiSectionObj)
3930 return True
3931
3932 ## __RuleSectionCouldBeOptional() method
3933 #
3934 # Get whether a section could be optional
3935 #
3936 # @param self The object pointer
3937 # @param SectionType The section type to check
3938 # @retval True section could be optional
3939 # @retval False section never optional
3940 #
3941 def __RuleSectionCouldBeOptional(self, SectionType):
3942 if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"):
3943 return True
3944 else:
3945 return False
3946
3947 ## __RuleSectionCouldHaveBuildNum() method
3948 #
3949 # Get whether a section could have build number information
3950 #
3951 # @param self The object pointer
3952 # @param SectionType The section type to check
3953 # @retval True section could have build number information
3954 # @retval False section never have build number information
3955 #
3956 def __RuleSectionCouldHaveBuildNum(self, SectionType):
3957 if SectionType in ("VERSION"):
3958 return True
3959 else:
3960 return False
3961
3962 ## __RuleSectionCouldHaveString() method
3963 #
3964 # Get whether a section could have string
3965 #
3966 # @param self The object pointer
3967 # @param SectionType The section type to check
3968 # @retval True section could have string
3969 # @retval False section never have string
3970 #
3971 def __RuleSectionCouldHaveString(self, SectionType):
3972 if SectionType in ("UI", "VERSION"):
3973 return True
3974 else:
3975 return False
3976
3977 ## __CheckRuleSectionFileType() method
3978 #
3979 # Get whether a section matches a file type
3980 #
3981 # @param self The object pointer
3982 # @param SectionType The section type to check
3983 # @param FileType The file type to check
3984 #
3985 def __CheckRuleSectionFileType(self, SectionType, FileType):
3986 if SectionType == "COMPAT16":
3987 if FileType not in ("COMPAT16", "SEC_COMPAT16"):
3988 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3989 elif SectionType == "PE32":
3990 if FileType not in ("PE32", "SEC_PE32"):
3991 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3992 elif SectionType == "PIC":
3993 if FileType not in ("PIC", "PIC"):
3994 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3995 elif SectionType == "TE":
3996 if FileType not in ("TE", "SEC_TE"):
3997 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3998 elif SectionType == "RAW":
3999 if FileType not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"):
4000 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
4001 elif SectionType == "DXE_DEPEX" or SectionType == "SMM_DEPEX":
4002 if FileType not in ("DXE_DEPEX", "SEC_DXE_DEPEX", "SMM_DEPEX"):
4003 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
4004 elif SectionType == "UI":
4005 if FileType not in ("UI", "SEC_UI"):
4006 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
4007 elif SectionType == "VERSION":
4008 if FileType not in ("VERSION", "SEC_VERSION"):
4009 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
4010 elif SectionType == "PEI_DEPEX":
4011 if FileType not in ("PEI_DEPEX", "SEC_PEI_DEPEX"):
4012 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
4013 elif SectionType == "GUID":
4014 if FileType not in ("PE32", "SEC_GUID"):
4015 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
4016
4017 ## __GetRuleEncapsulationSection() method
4018 #
4019 # Get encapsulation section for Rule
4020 #
4021 # @param self The object pointer
4022 # @param Rule for whom section is got
4023 # @retval True Successfully find section statement
4024 # @retval False Not able to find section statement
4025 #
4026 def __GetRuleEncapsulationSection(self, Rule):
4027
4028 if self.__IsKeyword( "COMPRESS"):
4029 Type = "PI_STD"
4030 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
4031 Type = self.__Token
4032
4033 if not self.__IsToken("{"):
4034 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
4035
4036 CompressSectionObj = CompressSection.CompressSection()
4037
4038 CompressSectionObj.CompType = Type
4039 # Recursive sections...
4040 while True:
4041 IsEncapsulate = self.__GetRuleEncapsulationSection(CompressSectionObj)
4042 IsLeaf = self.__GetEfiSection(CompressSectionObj)
4043 if not IsEncapsulate and not IsLeaf:
4044 break
4045
4046 if not self.__IsToken( "}"):
4047 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
4048 Rule.SectionList.append(CompressSectionObj)
4049
4050 return True
4051
4052 elif self.__IsKeyword( "GUIDED"):
4053 GuidValue = None
4054 if self.__GetNextGuid():
4055 GuidValue = self.__Token
4056
4057 if self.__IsKeyword( "$(NAMED_GUID)"):
4058 GuidValue = self.__Token
4059
4060 AttribDict = self.__GetGuidAttrib()
4061
4062 if not self.__IsToken("{"):
4063 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
4064 GuidSectionObj = GuidSection.GuidSection()
4065 GuidSectionObj.NameGuid = GuidValue
4066 GuidSectionObj.SectionType = "GUIDED"
4067 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
4068 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
4069 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]
4070
4071 # Efi sections...
4072 while True:
4073 IsEncapsulate = self.__GetRuleEncapsulationSection(GuidSectionObj)
4074 IsLeaf = self.__GetEfiSection(GuidSectionObj)
4075 if not IsEncapsulate and not IsLeaf:
4076 break
4077
4078 if not self.__IsToken( "}"):
4079 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
4080 Rule.SectionList.append(GuidSectionObj)
4081
4082 return True
4083
4084 return False
4085
4086 ## __GetVtf() method
4087 #
4088 # Get VTF section contents and store its data into VTF list of self.Profile
4089 #
4090 # @param self The object pointer
4091 # @retval True Successfully find a VTF
4092 # @retval False Not able to find a VTF
4093 #
4094 def __GetVtf(self):
4095
4096 if not self.__GetNextToken():
4097 return False
4098
4099 S = self.__Token.upper()
4100 if S.startswith("[") and not S.startswith("[VTF."):
4101 self.SectionParser(S)
4102 self.__UndoToken()
4103 return False
4104
4105 self.__UndoToken()
4106 if not self.__IsToken("[VTF.", True):
4107 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
4108 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
4109 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
4110 raise Warning("expected [VTF.]", self.FileName, self.CurrentLineNumber)
4111
4112 if not self.__SkipToToken("."):
4113 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
4114
4115 Arch = self.__SkippedChars.rstrip(".").upper()
4116 if Arch not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
4117 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
4118
4119 if not self.__GetNextWord():
4120 raise Warning("expected VTF name", self.FileName, self.CurrentLineNumber)
4121 Name = self.__Token.upper()
4122
4123 VtfObj = Vtf.Vtf()
4124 VtfObj.UiName = Name
4125 VtfObj.KeyArch = Arch
4126
4127 if self.__IsToken(","):
4128 if not self.__GetNextWord():
4129 raise Warning("expected Arch list", self.FileName, self.CurrentLineNumber)
4130 if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
4131 raise Warning("Unknown Arch '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
4132 VtfObj.ArchList = self.__Token.upper()
4133
4134 if not self.__IsToken( "]"):
4135 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
4136
4137 if self.__IsKeyword("IA32_RST_BIN"):
4138 if not self.__IsToken("="):
4139 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4140
4141 if not self.__GetNextToken():
4142 raise Warning("expected Reset file", self.FileName, self.CurrentLineNumber)
4143
4144 VtfObj.ResetBin = self.__Token
4145 if VtfObj.ResetBin.replace('$(WORKSPACE)', '').find('$') == -1:
4146 #check for file path
4147 ErrorCode, ErrorInfo = PathClass(NormPath(VtfObj.ResetBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()
4148 if ErrorCode != 0:
4149 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
4150
4151 while self.__GetComponentStatement(VtfObj):
4152 pass
4153
4154 self.Profile.VtfList.append(VtfObj)
4155 return True
4156
4157 ## __GetComponentStatement() method
4158 #
4159 # Get components in VTF
4160 #
4161 # @param self The object pointer
4162 # @param VtfObj for whom component is got
4163 # @retval True Successfully find a component
4164 # @retval False Not able to find a component
4165 #
4166 def __GetComponentStatement(self, VtfObj):
4167
4168 if not self.__IsKeyword("COMP_NAME"):
4169 return False
4170
4171 if not self.__IsToken("="):
4172 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4173
4174 if not self.__GetNextWord():
4175 raise Warning("expected Component Name", self.FileName, self.CurrentLineNumber)
4176
4177 CompStatementObj = ComponentStatement.ComponentStatement()
4178 CompStatementObj.CompName = self.__Token
4179
4180 if not self.__IsKeyword("COMP_LOC"):
4181 raise Warning("expected COMP_LOC", self.FileName, self.CurrentLineNumber)
4182
4183 if not self.__IsToken("="):
4184 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4185
4186 CompStatementObj.CompLoc = ""
4187 if self.__GetNextWord():
4188 CompStatementObj.CompLoc = self.__Token
4189 if self.__IsToken('|'):
4190 if not self.__GetNextWord():
4191 raise Warning("Expected Region Name", self.FileName, self.CurrentLineNumber)
4192
4193 if self.__Token not in ("F", "N", "S"): #, "H", "L", "PH", "PL"): not support
4194 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
4195
4196 CompStatementObj.FilePos = self.__Token
4197 else:
4198 self.CurrentLineNumber += 1
4199 self.CurrentOffsetWithinLine = 0
4200
4201 if not self.__IsKeyword("COMP_TYPE"):
4202 raise Warning("expected COMP_TYPE", self.FileName, self.CurrentLineNumber)
4203
4204 if not self.__IsToken("="):
4205 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4206
4207 if not self.__GetNextToken():
4208 raise Warning("expected Component type", self.FileName, self.CurrentLineNumber)
4209 if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"):
4210 if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \
4211 not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]):
4212 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
4213 CompStatementObj.CompType = self.__Token
4214
4215 if not self.__IsKeyword("COMP_VER"):
4216 raise Warning("expected COMP_VER", self.FileName, self.CurrentLineNumber)
4217
4218 if not self.__IsToken("="):
4219 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4220
4221 if not self.__GetNextToken():
4222 raise Warning("expected Component version", self.FileName, self.CurrentLineNumber)
4223
4224 Pattern = re.compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', re.DOTALL)
4225 if Pattern.match(self.__Token) == None:
4226 raise Warning("Unknown version format '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
4227 CompStatementObj.CompVer = self.__Token
4228
4229 if not self.__IsKeyword("COMP_CS"):
4230 raise Warning("expected COMP_CS", self.FileName, self.CurrentLineNumber)
4231
4232 if not self.__IsToken("="):
4233 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4234
4235 if not self.__GetNextToken():
4236 raise Warning("expected Component CS", self.FileName, self.CurrentLineNumber)
4237 if self.__Token not in ("1", "0"):
4238 raise Warning("Unknown Component CS '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
4239 CompStatementObj.CompCs = self.__Token
4240
4241
4242 if not self.__IsKeyword("COMP_BIN"):
4243 raise Warning("expected COMP_BIN", self.FileName, self.CurrentLineNumber)
4244
4245 if not self.__IsToken("="):
4246 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4247
4248 if not self.__GetNextToken():
4249 raise Warning("expected Component file", self.FileName, self.CurrentLineNumber)
4250
4251 CompStatementObj.CompBin = self.__Token
4252 if CompStatementObj.CompBin != '-' and CompStatementObj.CompBin.replace('$(WORKSPACE)', '').find('$') == -1:
4253 #check for file path
4254 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()
4255 if ErrorCode != 0:
4256 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
4257
4258 if not self.__IsKeyword("COMP_SYM"):
4259 raise Warning("expected COMP_SYM", self.FileName, self.CurrentLineNumber)
4260
4261 if not self.__IsToken("="):
4262 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4263
4264 if not self.__GetNextToken():
4265 raise Warning("expected Component symbol file", self.FileName, self.CurrentLineNumber)
4266
4267 CompStatementObj.CompSym = self.__Token
4268 if CompStatementObj.CompSym != '-' and CompStatementObj.CompSym.replace('$(WORKSPACE)', '').find('$') == -1:
4269 #check for file path
4270 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompSym), GenFdsGlobalVariable.WorkSpaceDir).Validate()
4271 if ErrorCode != 0:
4272 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
4273
4274 if not self.__IsKeyword("COMP_SIZE"):
4275 raise Warning("expected COMP_SIZE", self.FileName, self.CurrentLineNumber)
4276
4277 if not self.__IsToken("="):
4278 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4279
4280 if self.__IsToken("-"):
4281 CompStatementObj.CompSize = self.__Token
4282 elif self.__GetNextDecimalNumber():
4283 CompStatementObj.CompSize = self.__Token
4284 elif self.__GetNextHexNumber():
4285 CompStatementObj.CompSize = self.__Token
4286 else:
4287 raise Warning("Unknown size '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
4288
4289 VtfObj.ComponentStatementList.append(CompStatementObj)
4290 return True
4291
4292 ## __GetOptionRom() method
4293 #
4294 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
4295 #
4296 # @param self The object pointer
4297 # @retval True Successfully find a OptionROM
4298 # @retval False Not able to find a OptionROM
4299 #
4300 def __GetOptionRom(self):
4301
4302 if not self.__GetNextToken():
4303 return False
4304
4305 S = self.__Token.upper()
4306 if S.startswith("[") and not S.startswith("[OPTIONROM."):
4307 self.SectionParser(S)
4308 self.__UndoToken()
4309 return False
4310
4311 self.__UndoToken()
4312 if not self.__IsToken("[OptionRom.", True):
4313 raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
4314
4315 OptRomName = self.__GetUiName()
4316
4317 if not self.__IsToken( "]"):
4318 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
4319
4320 OptRomObj = OptionRom.OPTIONROM()
4321 OptRomObj.DriverName = OptRomName
4322 self.Profile.OptRomDict[OptRomName] = OptRomObj
4323
4324 while True:
4325 isInf = self.__GetOptRomInfStatement(OptRomObj)
4326 isFile = self.__GetOptRomFileStatement(OptRomObj)
4327 if not isInf and not isFile:
4328 break
4329
4330 return True
4331
4332 ## __GetOptRomInfStatement() method
4333 #
4334 # Get INF statements
4335 #
4336 # @param self The object pointer
4337 # @param Obj for whom inf statement is got
4338 # @retval True Successfully find inf statement
4339 # @retval False Not able to find inf statement
4340 #
4341 def __GetOptRomInfStatement(self, Obj):
4342
4343 if not self.__IsKeyword( "INF"):
4344 return False
4345
4346 ffsInf = OptRomInfStatement.OptRomInfStatement()
4347 self.__GetInfOptions( ffsInf)
4348
4349 if not self.__GetNextToken():
4350 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)
4351 ffsInf.InfFileName = self.__Token
4352 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:
4353 #check for file path
4354 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
4355 if ErrorCode != 0:
4356 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
4357
4358 if not ffsInf.InfFileName in self.Profile.InfList:
4359 self.Profile.InfList.append(ffsInf.InfFileName)
4360 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
4361 self.Profile.InfFileLineList.append(FileLineTuple)
4362 if ffsInf.UseArch:
4363 if ffsInf.UseArch not in self.Profile.InfDict:
4364 self.Profile.InfDict[ffsInf.UseArch] = [ffsInf.InfFileName]
4365 else:
4366 self.Profile.InfDict[ffsInf.UseArch].append(ffsInf.InfFileName)
4367 else:
4368 self.Profile.InfDict['ArchTBD'].append(ffsInf.InfFileName)
4369
4370
4371 self.__GetOptRomOverrides (ffsInf)
4372
4373 Obj.FfsList.append(ffsInf)
4374 return True
4375
4376 ## __GetOptRomOverrides() method
4377 #
4378 # Get overrides for OptROM INF & FILE
4379 #
4380 # @param self The object pointer
4381 # @param FfsInfObj for whom overrides is got
4382 #
4383 def __GetOptRomOverrides(self, Obj):
4384 if self.__IsToken('{'):
4385 Overrides = OptionRom.OverrideAttribs()
4386 while True:
4387 if self.__IsKeyword( "PCI_VENDOR_ID"):
4388 if not self.__IsToken( "="):
4389 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4390 if not self.__GetNextHexNumber():
4391 raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber)
4392 Overrides.PciVendorId = self.__Token
4393 continue
4394
4395 if self.__IsKeyword( "PCI_CLASS_CODE"):
4396 if not self.__IsToken( "="):
4397 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4398 if not self.__GetNextHexNumber():
4399 raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber)
4400 Overrides.PciClassCode = self.__Token
4401 continue
4402
4403 if self.__IsKeyword( "PCI_DEVICE_ID"):
4404 if not self.__IsToken( "="):
4405 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4406 if not self.__GetNextHexNumber():
4407 raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber)
4408
4409 Overrides.PciDeviceId = self.__Token
4410 continue
4411
4412 if self.__IsKeyword( "PCI_REVISION"):
4413 if not self.__IsToken( "="):
4414 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4415 if not self.__GetNextHexNumber():
4416 raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber)
4417 Overrides.PciRevision = self.__Token
4418 continue
4419
4420 if self.__IsKeyword( "PCI_COMPRESS"):
4421 if not self.__IsToken( "="):
4422 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4423 if not self.__GetNextToken():
4424 raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)
4425 Overrides.NeedCompress = self.__Token.upper() == 'TRUE'
4426 continue
4427
4428 if self.__IsToken( "}"):
4429 break
4430 else:
4431 EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)
4432
4433 Obj.OverrideAttribs = Overrides
4434
4435 ## __GetOptRomFileStatement() method
4436 #
4437 # Get FILE statements
4438 #
4439 # @param self The object pointer
4440 # @param Obj for whom FILE statement is got
4441 # @retval True Successfully find FILE statement
4442 # @retval False Not able to find FILE statement
4443 #
4444 def __GetOptRomFileStatement(self, Obj):
4445
4446 if not self.__IsKeyword( "FILE"):
4447 return False
4448
4449 FfsFileObj = OptRomFileStatement.OptRomFileStatement()
4450
4451 if not self.__IsKeyword("EFI") and not self.__IsKeyword("BIN"):
4452 raise Warning("expected Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber)
4453 FfsFileObj.FileType = self.__Token
4454
4455 if not self.__GetNextToken():
4456 raise Warning("expected File path", self.FileName, self.CurrentLineNumber)
4457 FfsFileObj.FileName = self.__Token
4458 if FfsFileObj.FileName.replace('$(WORKSPACE)', '').find('$') == -1:
4459 #check for file path
4460 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
4461 if ErrorCode != 0:
4462 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
4463
4464 if FfsFileObj.FileType == 'EFI':
4465 self.__GetOptRomOverrides(FfsFileObj)
4466
4467 Obj.FfsList.append(FfsFileObj)
4468
4469 return True
4470
4471 ## __GetCapInFd() method
4472 #
4473 # Get Cap list contained in FD
4474 #
4475 # @param self The object pointer
4476 # @param FdName FD name
4477 # @retval CapList List of Capsule in FD
4478 #
4479 def __GetCapInFd (self, FdName):
4480
4481 CapList = []
4482 if FdName.upper() in self.Profile.FdDict.keys():
4483 FdObj = self.Profile.FdDict[FdName.upper()]
4484 for elementRegion in FdObj.RegionList:
4485 if elementRegion.RegionType == 'CAPSULE':
4486 for elementRegionData in elementRegion.RegionDataList:
4487 if elementRegionData.endswith(".cap"):
4488 continue
4489 if elementRegionData != None and elementRegionData.upper() not in CapList:
4490 CapList.append(elementRegionData.upper())
4491 return CapList
4492
4493 ## __GetReferencedFdCapTuple() method
4494 #
4495 # Get FV and FD list referenced by a capsule image
4496 #
4497 # @param self The object pointer
4498 # @param CapObj Capsule section to be searched
4499 # @param RefFdList referenced FD by section
4500 # @param RefFvList referenced FV by section
4501 #
4502 def __GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):
4503
4504 for CapsuleDataObj in CapObj.CapsuleDataList :
4505 if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName != None and CapsuleDataObj.FvName.upper() not in RefFvList:
4506 RefFvList.append (CapsuleDataObj.FvName.upper())
4507 elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName != None and CapsuleDataObj.FdName.upper() not in RefFdList:
4508 RefFdList.append (CapsuleDataObj.FdName.upper())
4509 elif CapsuleDataObj.Ffs != None:
4510 if isinstance(CapsuleDataObj.Ffs, FfsFileStatement.FileStatement):
4511 if CapsuleDataObj.Ffs.FvName != None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:
4512 RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())
4513 elif CapsuleDataObj.Ffs.FdName != None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:
4514 RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())
4515 else:
4516 self.__GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)
4517
4518 ## __GetFvInFd() method
4519 #
4520 # Get FV list contained in FD
4521 #
4522 # @param self The object pointer
4523 # @param FdName FD name
4524 # @retval FvList list of FV in FD
4525 #
4526 def __GetFvInFd (self, FdName):
4527
4528 FvList = []
4529 if FdName.upper() in self.Profile.FdDict.keys():
4530 FdObj = self.Profile.FdDict[FdName.upper()]
4531 for elementRegion in FdObj.RegionList:
4532 if elementRegion.RegionType == 'FV':
4533 for elementRegionData in elementRegion.RegionDataList:
4534 if elementRegionData.endswith(".fv"):
4535 continue
4536 if elementRegionData != None and elementRegionData.upper() not in FvList:
4537 FvList.append(elementRegionData.upper())
4538 return FvList
4539
4540 ## __GetReferencedFdFvTuple() method
4541 #
4542 # Get FD and FV list referenced by a FFS file
4543 #
4544 # @param self The object pointer
4545 # @param FfsFile contains sections to be searched
4546 # @param RefFdList referenced FD by section
4547 # @param RefFvList referenced FV by section
4548 #
4549 def __GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):
4550
4551 for FfsObj in FvObj.FfsList:
4552 if isinstance(FfsObj, FfsFileStatement.FileStatement):
4553 if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList:
4554 RefFvList.append(FfsObj.FvName.upper())
4555 elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList:
4556 RefFdList.append(FfsObj.FdName.upper())
4557 else:
4558 self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)
4559
4560 ## __GetReferencedFdFvTupleFromSection() method
4561 #
4562 # Get FD and FV list referenced by a FFS section
4563 #
4564 # @param self The object pointer
4565 # @param FfsFile contains sections to be searched
4566 # @param FdList referenced FD by section
4567 # @param FvList referenced FV by section
4568 #
4569 def __GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):
4570
4571 SectionStack = []
4572 SectionStack.extend(FfsFile.SectionList)
4573 while SectionStack != []:
4574 SectionObj = SectionStack.pop()
4575 if isinstance(SectionObj, FvImageSection.FvImageSection):
4576 if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList:
4577 FvList.append(SectionObj.FvName.upper())
4578 if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList:
4579 FvList.append(SectionObj.Fv.UiFvName.upper())
4580 self.__GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)
4581
4582 if isinstance(SectionObj, CompressSection.CompressSection) or isinstance(SectionObj, GuidSection.GuidSection):
4583 SectionStack.extend(SectionObj.SectionList)
4584
4585 ## CycleReferenceCheck() method
4586 #
4587 # Check whether cycle reference exists in FDF
4588 #
4589 # @param self The object pointer
4590 # @retval True cycle reference exists
4591 # @retval False Not exists cycle reference
4592 #
4593 def CycleReferenceCheck(self):
4594 #
4595 # Check the cycle between FV and FD image
4596 #
4597 MaxLength = len (self.Profile.FvDict)
4598 for FvName in self.Profile.FvDict.keys():
4599 LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName
4600 RefFvStack = []
4601 RefFvStack.append(FvName)
4602 FdAnalyzedList = []
4603
4604 Index = 0
4605 while RefFvStack != [] and Index < MaxLength:
4606 Index = Index + 1
4607 FvNameFromStack = RefFvStack.pop()
4608 if FvNameFromStack.upper() in self.Profile.FvDict.keys():
4609 FvObj = self.Profile.FvDict[FvNameFromStack.upper()]
4610 else:
4611 continue
4612
4613 RefFdList = []
4614 RefFvList = []
4615 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
4616
4617 for RefFdName in RefFdList:
4618 if RefFdName in FdAnalyzedList:
4619 continue
4620
4621 LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)
4622 FvInFdList = self.__GetFvInFd(RefFdName)
4623 if FvInFdList != []:
4624 for FvNameInFd in FvInFdList:
4625 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)
4626 if FvNameInFd not in RefFvStack:
4627 RefFvStack.append(FvNameInFd)
4628
4629 if FvName in RefFvStack or FvNameFromStack in RefFvStack:
4630 EdkLogger.info(LogStr)
4631 return True
4632 FdAnalyzedList.append(RefFdName)
4633
4634 for RefFvName in RefFvList:
4635 LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)
4636 if RefFvName not in RefFvStack:
4637 RefFvStack.append(RefFvName)
4638
4639 if FvName in RefFvStack or FvNameFromStack in RefFvStack:
4640 EdkLogger.info(LogStr)
4641 return True
4642
4643 #
4644 # Check the cycle between Capsule and FD image
4645 #
4646 MaxLength = len (self.Profile.CapsuleDict)
4647 for CapName in self.Profile.CapsuleDict.keys():
4648 #
4649 # Capsule image to be checked.
4650 #
4651 LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4652 RefCapStack = []
4653 RefCapStack.append(CapName)
4654 FdAnalyzedList = []
4655 FvAnalyzedList = []
4656
4657 Index = 0
4658 while RefCapStack != [] and Index < MaxLength:
4659 Index = Index + 1
4660 CapNameFromStack = RefCapStack.pop()
4661 if CapNameFromStack.upper() in self.Profile.CapsuleDict.keys():
4662 CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]
4663 else:
4664 continue
4665
4666 RefFvList = []
4667 RefFdList = []
4668 self.__GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)
4669
4670 FvListLength = 0
4671 FdListLength = 0
4672 while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):
4673 for RefFdName in RefFdList:
4674 if RefFdName in FdAnalyzedList:
4675 continue
4676
4677 LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)
4678 CapInFdList = self.__GetCapInFd(RefFdName)
4679 if CapInFdList != []:
4680 for CapNameInFd in CapInFdList:
4681 LogStr += "FD %s contains Capsule %s\n" % (RefFdName,CapNameInFd)
4682 if CapNameInFd not in RefCapStack:
4683 RefCapStack.append(CapNameInFd)
4684
4685 if CapName in RefCapStack or CapNameFromStack in RefCapStack:
4686 EdkLogger.info(LogStr)
4687 return True
4688
4689 FvInFdList = self.__GetFvInFd(RefFdName)
4690 if FvInFdList != []:
4691 for FvNameInFd in FvInFdList:
4692 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)
4693 if FvNameInFd not in RefFvList:
4694 RefFvList.append(FvNameInFd)
4695
4696 FdAnalyzedList.append(RefFdName)
4697 #
4698 # the number of the parsed FV and FD image
4699 #
4700 FvListLength = len (RefFvList)
4701 FdListLength = len (RefFdList)
4702 for RefFvName in RefFvList:
4703 if RefFvName in FvAnalyzedList:
4704 continue
4705 LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)
4706 if RefFvName.upper() in self.Profile.FvDict.keys():
4707 FvObj = self.Profile.FvDict[RefFvName.upper()]
4708 else:
4709 continue
4710 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
4711 FvAnalyzedList.append(RefFvName)
4712
4713 return False
4714
4715 if __name__ == "__main__":
4716 import sys
4717 try:
4718 test_file = sys.argv[1]
4719 except IndexError, v:
4720 print "Usage: %s filename" % sys.argv[0]
4721 sys.exit(1)
4722
4723 parser = FdfParser(test_file)
4724 try:
4725 parser.ParseFile()
4726 parser.CycleReferenceCheck()
4727 except Warning, X:
4728 print str(X)
4729 else:
4730 print "Success!"
4731