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