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