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