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