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