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