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