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