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