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