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