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