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