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