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