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