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