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