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