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