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