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