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