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