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