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