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