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