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