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