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