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