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