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