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