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