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