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