]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/FdfParser.py
Sync BaseTool trunk (version r2599) into EDKII BaseTools.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FdfParser.py
1 ## @file
2 # parse FDF file
3 #
4 # Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
5 #
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
10 #
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 #
14
15 ##
16 # Import Modules
17 #
18 import 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 self.__GetTokenStatements(FdObj)
1427
1428 self.__GetDefineStatements(FdObj)
1429
1430 self.__GetSetStatements(FdObj)
1431
1432 if not self.__GetRegionLayout(FdObj):
1433 raise Warning("expected region layout", self.FileName, self.CurrentLineNumber)
1434
1435 while self.__GetRegionLayout(FdObj):
1436 pass
1437 return True
1438
1439 ## __GetUiName() method
1440 #
1441 # Return the UI name of a section
1442 #
1443 # @param self The object pointer
1444 # @retval FdName UI name
1445 #
1446 def __GetUiName(self):
1447 Name = ""
1448 if self.__GetNextWord():
1449 Name = self.__Token
1450
1451 return Name
1452
1453 ## __GetCreateFile() method
1454 #
1455 # Return the output file name of object
1456 #
1457 # @param self The object pointer
1458 # @param Obj object whose data will be stored in file
1459 # @retval FdName UI name
1460 #
1461 def __GetCreateFile(self, Obj):
1462
1463 if self.__IsKeyword( "CREATE_FILE"):
1464 if not self.__IsToken( "="):
1465 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1466
1467 if not self.__GetNextToken():
1468 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)
1469
1470 FileName = self.__Token
1471 Obj.CreateFileName = FileName
1472
1473 return True
1474
1475 ## __GetTokenStatements() method
1476 #
1477 # Get token statements
1478 #
1479 # @param self The object pointer
1480 # @param Obj for whom token statement is got
1481 #
1482 def __GetTokenStatements(self, Obj):
1483 if not self.__IsKeyword( "BaseAddress"):
1484 raise Warning("BaseAddress missing", self.FileName, self.CurrentLineNumber)
1485
1486 if not self.__IsToken( "="):
1487 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1488
1489 if not self.__GetNextHexNumber():
1490 raise Warning("expected Hex base address", self.FileName, self.CurrentLineNumber)
1491
1492 Obj.BaseAddress = self.__Token
1493
1494 if self.__IsToken( "|"):
1495 pcdPair = self.__GetNextPcdName()
1496 Obj.BaseAddressPcd = pcdPair
1497 self.Profile.PcdDict[pcdPair] = Obj.BaseAddress
1498 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1499 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
1500
1501 if not self.__IsKeyword( "Size"):
1502 raise Warning("Size missing", self.FileName, self.CurrentLineNumber)
1503
1504 if not self.__IsToken( "="):
1505 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1506
1507 if not self.__GetNextHexNumber():
1508 raise Warning("expected Hex size", self.FileName, self.CurrentLineNumber)
1509
1510
1511 Size = self.__Token
1512 if self.__IsToken( "|"):
1513 pcdPair = self.__GetNextPcdName()
1514 Obj.SizePcd = pcdPair
1515 self.Profile.PcdDict[pcdPair] = Size
1516 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
1517 self.Profile.PcdFileLineDict[pcdPair] = FileLineTuple
1518 Obj.Size = long(Size, 0)
1519
1520 if not self.__IsKeyword( "ErasePolarity"):
1521 raise Warning("ErasePolarity missing", self.FileName, self.CurrentLineNumber)
1522
1523 if not self.__IsToken( "="):
1524 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1525
1526 if not self.__GetNextToken():
1527 raise Warning("expected Erase Polarity", self.FileName, self.CurrentLineNumber)
1528
1529 if self.__Token != "1" and self.__Token != "0":
1530 raise Warning("expected 1 or 0 Erase Polarity", self.FileName, self.CurrentLineNumber)
1531
1532 Obj.ErasePolarity = self.__Token
1533
1534 self.__GetBlockStatements(Obj)
1535
1536 ## __GetAddressStatements() method
1537 #
1538 # Get address statements
1539 #
1540 # @param self The object pointer
1541 # @param Obj for whom address statement is got
1542 # @retval True Successfully find
1543 # @retval False Not able to find
1544 #
1545 def __GetAddressStatements(self, Obj):
1546
1547 if self.__IsKeyword("BsBaseAddress"):
1548 if not self.__IsToken( "="):
1549 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1550
1551 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1552 raise Warning("expected address", self.FileName, self.CurrentLineNumber)
1553
1554 BsAddress = long(self.__Token, 0)
1555 Obj.BsBaseAddress = BsAddress
1556
1557 if self.__IsKeyword("RtBaseAddress"):
1558 if not self.__IsToken( "="):
1559 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
1560
1561 if not self.__GetNextDecimalNumber() and not self.__GetNextHexNumber():
1562 raise Warning("expected address", self.FileName, self.CurrentLineNumber)
1563
1564 RtAddress = long(self.__Token, 0)
1565 Obj.RtBaseAddress = RtAddress
1566
1567 ## __GetBlockStatements() method
1568 #
1569 # Get block statements
1570 #
1571 # @param self The object pointer
1572 # @param Obj for whom block statement is got
1573 #
1574 def __GetBlockStatements(self, Obj):
1575
1576 if not self.__GetBlockStatement(Obj):
1577 #set default block size is 1
1578 Obj.BlockSizeList.append((1, Obj.Size, None))
1579 return
1580
1581 while self.__GetBlockStatement(Obj):
1582 pass
1583
1584 for Item in Obj.BlockSizeList:
1585 if Item[0] == None or Item[1] == None:
1586 raise Warning("expected block statement", self.FileName, self.CurrentLineNumber)
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 while self.__GetBlockStatement(FvObj):
2042 pass
2043
2044 self.__GetSetStatements(FvObj)
2045
2046 self.__GetFvBaseAddress(FvObj)
2047
2048 self.__GetFvForceRebase(FvObj)
2049
2050 self.__GetFvAlignment(FvObj)
2051
2052 self.__GetFvAttributes(FvObj)
2053
2054 self.__GetFvNameGuid(FvObj)
2055
2056 FvObj.FvExtEntryTypeValue = []
2057 FvObj.FvExtEntryType = []
2058 FvObj.FvExtEntryData = []
2059 while True:
2060 isFvExtEntry = self.__GetFvExtEntryStatement(FvObj)
2061 if not isFvExtEntry:
2062 break
2063
2064 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
2065 self.__GetAprioriSection(FvObj, FvObj.DefineVarDict.copy())
2066
2067 while True:
2068 isInf = self.__GetInfStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
2069 isFile = self.__GetFileStatement(FvObj, MacroDict = FvObj.DefineVarDict.copy())
2070 if not isInf and not isFile:
2071 break
2072
2073 return True
2074
2075 ## __GetFvAlignment() method
2076 #
2077 # Get alignment for FV
2078 #
2079 # @param self The object pointer
2080 # @param Obj for whom alignment is got
2081 # @retval True Successfully find a alignment statement
2082 # @retval False Not able to find a alignment statement
2083 #
2084 def __GetFvAlignment(self, Obj):
2085
2086 if not self.__IsKeyword( "FvAlignment"):
2087 return False
2088
2089 if not self.__IsToken( "="):
2090 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2091
2092 if not self.__GetNextToken():
2093 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)
2094
2095 if self.__Token.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2096 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2097 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2098 "1G", "2G"):
2099 raise Warning("Unknown alignment value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2100 Obj.FvAlignment = self.__Token
2101 return True
2102
2103 ## __GetFvBaseAddress() method
2104 #
2105 # Get BaseAddress for FV
2106 #
2107 # @param self The object pointer
2108 # @param Obj for whom FvBaseAddress is got
2109 # @retval True Successfully find a FvBaseAddress statement
2110 # @retval False Not able to find a FvBaseAddress statement
2111 #
2112 def __GetFvBaseAddress(self, Obj):
2113
2114 if not self.__IsKeyword("FvBaseAddress"):
2115 return False
2116
2117 if not self.__IsToken( "="):
2118 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2119
2120 if not self.__GetNextToken():
2121 raise Warning("expected FV base address value", self.FileName, self.CurrentLineNumber)
2122
2123 IsValidBaseAddrValue = re.compile('^0[x|X][0-9a-fA-F]+')
2124
2125 if not IsValidBaseAddrValue.match(self.__Token.upper()):
2126 raise Warning("Unknown FV base address value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2127 Obj.FvBaseAddress = self.__Token
2128 return True
2129
2130 ## __GetFvForceRebase() method
2131 #
2132 # Get FvForceRebase for FV
2133 #
2134 # @param self The object pointer
2135 # @param Obj for whom FvForceRebase is got
2136 # @retval True Successfully find a FvForceRebase statement
2137 # @retval False Not able to find a FvForceRebase statement
2138 #
2139 def __GetFvForceRebase(self, Obj):
2140
2141 if not self.__IsKeyword("FvForceRebase"):
2142 return False
2143
2144 if not self.__IsToken( "="):
2145 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2146
2147 if not self.__GetNextToken():
2148 raise Warning("expected FvForceRebase value", self.FileName, self.CurrentLineNumber)
2149
2150 if self.__Token.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:
2151 raise Warning("Unknown FvForceRebase value '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2152
2153 if self.__Token.upper() in ["TRUE", "1", "0X1", "0X01"]:
2154 Obj.FvForceRebase = True
2155 elif self.__Token.upper() in ["FALSE", "0", "0X0", "0X00"]:
2156 Obj.FvForceRebase = False
2157 else:
2158 Obj.FvForceRebase = None
2159
2160 return True
2161
2162
2163 ## __GetFvAttributes() method
2164 #
2165 # Get attributes for FV
2166 #
2167 # @param self The object pointer
2168 # @param Obj for whom attribute is got
2169 # @retval None
2170 #
2171 def __GetFvAttributes(self, FvObj):
2172
2173 while self.__GetNextWord():
2174 name = self.__Token
2175 if name not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
2176 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2177 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2178 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2179 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2180 "WRITE_POLICY_RELIABLE"):
2181 self.__UndoToken()
2182 return
2183
2184 if not self.__IsToken( "="):
2185 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2186
2187 if not self.__GetNextToken() or self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
2188 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
2189
2190 FvObj.FvAttributeDict[name] = self.__Token
2191
2192 return
2193
2194 ## __GetFvNameGuid() method
2195 #
2196 # Get FV GUID for FV
2197 #
2198 # @param self The object pointer
2199 # @param Obj for whom GUID is got
2200 # @retval None
2201 #
2202 def __GetFvNameGuid(self, FvObj):
2203
2204 if not self.__IsKeyword( "FvNameGuid"):
2205 return
2206
2207 if not self.__IsToken( "="):
2208 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2209
2210 if not self.__GetNextGuid():
2211 raise Warning("expected FV GUID value", self.FileName, self.CurrentLineNumber)
2212
2213 FvObj.FvNameGuid = self.__Token
2214
2215 return
2216
2217 def __GetFvExtEntryStatement(self, FvObj):
2218
2219 if not self.__IsKeyword( "FV_EXT_ENTRY"):
2220 return False
2221
2222 if not self.__IsKeyword ("TYPE"):
2223 raise Warning("expected 'TYPE'", self.FileName, self.CurrentLineNumber)
2224
2225 if not self.__IsToken( "="):
2226 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2227
2228 if not self.__GetNextHexNumber() and not self.__GetNextDecimalNumber():
2229 raise Warning("expected Hex FV extension entry type value At Line ", self.FileName, self.CurrentLineNumber)
2230
2231 FvObj.FvExtEntryTypeValue += [self.__Token]
2232
2233 if not self.__IsToken( "{"):
2234 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2235
2236 if not self.__IsKeyword ("FILE") and not self.__IsKeyword ("DATA"):
2237 raise Warning("expected 'FILE' or 'DATA'", self.FileName, self.CurrentLineNumber)
2238
2239 FvObj.FvExtEntryType += [self.__Token]
2240
2241 if self.__Token == 'DATA':
2242
2243 if not self.__IsToken( "="):
2244 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2245
2246 if not self.__IsToken( "{"):
2247 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2248
2249 if not self.__GetNextHexNumber():
2250 raise Warning("expected Hex byte", self.FileName, self.CurrentLineNumber)
2251
2252 if len(self.__Token) > 4:
2253 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
2254
2255 DataString = self.__Token
2256 DataString += ","
2257
2258 while self.__IsToken(","):
2259 if not self.__GetNextHexNumber():
2260 raise Warning("Invalid Hex number", self.FileName, self.CurrentLineNumber)
2261 if len(self.__Token) > 4:
2262 raise Warning("Hex byte(must be 2 digits) too long", self.FileName, self.CurrentLineNumber)
2263 DataString += self.__Token
2264 DataString += ","
2265
2266 if not self.__IsToken( "}"):
2267 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2268
2269 if not self.__IsToken( "}"):
2270 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2271
2272 DataString = DataString.rstrip(",")
2273 FvObj.FvExtEntryData += [DataString]
2274
2275 if self.__Token == 'FILE':
2276
2277 if not self.__IsToken( "="):
2278 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2279
2280 if not self.__GetNextToken():
2281 raise Warning("expected FV Extension Entry file path At Line ", self.FileName, self.CurrentLineNumber)
2282
2283 FvObj.FvExtEntryData += [self.__Token]
2284
2285 if not self.__IsToken( "}"):
2286 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2287
2288 return True
2289
2290 ## __GetAprioriSection() method
2291 #
2292 # Get token statements
2293 #
2294 # @param self The object pointer
2295 # @param FvObj for whom apriori is got
2296 # @param MacroDict dictionary used to replace macro
2297 # @retval True Successfully find apriori statement
2298 # @retval False Not able to find apriori statement
2299 #
2300 def __GetAprioriSection(self, FvObj, MacroDict = {}):
2301
2302 if not self.__IsKeyword( "APRIORI"):
2303 return False
2304
2305 if not self.__IsKeyword("PEI") and not self.__IsKeyword("DXE"):
2306 raise Warning("expected Apriori file type", self.FileName, self.CurrentLineNumber)
2307 AprType = self.__Token
2308
2309 if not self.__IsToken( "{"):
2310 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2311
2312 AprSectionObj = AprioriSection.AprioriSection()
2313 AprSectionObj.AprioriType = AprType
2314
2315 self.__GetDefineStatements(AprSectionObj)
2316 MacroDict.update(AprSectionObj.DefineVarDict)
2317
2318 while True:
2319 IsInf = self.__GetInfStatement( AprSectionObj, MacroDict = MacroDict)
2320 IsFile = self.__GetFileStatement( AprSectionObj)
2321 if not IsInf and not IsFile:
2322 break
2323
2324 if not self.__IsToken( "}"):
2325 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2326
2327 FvObj.AprioriSectionList.append(AprSectionObj)
2328 return True
2329
2330 ## __GetInfStatement() method
2331 #
2332 # Get INF statements
2333 #
2334 # @param self The object pointer
2335 # @param Obj for whom inf statement is got
2336 # @param MacroDict dictionary used to replace macro
2337 # @retval True Successfully find inf statement
2338 # @retval False Not able to find inf statement
2339 #
2340 def __GetInfStatement(self, Obj, ForCapsule = False, MacroDict = {}):
2341
2342 if not self.__IsKeyword( "INF"):
2343 return False
2344
2345 ffsInf = FfsInfStatement.FfsInfStatement()
2346 self.__GetInfOptions( ffsInf)
2347
2348 if not self.__GetNextToken():
2349 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)
2350 ffsInf.InfFileName = self.__Token
2351
2352 ffsInf.CurrentLineNum = self.CurrentLineNumber
2353 ffsInf.CurrentLineContent = self.__CurrentLine()
2354
2355 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:
2356 #do case sensitive check for file path
2357 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
2358 if ErrorCode != 0:
2359 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
2360
2361 if not ffsInf.InfFileName in self.Profile.InfList:
2362 self.Profile.InfList.append(ffsInf.InfFileName)
2363 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
2364 self.Profile.InfFileLineList.append(FileLineTuple)
2365
2366 if self.__IsToken('|'):
2367 if self.__IsKeyword('RELOCS_STRIPPED'):
2368 ffsInf.KeepReloc = False
2369 elif self.__IsKeyword('RELOCS_RETAINED'):
2370 ffsInf.KeepReloc = True
2371 else:
2372 raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2373
2374 if ForCapsule:
2375 capsuleFfs = CapsuleData.CapsuleFfs()
2376 capsuleFfs.Ffs = ffsInf
2377 Obj.CapsuleDataList.append(capsuleFfs)
2378 else:
2379 Obj.FfsList.append(ffsInf)
2380 return True
2381
2382 ## __GetInfOptions() method
2383 #
2384 # Get options for INF
2385 #
2386 # @param self The object pointer
2387 # @param FfsInfObj for whom option is got
2388 #
2389 def __GetInfOptions(self, FfsInfObj):
2390
2391 if self.__IsKeyword( "RuleOverride"):
2392 if not self.__IsToken( "="):
2393 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2394 if not self.__GetNextToken():
2395 raise Warning("expected Rule name", self.FileName, self.CurrentLineNumber)
2396 FfsInfObj.Rule = self.__Token
2397
2398 if self.__IsKeyword( "VERSION"):
2399 if not self.__IsToken( "="):
2400 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2401 if not self.__GetNextToken():
2402 raise Warning("expected Version", self.FileName, self.CurrentLineNumber)
2403
2404 if self.__GetStringData():
2405 FfsInfObj.Version = self.__Token
2406
2407 if self.__IsKeyword( "UI"):
2408 if not self.__IsToken( "="):
2409 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2410 if not self.__GetNextToken():
2411 raise Warning("expected UI name", self.FileName, self.CurrentLineNumber)
2412
2413 if self.__GetStringData():
2414 FfsInfObj.Ui = self.__Token
2415
2416 if self.__IsKeyword( "USE"):
2417 if not self.__IsToken( "="):
2418 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2419 if not self.__GetNextToken():
2420 raise Warning("expected ARCH name", self.FileName, self.CurrentLineNumber)
2421 FfsInfObj.UseArch = self.__Token
2422
2423
2424 if self.__GetNextToken():
2425 p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2426 if p.match(self.__Token):
2427 FfsInfObj.KeyStringList.append(self.__Token)
2428 if not self.__IsToken(","):
2429 return
2430 else:
2431 self.__UndoToken()
2432 return
2433
2434 while self.__GetNextToken():
2435 if not p.match(self.__Token):
2436 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
2437 FfsInfObj.KeyStringList.append(self.__Token)
2438
2439 if not self.__IsToken(","):
2440 break
2441
2442 ## __GetFileStatement() method
2443 #
2444 # Get FILE statements
2445 #
2446 # @param self The object pointer
2447 # @param Obj for whom FILE statement is got
2448 # @param MacroDict dictionary used to replace macro
2449 # @retval True Successfully find FILE statement
2450 # @retval False Not able to find FILE statement
2451 #
2452 def __GetFileStatement(self, Obj, ForCapsule = False, MacroDict = {}):
2453
2454 if not self.__IsKeyword( "FILE"):
2455 return False
2456
2457 if not self.__GetNextWord():
2458 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)
2459
2460 if ForCapsule and self.__Token == 'DATA':
2461 self.__UndoToken()
2462 self.__UndoToken()
2463 return False
2464
2465 FfsFileObj = FfsFileStatement.FileStatement()
2466 FfsFileObj.FvFileType = self.__Token
2467
2468 if not self.__IsToken( "="):
2469 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2470
2471 if not self.__GetNextGuid():
2472 if not self.__GetNextWord():
2473 raise Warning("expected File GUID", self.FileName, self.CurrentLineNumber)
2474 if self.__Token == 'PCD':
2475 if not self.__IsToken( "("):
2476 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
2477 PcdPair = self.__GetNextPcdName()
2478 if not self.__IsToken( ")"):
2479 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
2480 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
2481
2482 FfsFileObj.NameGuid = self.__Token
2483
2484 self.__GetFilePart( FfsFileObj, MacroDict.copy())
2485
2486 if ForCapsule:
2487 capsuleFfs = CapsuleData.CapsuleFfs()
2488 capsuleFfs.Ffs = FfsFileObj
2489 Obj.CapsuleDataList.append(capsuleFfs)
2490 else:
2491 Obj.FfsList.append(FfsFileObj)
2492
2493 return True
2494
2495 ## __FileCouldHaveRelocFlag() method
2496 #
2497 # Check whether reloc strip flag can be set for a file type.
2498 #
2499 # @param self The object pointer
2500 # @param FileType The file type to check with
2501 # @retval True This type could have relocation strip flag
2502 # @retval False No way to have it
2503 #
2504
2505 def __FileCouldHaveRelocFlag (self, FileType):
2506 if FileType in ('SEC', 'PEI_CORE', 'PEIM', 'PEI_DXE_COMBO'):
2507 return True
2508 else:
2509 return False
2510
2511 ## __SectionCouldHaveRelocFlag() method
2512 #
2513 # Check whether reloc strip flag can be set for a section type.
2514 #
2515 # @param self The object pointer
2516 # @param SectionType The section type to check with
2517 # @retval True This type could have relocation strip flag
2518 # @retval False No way to have it
2519 #
2520
2521 def __SectionCouldHaveRelocFlag (self, SectionType):
2522 if SectionType in ('TE', 'PE32'):
2523 return True
2524 else:
2525 return False
2526
2527 ## __GetFilePart() method
2528 #
2529 # Get components for FILE statement
2530 #
2531 # @param self The object pointer
2532 # @param FfsFileObj for whom component is got
2533 # @param MacroDict dictionary used to replace macro
2534 #
2535 def __GetFilePart(self, FfsFileObj, MacroDict = {}):
2536
2537 self.__GetFileOpts( FfsFileObj)
2538
2539 if not self.__IsToken("{"):
2540 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2541 if self.__FileCouldHaveRelocFlag(FfsFileObj.FvFileType):
2542 if self.__Token == 'RELOCS_STRIPPED':
2543 FfsFileObj.KeepReloc = False
2544 else:
2545 FfsFileObj.KeepReloc = True
2546 else:
2547 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj.FvFileType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
2548
2549 if not self.__IsToken("{"):
2550 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2551
2552 if not self.__GetNextToken():
2553 raise Warning("expected File name or section data", self.FileName, self.CurrentLineNumber)
2554
2555 if self.__Token == "FV":
2556 if not self.__IsToken( "="):
2557 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2558 if not self.__GetNextToken():
2559 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
2560 FfsFileObj.FvName = self.__Token
2561
2562 elif self.__Token == "FD":
2563 if not self.__IsToken( "="):
2564 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2565 if not self.__GetNextToken():
2566 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)
2567 FfsFileObj.FdName = self.__Token
2568
2569 elif self.__Token in ("DEFINE", "APRIORI", "SECTION"):
2570 self.__UndoToken()
2571 self.__GetSectionData( FfsFileObj, MacroDict)
2572 else:
2573 FfsFileObj.CurrentLineNum = self.CurrentLineNumber
2574 FfsFileObj.CurrentLineContent = self.__CurrentLine()
2575 FfsFileObj.FileName = self.__Token
2576 if FfsFileObj.FileName.replace('$(WORKSPACE)', '').find('$') == -1:
2577 #
2578 # For file in OUTPUT_DIRECTORY will not check whether it exist or not at AutoGen phase.
2579 #
2580 if not GlobalData.gAutoGenPhase:
2581 #do case sensitive check for file path
2582 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
2583 if ErrorCode != 0:
2584 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
2585 else:
2586 if not self.__GetMacroValue("OUTPUT_DIRECTORY") in FfsFileObj.FileName:
2587 #do case sensitive check for file path
2588 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
2589 if ErrorCode != 0:
2590 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
2591
2592
2593 if not self.__IsToken( "}"):
2594 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2595
2596 ## __GetFileOpts() method
2597 #
2598 # Get options for FILE statement
2599 #
2600 # @param self The object pointer
2601 # @param FfsFileObj for whom options is got
2602 #
2603 def __GetFileOpts(self, FfsFileObj):
2604
2605 if self.__GetNextToken():
2606 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
2607 if Pattern.match(self.__Token):
2608 FfsFileObj.KeyStringList.append(self.__Token)
2609 if self.__IsToken(","):
2610 while self.__GetNextToken():
2611 if not Pattern.match(self.__Token):
2612 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
2613 FfsFileObj.KeyStringList.append(self.__Token)
2614
2615 if not self.__IsToken(","):
2616 break
2617
2618 else:
2619 self.__UndoToken()
2620
2621 if self.__IsKeyword( "FIXED", True):
2622 FfsFileObj.Fixed = True
2623
2624 if self.__IsKeyword( "CHECKSUM", True):
2625 FfsFileObj.CheckSum = True
2626
2627 if self.__GetAlignment():
2628 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2629 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2630 #For FFS, Auto is default option same to ""
2631 if not self.__Token == "Auto":
2632 FfsFileObj.Alignment = self.__Token
2633
2634 ## __GetAlignment() method
2635 #
2636 # Return the alignment value
2637 #
2638 # @param self The object pointer
2639 # @retval True Successfully find alignment
2640 # @retval False Not able to find alignment
2641 #
2642 def __GetAlignment(self):
2643 if self.__IsKeyword( "Align", True):
2644 if not self.__IsToken( "="):
2645 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2646
2647 if not self.__GetNextToken():
2648 raise Warning("expected alignment value", self.FileName, self.CurrentLineNumber)
2649 return True
2650
2651 return False
2652
2653 ## __GetFilePart() method
2654 #
2655 # Get section data for FILE statement
2656 #
2657 # @param self The object pointer
2658 # @param FfsFileObj for whom section is got
2659 # @param MacroDict dictionary used to replace macro
2660 #
2661 def __GetSectionData(self, FfsFileObj, MacroDict = {}):
2662 Dict = {}
2663 Dict.update(MacroDict)
2664
2665 self.__GetDefineStatements(FfsFileObj)
2666
2667 Dict.update(FfsFileObj.DefineVarDict)
2668 self.__GetAprioriSection(FfsFileObj, Dict.copy())
2669 self.__GetAprioriSection(FfsFileObj, Dict.copy())
2670
2671 while True:
2672 IsLeafSection = self.__GetLeafSection(FfsFileObj, Dict)
2673 IsEncapSection = self.__GetEncapsulationSec(FfsFileObj)
2674 if not IsLeafSection and not IsEncapSection:
2675 break
2676
2677 ## __GetLeafSection() method
2678 #
2679 # Get leaf section for Obj
2680 #
2681 # @param self The object pointer
2682 # @param Obj for whom leaf section is got
2683 # @param MacroDict dictionary used to replace macro
2684 # @retval True Successfully find section statement
2685 # @retval False Not able to find section statement
2686 #
2687 def __GetLeafSection(self, Obj, MacroDict = {}):
2688
2689 OldPos = self.GetFileBufferPos()
2690
2691 if not self.__IsKeyword( "SECTION"):
2692 if len(Obj.SectionList) == 0:
2693 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)
2694 else:
2695 return False
2696
2697 AlignValue = None
2698 if self.__GetAlignment():
2699 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2700 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2701 AlignValue = self.__Token
2702
2703 BuildNum = None
2704 if self.__IsKeyword( "BUILD_NUM"):
2705 if not self.__IsToken( "="):
2706 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2707
2708 if not self.__GetNextToken():
2709 raise Warning("expected Build number value", self.FileName, self.CurrentLineNumber)
2710
2711 BuildNum = self.__Token
2712
2713 if self.__IsKeyword( "VERSION"):
2714 if AlignValue == 'Auto':
2715 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2716 if not self.__IsToken( "="):
2717 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2718 if not self.__GetNextToken():
2719 raise Warning("expected version", self.FileName, self.CurrentLineNumber)
2720 VerSectionObj = VerSection.VerSection()
2721 VerSectionObj.Alignment = AlignValue
2722 VerSectionObj.BuildNum = BuildNum
2723 if self.__GetStringData():
2724 VerSectionObj.StringData = self.__Token
2725 else:
2726 VerSectionObj.FileName = self.__Token
2727 Obj.SectionList.append(VerSectionObj)
2728
2729 elif self.__IsKeyword( "UI"):
2730 if AlignValue == 'Auto':
2731 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2732 if not self.__IsToken( "="):
2733 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2734 if not self.__GetNextToken():
2735 raise Warning("expected UI", self.FileName, self.CurrentLineNumber)
2736 UiSectionObj = UiSection.UiSection()
2737 UiSectionObj.Alignment = AlignValue
2738 if self.__GetStringData():
2739 UiSectionObj.StringData = self.__Token
2740 else:
2741 UiSectionObj.FileName = self.__Token
2742 Obj.SectionList.append(UiSectionObj)
2743
2744 elif self.__IsKeyword( "FV_IMAGE"):
2745 if AlignValue == 'Auto':
2746 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2747 if not self.__IsToken( "="):
2748 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2749 if not self.__GetNextToken():
2750 raise Warning("expected FV name or FV file path", self.FileName, self.CurrentLineNumber)
2751
2752 FvName = self.__Token
2753 FvObj = None
2754
2755 if self.__IsToken( "{"):
2756 FvObj = Fv.FV()
2757 FvObj.UiFvName = FvName.upper()
2758 self.__GetDefineStatements(FvObj)
2759 MacroDict.update(FvObj.DefineVarDict)
2760 self.__GetBlockStatement(FvObj)
2761 self.__GetSetStatements(FvObj)
2762 self.__GetFvAlignment(FvObj)
2763 self.__GetFvAttributes(FvObj)
2764 self.__GetAprioriSection(FvObj, MacroDict.copy())
2765 self.__GetAprioriSection(FvObj, MacroDict.copy())
2766
2767 while True:
2768 IsInf = self.__GetInfStatement(FvObj, MacroDict.copy())
2769 IsFile = self.__GetFileStatement(FvObj, MacroDict.copy())
2770 if not IsInf and not IsFile:
2771 break
2772
2773 if not self.__IsToken( "}"):
2774 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2775
2776 FvImageSectionObj = FvImageSection.FvImageSection()
2777 FvImageSectionObj.Alignment = AlignValue
2778 if FvObj != None:
2779 FvImageSectionObj.Fv = FvObj
2780 FvImageSectionObj.FvName = None
2781 else:
2782 FvImageSectionObj.FvName = FvName.upper()
2783 FvImageSectionObj.FvFileName = FvName
2784
2785 Obj.SectionList.append(FvImageSectionObj)
2786
2787 elif self.__IsKeyword("PEI_DEPEX_EXP") or self.__IsKeyword("DXE_DEPEX_EXP") or self.__IsKeyword("SMM_DEPEX_EXP"):
2788 if AlignValue == 'Auto':
2789 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2790 DepexSectionObj = DepexSection.DepexSection()
2791 DepexSectionObj.Alignment = AlignValue
2792 DepexSectionObj.DepexType = self.__Token
2793
2794 if not self.__IsToken( "="):
2795 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2796 if not self.__IsToken( "{"):
2797 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2798 if not self.__SkipToToken( "}"):
2799 raise Warning("expected Depex expression ending '}'", self.FileName, self.CurrentLineNumber)
2800
2801 DepexSectionObj.Expression = self.__SkippedChars.rstrip('}')
2802 Obj.SectionList.append(DepexSectionObj)
2803
2804 else:
2805 if not self.__GetNextWord():
2806 raise Warning("expected section type", self.FileName, self.CurrentLineNumber)
2807
2808 # Encapsulation section appear, UndoToken and return
2809 if self.__Token == "COMPRESS" or self.__Token == "GUIDED":
2810 self.SetFileBufferPos(OldPos)
2811 return False
2812
2813 if self.__Token not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
2814 "UI", "VERSION", "PEI_DEPEX", "SUBTYPE_GUID", "SMM_DEPEX"):
2815 raise Warning("Unknown section type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2816 if AlignValue == 'Auto'and (not self.__Token == 'PE32') and (not self.__Token == 'TE'):
2817 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
2818
2819 # DataSection
2820 DataSectionObj = DataSection.DataSection()
2821 DataSectionObj.Alignment = AlignValue
2822 DataSectionObj.SecType = self.__Token
2823
2824 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
2825 if self.__FileCouldHaveRelocFlag(Obj.FvFileType) and self.__SectionCouldHaveRelocFlag(DataSectionObj.SecType):
2826 if self.__Token == 'RELOCS_STRIPPED':
2827 DataSectionObj.KeepReloc = False
2828 else:
2829 DataSectionObj.KeepReloc = True
2830 else:
2831 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)
2832
2833 if self.__IsToken("="):
2834 if not self.__GetNextToken():
2835 raise Warning("expected section file path", self.FileName, self.CurrentLineNumber)
2836 DataSectionObj.SectFileName = self.__Token
2837 if DataSectionObj.SectFileName.replace('$(WORKSPACE)', '').find('$') == -1:
2838 #do case sensitive check for file path
2839 ErrorCode, ErrorInfo = PathClass(NormPath(DataSectionObj.SectFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
2840 if ErrorCode != 0:
2841 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
2842 else:
2843 if not self.__GetCglSection(DataSectionObj):
2844 return False
2845
2846 Obj.SectionList.append(DataSectionObj)
2847
2848 return True
2849
2850 ## __GetCglSection() method
2851 #
2852 # Get compressed or GUIDed section for Obj
2853 #
2854 # @param self The object pointer
2855 # @param Obj for whom leaf section is got
2856 # @param AlignValue alignment value for complex section
2857 # @retval True Successfully find section statement
2858 # @retval False Not able to find section statement
2859 #
2860 def __GetCglSection(self, Obj, AlignValue = None):
2861
2862 if self.__IsKeyword( "COMPRESS"):
2863 type = "PI_STD"
2864 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
2865 type = self.__Token
2866
2867 if not self.__IsToken("{"):
2868 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2869
2870 CompressSectionObj = CompressSection.CompressSection()
2871 CompressSectionObj.Alignment = AlignValue
2872 CompressSectionObj.CompType = type
2873 # Recursive sections...
2874 while True:
2875 IsLeafSection = self.__GetLeafSection(CompressSectionObj)
2876 IsEncapSection = self.__GetEncapsulationSec(CompressSectionObj)
2877 if not IsLeafSection and not IsEncapSection:
2878 break
2879
2880
2881 if not self.__IsToken( "}"):
2882 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2883 Obj.SectionList.append(CompressSectionObj)
2884
2885 # else:
2886 # raise Warning("Compress type not known")
2887
2888 return True
2889
2890 elif self.__IsKeyword( "GUIDED"):
2891 GuidValue = None
2892 if self.__GetNextGuid():
2893 GuidValue = self.__Token
2894
2895 AttribDict = self.__GetGuidAttrib()
2896 if not self.__IsToken("{"):
2897 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
2898 GuidSectionObj = GuidSection.GuidSection()
2899 GuidSectionObj.Alignment = AlignValue
2900 GuidSectionObj.NameGuid = GuidValue
2901 GuidSectionObj.SectionType = "GUIDED"
2902 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
2903 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
2904 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]
2905 # Recursive sections...
2906 while True:
2907 IsLeafSection = self.__GetLeafSection(GuidSectionObj)
2908 IsEncapSection = self.__GetEncapsulationSec(GuidSectionObj)
2909 if not IsLeafSection and not IsEncapSection:
2910 break
2911
2912 if not self.__IsToken( "}"):
2913 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
2914 Obj.SectionList.append(GuidSectionObj)
2915
2916 return True
2917
2918 return False
2919
2920 ## __GetGuidAttri() method
2921 #
2922 # Get attributes for GUID section
2923 #
2924 # @param self The object pointer
2925 # @retval AttribDict Dictionary of key-value pair of section attributes
2926 #
2927 def __GetGuidAttrib(self):
2928
2929 AttribDict = {}
2930 AttribDict["PROCESSING_REQUIRED"] = "NONE"
2931 AttribDict["AUTH_STATUS_VALID"] = "NONE"
2932 AttribDict["EXTRA_HEADER_SIZE"] = -1
2933 while self.__IsKeyword("PROCESSING_REQUIRED") or self.__IsKeyword("AUTH_STATUS_VALID") \
2934 or self.__IsKeyword("EXTRA_HEADER_SIZE"):
2935 AttribKey = self.__Token
2936
2937 if not self.__IsToken("="):
2938 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
2939
2940 if not self.__GetNextToken():
2941 raise Warning("expected TRUE(1)/FALSE(0)/Number", self.FileName, self.CurrentLineNumber)
2942 elif AttribKey == "EXTRA_HEADER_SIZE":
2943 Base = 10
2944 if self.__Token[0:2].upper() == "0X":
2945 Base = 16
2946 try:
2947 AttribDict[AttribKey] = int(self.__Token, Base)
2948 continue
2949 except ValueError:
2950 raise Warning("expected Number", self.FileName, self.CurrentLineNumber)
2951 elif self.__Token.upper() not in ("TRUE", "FALSE", "1", "0"):
2952 raise Warning("expected TRUE/FALSE (1/0)", self.FileName, self.CurrentLineNumber)
2953 AttribDict[AttribKey] = self.__Token
2954
2955 return AttribDict
2956
2957 ## __GetEncapsulationSec() method
2958 #
2959 # Get encapsulation section for FILE
2960 #
2961 # @param self The object pointer
2962 # @param FfsFile for whom section is got
2963 # @retval True Successfully find section statement
2964 # @retval False Not able to find section statement
2965 #
2966 def __GetEncapsulationSec(self, FfsFileObj):
2967
2968 OldPos = self.GetFileBufferPos()
2969 if not self.__IsKeyword( "SECTION"):
2970 if len(FfsFileObj.SectionList) == 0:
2971 raise Warning("expected SECTION", self.FileName, self.CurrentLineNumber)
2972 else:
2973 return False
2974
2975 AlignValue = None
2976 if self.__GetAlignment():
2977 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
2978 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
2979 AlignValue = self.__Token
2980
2981 if not self.__GetCglSection(FfsFileObj, AlignValue):
2982 self.SetFileBufferPos(OldPos)
2983 return False
2984 else:
2985 return True
2986
2987 ## __GetCapsule() method
2988 #
2989 # Get capsule section contents and store its data into capsule list of self.Profile
2990 #
2991 # @param self The object pointer
2992 # @retval True Successfully find a capsule
2993 # @retval False Not able to find a capsule
2994 #
2995 def __GetCapsule(self):
2996
2997 if not self.__GetNextToken():
2998 return False
2999
3000 S = self.__Token.upper()
3001 if S.startswith("[") and not S.startswith("[CAPSULE."):
3002 if not S.startswith("[VTF.") and not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
3003 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
3004 self.__UndoToken()
3005 return False
3006
3007 self.__UndoToken()
3008 if not self.__IsToken("[CAPSULE.", True):
3009 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
3010 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3011 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3012 raise Warning("expected [Capsule.]", self.FileName, self.CurrentLineNumber)
3013
3014 CapsuleObj = Capsule.Capsule()
3015
3016 CapsuleName = self.__GetUiName()
3017 if not CapsuleName:
3018 raise Warning("expected capsule name", self.FileName, self.CurrentLineNumber)
3019
3020 CapsuleObj.UiCapsuleName = CapsuleName.upper()
3021
3022 if not self.__IsToken( "]"):
3023 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
3024
3025 if self.__IsKeyword("CREATE_FILE"):
3026 if not self.__IsToken( "="):
3027 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3028
3029 if not self.__GetNextToken():
3030 raise Warning("expected file name", self.FileName, self.CurrentLineNumber)
3031
3032 CapsuleObj.CreateFile = self.__Token
3033
3034 self.__GetCapsuleStatements(CapsuleObj)
3035 self.Profile.CapsuleDict[CapsuleObj.UiCapsuleName] = CapsuleObj
3036 return True
3037
3038 ## __GetCapsuleStatements() method
3039 #
3040 # Get statements for capsule
3041 #
3042 # @param self The object pointer
3043 # @param Obj for whom statements are got
3044 #
3045 def __GetCapsuleStatements(self, Obj):
3046 self.__GetCapsuleTokens(Obj)
3047 self.__GetDefineStatements(Obj)
3048 self.__GetSetStatements(Obj)
3049 self.__GetCapsuleData(Obj)
3050
3051 ## __GetCapsuleTokens() method
3052 #
3053 # Get token statements for capsule
3054 #
3055 # @param self The object pointer
3056 # @param Obj for whom token statements are got
3057 #
3058 def __GetCapsuleTokens(self, Obj):
3059 if not self.__GetNextToken():
3060 return False
3061 while self.__Token in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS"):
3062 Name = self.__Token.strip()
3063 if not self.__IsToken("="):
3064 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3065 if not self.__GetNextToken():
3066 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
3067 if Name == 'CAPSULE_FLAGS':
3068 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
3069 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
3070 Value = self.__Token.strip()
3071 while self.__IsToken(","):
3072 Value += ','
3073 if not self.__GetNextToken():
3074 raise Warning("expected value", self.FileName, self.CurrentLineNumber)
3075 if not self.__Token in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
3076 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self.FileName, self.CurrentLineNumber)
3077 Value += self.__Token.strip()
3078 else:
3079 Value = self.__Token.strip()
3080 Obj.TokensDict[Name] = Value
3081 if not self.__GetNextToken():
3082 return False
3083 self.__UndoToken()
3084
3085 ## __GetCapsuleData() method
3086 #
3087 # Get capsule data for capsule
3088 #
3089 # @param self The object pointer
3090 # @param Obj for whom capsule data are got
3091 #
3092 def __GetCapsuleData(self, Obj):
3093
3094 while True:
3095 IsInf = self.__GetInfStatement(Obj, True)
3096 IsFile = self.__GetFileStatement(Obj, True)
3097 IsFv = self.__GetFvStatement(Obj)
3098 IsFd = self.__GetFdStatement(Obj)
3099 IsAnyFile = self.__GetAnyFileStatement(Obj)
3100 if not (IsInf or IsFile or IsFv or IsFd or IsAnyFile):
3101 break
3102
3103 ## __GetFvStatement() method
3104 #
3105 # Get FV for capsule
3106 #
3107 # @param self The object pointer
3108 # @param CapsuleObj for whom FV is got
3109 # @retval True Successfully find a FV statement
3110 # @retval False Not able to find a FV statement
3111 #
3112 def __GetFvStatement(self, CapsuleObj):
3113
3114 if not self.__IsKeyword("FV"):
3115 return False
3116
3117 if not self.__IsToken("="):
3118 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3119
3120 if not self.__GetNextToken():
3121 raise Warning("expected FV name", self.FileName, self.CurrentLineNumber)
3122
3123 if self.__Token.upper() not in self.Profile.FvDict.keys():
3124 raise Warning("FV name does not exist", self.FileName, self.CurrentLineNumber)
3125
3126 CapsuleFv = CapsuleData.CapsuleFv()
3127 CapsuleFv.FvName = self.__Token
3128 CapsuleObj.CapsuleDataList.append(CapsuleFv)
3129 return True
3130
3131 ## __GetFdStatement() method
3132 #
3133 # Get FD for capsule
3134 #
3135 # @param self The object pointer
3136 # @param CapsuleObj for whom FD is got
3137 # @retval True Successfully find a FD statement
3138 # @retval False Not able to find a FD statement
3139 #
3140 def __GetFdStatement(self, CapsuleObj):
3141
3142 if not self.__IsKeyword("FD"):
3143 return False
3144
3145 if not self.__IsToken("="):
3146 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3147
3148 if not self.__GetNextToken():
3149 raise Warning("expected FD name", self.FileName, self.CurrentLineNumber)
3150
3151 if self.__Token.upper() not in self.Profile.FdDict.keys():
3152 raise Warning("FD name does not exist", self.FileName, self.CurrentLineNumber)
3153
3154 CapsuleFd = CapsuleData.CapsuleFd()
3155 CapsuleFd.FdName = self.__Token
3156 CapsuleObj.CapsuleDataList.append(CapsuleFd)
3157 return True
3158
3159 ## __GetAnyFileStatement() method
3160 #
3161 # Get AnyFile for capsule
3162 #
3163 # @param self The object pointer
3164 # @param CapsuleObj for whom AnyFile is got
3165 # @retval True Successfully find a Anyfile statement
3166 # @retval False Not able to find a AnyFile statement
3167 #
3168 def __GetAnyFileStatement(self, CapsuleObj):
3169
3170 if not self.__IsKeyword("FILE"):
3171 return False
3172
3173 if not self.__IsKeyword("DATA"):
3174 self.__UndoToken()
3175 return False
3176
3177 if not self.__IsToken("="):
3178 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3179
3180 if not self.__GetNextToken():
3181 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
3182
3183 AnyFileName = self.__Token
3184 AnyFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(AnyFileName)
3185 if not os.path.exists(AnyFileName):
3186 raise Warning("File %s not exists"%AnyFileName, self.FileName, self.CurrentLineNumber)
3187
3188 CapsuleAnyFile = CapsuleData.CapsuleAnyFile()
3189 CapsuleAnyFile.FileName = AnyFileName
3190 CapsuleObj.CapsuleDataList.append(CapsuleAnyFile)
3191 return True
3192
3193 ## __GetRule() method
3194 #
3195 # Get Rule section contents and store its data into rule list of self.Profile
3196 #
3197 # @param self The object pointer
3198 # @retval True Successfully find a Rule
3199 # @retval False Not able to find a Rule
3200 #
3201 def __GetRule(self):
3202
3203 if not self.__GetNextToken():
3204 return False
3205
3206 S = self.__Token.upper()
3207 if S.startswith("[") and not S.startswith("[RULE."):
3208 if not S.startswith("[OPTIONROM."):
3209 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
3210 self.__UndoToken()
3211 return False
3212 self.__UndoToken()
3213 if not self.__IsToken("[Rule.", True):
3214 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
3215 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3216 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3217 raise Warning("expected [Rule.]", self.FileName, self.CurrentLineNumber)
3218
3219 if not self.__SkipToToken("."):
3220 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
3221
3222 Arch = self.__SkippedChars.rstrip(".")
3223 if Arch.upper() not in ("IA32", "X64", "IPF", "EBC", "ARM", "AARCH64", "COMMON"):
3224 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
3225
3226 ModuleType = self.__GetModuleType()
3227
3228 TemplateName = ""
3229 if self.__IsToken("."):
3230 if not self.__GetNextWord():
3231 raise Warning("expected template name", self.FileName, self.CurrentLineNumber)
3232 TemplateName = self.__Token
3233
3234 if not self.__IsToken( "]"):
3235 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
3236
3237 RuleObj = self.__GetRuleFileStatements()
3238 RuleObj.Arch = Arch.upper()
3239 RuleObj.ModuleType = ModuleType
3240 RuleObj.TemplateName = TemplateName
3241 if TemplateName == '' :
3242 self.Profile.RuleDict['RULE' + \
3243 '.' + \
3244 Arch.upper() + \
3245 '.' + \
3246 ModuleType.upper() ] = RuleObj
3247 else :
3248 self.Profile.RuleDict['RULE' + \
3249 '.' + \
3250 Arch.upper() + \
3251 '.' + \
3252 ModuleType.upper() + \
3253 '.' + \
3254 TemplateName.upper() ] = RuleObj
3255 # self.Profile.RuleList.append(rule)
3256 return True
3257
3258 ## __GetModuleType() method
3259 #
3260 # Return the module type
3261 #
3262 # @param self The object pointer
3263 # @retval string module type
3264 #
3265 def __GetModuleType(self):
3266
3267 if not self.__GetNextWord():
3268 raise Warning("expected Module type", self.FileName, self.CurrentLineNumber)
3269 if self.__Token.upper() not in ("SEC", "PEI_CORE", "PEIM", "DXE_CORE", \
3270 "DXE_DRIVER", "DXE_SAL_DRIVER", \
3271 "DXE_SMM_DRIVER", "DXE_RUNTIME_DRIVER", \
3272 "UEFI_DRIVER", "UEFI_APPLICATION", "USER_DEFINED", "DEFAULT", "BASE", \
3273 "SECURITY_CORE", "COMBINED_PEIM_DRIVER", "PIC_PEIM", "RELOCATABLE_PEIM", \
3274 "PE32_PEIM", "BS_DRIVER", "RT_DRIVER", "SAL_RT_DRIVER", "APPLICATION", "ACPITABLE", "SMM_CORE"):
3275 raise Warning("Unknown Module type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3276 return self.__Token
3277
3278 ## __GetFileExtension() method
3279 #
3280 # Return the file extension
3281 #
3282 # @param self The object pointer
3283 # @retval string file name extension
3284 #
3285 def __GetFileExtension(self):
3286 if not self.__IsToken("."):
3287 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
3288
3289 Ext = ""
3290 if self.__GetNextToken():
3291 Pattern = re.compile(r'([a-zA-Z][a-zA-Z0-9]*)')
3292 if Pattern.match(self.__Token):
3293 Ext = self.__Token
3294 return '.' + Ext
3295 else:
3296 raise Warning("Unknown file extension '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3297
3298 else:
3299 raise Warning("expected file extension", self.FileName, self.CurrentLineNumber)
3300
3301 ## __GetRuleFileStatement() method
3302 #
3303 # Get rule contents
3304 #
3305 # @param self The object pointer
3306 # @retval Rule Rule object
3307 #
3308 def __GetRuleFileStatements(self):
3309
3310 if not self.__IsKeyword("FILE"):
3311 raise Warning("expected FILE", self.FileName, self.CurrentLineNumber)
3312
3313 if not self.__GetNextWord():
3314 raise Warning("expected FFS type", self.FileName, self.CurrentLineNumber)
3315
3316 Type = self.__Token.strip().upper()
3317 if Type not in ("RAW", "FREEFORM", "SEC", "PEI_CORE", "PEIM",\
3318 "PEI_DXE_COMBO", "DRIVER", "DXE_CORE", "APPLICATION", "FV_IMAGE", "SMM", "SMM_CORE"):
3319 raise Warning("Unknown FV type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3320
3321 if not self.__IsToken("="):
3322 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3323
3324 if not self.__IsKeyword("$(NAMED_GUID)"):
3325 if not self.__GetNextWord():
3326 raise Warning("expected $(NAMED_GUID)", self.FileName, self.CurrentLineNumber)
3327 if self.__Token == 'PCD':
3328 if not self.__IsToken( "("):
3329 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
3330 PcdPair = self.__GetNextPcdName()
3331 if not self.__IsToken( ")"):
3332 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
3333 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
3334
3335 NameGuid = self.__Token
3336
3337 KeepReloc = None
3338 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
3339 if self.__FileCouldHaveRelocFlag(Type):
3340 if self.__Token == 'RELOCS_STRIPPED':
3341 KeepReloc = False
3342 else:
3343 KeepReloc = True
3344 else:
3345 raise Warning("File type %s could not have reloc strip flag%d" % (Type, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3346
3347 KeyStringList = []
3348 if self.__GetNextToken():
3349 Pattern = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
3350 if Pattern.match(self.__Token):
3351 KeyStringList.append(self.__Token)
3352 if self.__IsToken(","):
3353 while self.__GetNextToken():
3354 if not Pattern.match(self.__Token):
3355 raise Warning("expected KeyString \"Target_Tag_Arch\"", self.FileName, self.CurrentLineNumber)
3356 KeyStringList.append(self.__Token)
3357
3358 if not self.__IsToken(","):
3359 break
3360
3361 else:
3362 self.__UndoToken()
3363
3364
3365 Fixed = False
3366 if self.__IsKeyword("Fixed", True):
3367 Fixed = True
3368
3369 CheckSum = False
3370 if self.__IsKeyword("CheckSum", True):
3371 CheckSum = True
3372
3373 AlignValue = ""
3374 if self.__GetAlignment():
3375 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3376 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3377 #For FFS, Auto is default option same to ""
3378 if not self.__Token == "Auto":
3379 AlignValue = self.__Token
3380
3381 if self.__IsToken("{"):
3382 # Complex file rule expected
3383 Rule = RuleComplexFile.RuleComplexFile()
3384 Rule.FvFileType = Type
3385 Rule.NameGuid = NameGuid
3386 Rule.Alignment = AlignValue
3387 Rule.CheckSum = CheckSum
3388 Rule.Fixed = Fixed
3389 Rule.KeyStringList = KeyStringList
3390 if KeepReloc != None:
3391 Rule.KeepReloc = KeepReloc
3392
3393 while True:
3394 IsEncapsulate = self.__GetRuleEncapsulationSection(Rule)
3395 IsLeaf = self.__GetEfiSection(Rule)
3396 if not IsEncapsulate and not IsLeaf:
3397 break
3398
3399 if not self.__IsToken("}"):
3400 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
3401
3402 return Rule
3403
3404 else:
3405 # Simple file rule expected
3406 if not self.__GetNextWord():
3407 raise Warning("expected leaf section type", self.FileName, self.CurrentLineNumber)
3408
3409 SectionName = self.__Token
3410
3411 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3412 "UI", "PEI_DEPEX", "VERSION", "SUBTYPE_GUID", "SMM_DEPEX"):
3413 raise Warning("Unknown leaf section name '%s'" % SectionName, self.FileName, self.CurrentLineNumber)
3414
3415
3416 if self.__IsKeyword("Fixed", True):
3417 Fixed = True
3418
3419 if self.__IsKeyword("CheckSum", True):
3420 CheckSum = True
3421
3422 SectAlignment = ""
3423 if self.__GetAlignment():
3424 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3425 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3426 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
3427 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
3428 SectAlignment = self.__Token
3429
3430 Ext = None
3431 if self.__IsToken('|'):
3432 Ext = self.__GetFileExtension()
3433 elif not self.__GetNextToken():
3434 raise Warning("expected File name", self.FileName, self.CurrentLineNumber)
3435
3436 Rule = RuleSimpleFile.RuleSimpleFile()
3437 Rule.SectionType = SectionName
3438 Rule.FvFileType = Type
3439 Rule.NameGuid = NameGuid
3440 Rule.Alignment = AlignValue
3441 Rule.SectAlignment = SectAlignment
3442 Rule.CheckSum = CheckSum
3443 Rule.Fixed = Fixed
3444 Rule.KeyStringList = KeyStringList
3445 if KeepReloc != None:
3446 Rule.KeepReloc = KeepReloc
3447 Rule.FileExtension = Ext
3448 Rule.FileName = self.__Token
3449 return Rule
3450
3451 ## __GetEfiSection() method
3452 #
3453 # Get section list for Rule
3454 #
3455 # @param self The object pointer
3456 # @param Obj for whom section is got
3457 # @retval True Successfully find section statement
3458 # @retval False Not able to find section statement
3459 #
3460 def __GetEfiSection(self, Obj):
3461
3462 OldPos = self.GetFileBufferPos()
3463 if not self.__GetNextWord():
3464 return False
3465 SectionName = self.__Token
3466
3467 if SectionName not in ("COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3468 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3469 self.__UndoToken()
3470 return False
3471
3472 if SectionName == "FV_IMAGE":
3473 FvImageSectionObj = FvImageSection.FvImageSection()
3474 if self.__IsKeyword("FV_IMAGE"):
3475 pass
3476 if self.__IsToken( "{"):
3477 FvObj = Fv.FV()
3478 self.__GetDefineStatements(FvObj)
3479 self.__GetBlockStatement(FvObj)
3480 self.__GetSetStatements(FvObj)
3481 self.__GetFvAlignment(FvObj)
3482 self.__GetFvAttributes(FvObj)
3483 self.__GetAprioriSection(FvObj)
3484 self.__GetAprioriSection(FvObj)
3485
3486 while True:
3487 IsInf = self.__GetInfStatement(FvObj)
3488 IsFile = self.__GetFileStatement(FvObj)
3489 if not IsInf and not IsFile:
3490 break
3491
3492 if not self.__IsToken( "}"):
3493 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
3494 FvImageSectionObj.Fv = FvObj
3495 FvImageSectionObj.FvName = None
3496
3497 else:
3498 if not self.__IsKeyword("FV"):
3499 raise Warning("expected 'FV'", self.FileName, self.CurrentLineNumber)
3500 FvImageSectionObj.FvFileType = self.__Token
3501
3502 if self.__GetAlignment():
3503 if self.__Token not in ("8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3504 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3505 FvImageSectionObj.Alignment = self.__Token
3506
3507 if self.__IsToken('|'):
3508 FvImageSectionObj.FvFileExtension = self.__GetFileExtension()
3509 elif self.__GetNextToken():
3510 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3511 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3512 FvImageSectionObj.FvFileName = self.__Token
3513 else:
3514 self.__UndoToken()
3515 else:
3516 raise Warning("expected FV file name", self.FileName, self.CurrentLineNumber)
3517
3518 Obj.SectionList.append(FvImageSectionObj)
3519 return True
3520
3521 EfiSectionObj = EfiSection.EfiSection()
3522 EfiSectionObj.SectionType = SectionName
3523
3524 if not self.__GetNextToken():
3525 raise Warning("expected file type", self.FileName, self.CurrentLineNumber)
3526
3527 if self.__Token == "STRING":
3528 if not self.__RuleSectionCouldHaveString(EfiSectionObj.SectionType):
3529 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3530
3531 if not self.__IsToken('='):
3532 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3533
3534 if not self.__GetNextToken():
3535 raise Warning("expected Quoted String", self.FileName, self.CurrentLineNumber)
3536
3537 if self.__GetStringData():
3538 EfiSectionObj.StringData = self.__Token
3539
3540 if self.__IsKeyword("BUILD_NUM"):
3541 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
3542 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3543
3544 if not self.__IsToken("="):
3545 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3546 if not self.__GetNextToken():
3547 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)
3548 EfiSectionObj.BuildNum = self.__Token
3549
3550 else:
3551 EfiSectionObj.FileType = self.__Token
3552 self.__CheckRuleSectionFileType(EfiSectionObj.SectionType, EfiSectionObj.FileType)
3553
3554 if self.__IsKeyword("Optional"):
3555 if not self.__RuleSectionCouldBeOptional(EfiSectionObj.SectionType):
3556 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3557 EfiSectionObj.Optional = True
3558
3559 if self.__IsKeyword("BUILD_NUM"):
3560 if not self.__RuleSectionCouldHaveBuildNum(EfiSectionObj.SectionType):
3561 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj.SectionType, self.CurrentLineNumber), self.FileName, self.CurrentLineNumber)
3562
3563 if not self.__IsToken("="):
3564 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3565 if not self.__GetNextToken():
3566 raise Warning("expected Build number", self.FileName, self.CurrentLineNumber)
3567 EfiSectionObj.BuildNum = self.__Token
3568
3569 if self.__GetAlignment():
3570 if self.__Token not in ("Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K" ,"64K"):
3571 raise Warning("Incorrect alignment '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3572 if self.__Token == 'Auto' and (not SectionName == 'PE32') and (not SectionName == 'TE'):
3573 raise Warning("Auto alignment can only be used in PE32 or TE section ", self.FileName, self.CurrentLineNumber)
3574 EfiSectionObj.Alignment = self.__Token
3575
3576 if self.__IsKeyword('RELOCS_STRIPPED') or self.__IsKeyword('RELOCS_RETAINED'):
3577 if self.__SectionCouldHaveRelocFlag(EfiSectionObj.SectionType):
3578 if self.__Token == 'RELOCS_STRIPPED':
3579 EfiSectionObj.KeepReloc = False
3580 else:
3581 EfiSectionObj.KeepReloc = True
3582 if Obj.KeepReloc != None and Obj.KeepReloc != EfiSectionObj.KeepReloc:
3583 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
3584 else:
3585 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj.SectionType, self.FileName, self.CurrentLineNumber)
3586
3587
3588 if self.__IsToken('|'):
3589 EfiSectionObj.FileExtension = self.__GetFileExtension()
3590 elif self.__GetNextToken():
3591 if self.__Token not in ("}", "COMPAT16", "PE32", "PIC", "TE", "FV_IMAGE", "RAW", "DXE_DEPEX",\
3592 "UI", "VERSION", "PEI_DEPEX", "GUID", "SMM_DEPEX"):
3593
3594 if self.__Token.startswith('PCD'):
3595 self.__UndoToken()
3596 self.__GetNextWord()
3597
3598 if self.__Token == 'PCD':
3599 if not self.__IsToken( "("):
3600 raise Warning("expected '('", self.FileName, self.CurrentLineNumber)
3601 PcdPair = self.__GetNextPcdName()
3602 if not self.__IsToken( ")"):
3603 raise Warning("expected ')'", self.FileName, self.CurrentLineNumber)
3604 self.__Token = 'PCD('+PcdPair[1]+'.'+PcdPair[0]+')'
3605
3606 EfiSectionObj.FileName = self.__Token
3607
3608 else:
3609 self.__UndoToken()
3610 else:
3611 raise Warning("expected section file name", self.FileName, self.CurrentLineNumber)
3612
3613 Obj.SectionList.append(EfiSectionObj)
3614 return True
3615
3616 ## __RuleSectionCouldBeOptional() method
3617 #
3618 # Get whether a section could be optional
3619 #
3620 # @param self The object pointer
3621 # @param SectionType The section type to check
3622 # @retval True section could be optional
3623 # @retval False section never optional
3624 #
3625 def __RuleSectionCouldBeOptional(self, SectionType):
3626 if SectionType in ("DXE_DEPEX", "UI", "VERSION", "PEI_DEPEX", "RAW", "SMM_DEPEX"):
3627 return True
3628 else:
3629 return False
3630
3631 ## __RuleSectionCouldHaveBuildNum() method
3632 #
3633 # Get whether a section could have build number information
3634 #
3635 # @param self The object pointer
3636 # @param SectionType The section type to check
3637 # @retval True section could have build number information
3638 # @retval False section never have build number information
3639 #
3640 def __RuleSectionCouldHaveBuildNum(self, SectionType):
3641 if SectionType in ("VERSION"):
3642 return True
3643 else:
3644 return False
3645
3646 ## __RuleSectionCouldHaveString() method
3647 #
3648 # Get whether a section could have string
3649 #
3650 # @param self The object pointer
3651 # @param SectionType The section type to check
3652 # @retval True section could have string
3653 # @retval False section never have string
3654 #
3655 def __RuleSectionCouldHaveString(self, SectionType):
3656 if SectionType in ("UI", "VERSION"):
3657 return True
3658 else:
3659 return False
3660
3661 ## __CheckRuleSectionFileType() method
3662 #
3663 # Get whether a section matches a file type
3664 #
3665 # @param self The object pointer
3666 # @param SectionType The section type to check
3667 # @param FileType The file type to check
3668 #
3669 def __CheckRuleSectionFileType(self, SectionType, FileType):
3670 if SectionType == "COMPAT16":
3671 if FileType not in ("COMPAT16", "SEC_COMPAT16"):
3672 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3673 elif SectionType == "PE32":
3674 if FileType not in ("PE32", "SEC_PE32"):
3675 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3676 elif SectionType == "PIC":
3677 if FileType not in ("PIC", "PIC"):
3678 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3679 elif SectionType == "TE":
3680 if FileType not in ("TE", "SEC_TE"):
3681 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3682 elif SectionType == "RAW":
3683 if FileType not in ("BIN", "SEC_BIN", "RAW", "ASL", "ACPI"):
3684 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3685 elif SectionType == "DXE_DEPEX" or SectionType == "SMM_DEPEX":
3686 if FileType not in ("DXE_DEPEX", "SEC_DXE_DEPEX", "SMM_DEPEX"):
3687 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3688 elif SectionType == "UI":
3689 if FileType not in ("UI", "SEC_UI"):
3690 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3691 elif SectionType == "VERSION":
3692 if FileType not in ("VERSION", "SEC_VERSION"):
3693 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3694 elif SectionType == "PEI_DEPEX":
3695 if FileType not in ("PEI_DEPEX", "SEC_PEI_DEPEX"):
3696 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3697 elif SectionType == "GUID":
3698 if FileType not in ("PE32", "SEC_GUID"):
3699 raise Warning("Incorrect section file type '%s'" % FileType, self.FileName, self.CurrentLineNumber)
3700
3701 ## __GetRuleEncapsulationSection() method
3702 #
3703 # Get encapsulation section for Rule
3704 #
3705 # @param self The object pointer
3706 # @param Rule for whom section is got
3707 # @retval True Successfully find section statement
3708 # @retval False Not able to find section statement
3709 #
3710 def __GetRuleEncapsulationSection(self, Rule):
3711
3712 if self.__IsKeyword( "COMPRESS"):
3713 Type = "PI_STD"
3714 if self.__IsKeyword("PI_STD") or self.__IsKeyword("PI_NONE"):
3715 Type = self.__Token
3716
3717 if not self.__IsToken("{"):
3718 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
3719
3720 CompressSectionObj = CompressSection.CompressSection()
3721
3722 CompressSectionObj.CompType = Type
3723 # Recursive sections...
3724 while True:
3725 IsEncapsulate = self.__GetRuleEncapsulationSection(CompressSectionObj)
3726 IsLeaf = self.__GetEfiSection(CompressSectionObj)
3727 if not IsEncapsulate and not IsLeaf:
3728 break
3729
3730 if not self.__IsToken( "}"):
3731 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
3732 Rule.SectionList.append(CompressSectionObj)
3733
3734 return True
3735
3736 elif self.__IsKeyword( "GUIDED"):
3737 GuidValue = None
3738 if self.__GetNextGuid():
3739 GuidValue = self.__Token
3740
3741 if self.__IsKeyword( "$(NAMED_GUID)"):
3742 GuidValue = self.__Token
3743
3744 AttribDict = self.__GetGuidAttrib()
3745
3746 if not self.__IsToken("{"):
3747 raise Warning("expected '{'", self.FileName, self.CurrentLineNumber)
3748 GuidSectionObj = GuidSection.GuidSection()
3749 GuidSectionObj.NameGuid = GuidValue
3750 GuidSectionObj.SectionType = "GUIDED"
3751 GuidSectionObj.ProcessRequired = AttribDict["PROCESSING_REQUIRED"]
3752 GuidSectionObj.AuthStatusValid = AttribDict["AUTH_STATUS_VALID"]
3753 GuidSectionObj.ExtraHeaderSize = AttribDict["EXTRA_HEADER_SIZE"]
3754
3755 # Efi sections...
3756 while True:
3757 IsEncapsulate = self.__GetRuleEncapsulationSection(GuidSectionObj)
3758 IsLeaf = self.__GetEfiSection(GuidSectionObj)
3759 if not IsEncapsulate and not IsLeaf:
3760 break
3761
3762 if not self.__IsToken( "}"):
3763 raise Warning("expected '}'", self.FileName, self.CurrentLineNumber)
3764 Rule.SectionList.append(GuidSectionObj)
3765
3766 return True
3767
3768 return False
3769
3770 ## __GetVtf() method
3771 #
3772 # Get VTF section contents and store its data into VTF list of self.Profile
3773 #
3774 # @param self The object pointer
3775 # @retval True Successfully find a VTF
3776 # @retval False Not able to find a VTF
3777 #
3778 def __GetVtf(self):
3779
3780 if not self.__GetNextToken():
3781 return False
3782
3783 S = self.__Token.upper()
3784 if S.startswith("[") and not S.startswith("[VTF."):
3785 if not S.startswith("[RULE.") and not S.startswith("[OPTIONROM."):
3786 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
3787 self.__UndoToken()
3788 return False
3789
3790 self.__UndoToken()
3791 if not self.__IsToken("[VTF.", True):
3792 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
3793 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3794 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine :], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3795 raise Warning("expected [VTF.]", self.FileName, self.CurrentLineNumber)
3796
3797 if not self.__SkipToToken("."):
3798 raise Warning("expected '.'", self.FileName, self.CurrentLineNumber)
3799
3800 Arch = self.__SkippedChars.rstrip(".").upper()
3801 if Arch not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
3802 raise Warning("Unknown Arch '%s'" % Arch, self.FileName, self.CurrentLineNumber)
3803
3804 if not self.__GetNextWord():
3805 raise Warning("expected VTF name", self.FileName, self.CurrentLineNumber)
3806 Name = self.__Token.upper()
3807
3808 VtfObj = Vtf.Vtf()
3809 VtfObj.UiName = Name
3810 VtfObj.KeyArch = Arch
3811
3812 if self.__IsToken(","):
3813 if not self.__GetNextWord():
3814 raise Warning("expected Arch list", self.FileName, self.CurrentLineNumber)
3815 if self.__Token.upper() not in ("IA32", "X64", "IPF", "ARM", "AARCH64"):
3816 raise Warning("Unknown Arch '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3817 VtfObj.ArchList = self.__Token.upper()
3818
3819 if not self.__IsToken( "]"):
3820 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
3821
3822 if self.__IsKeyword("IA32_RST_BIN"):
3823 if not self.__IsToken("="):
3824 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3825
3826 if not self.__GetNextToken():
3827 raise Warning("expected Reset file", self.FileName, self.CurrentLineNumber)
3828
3829 VtfObj.ResetBin = self.__Token
3830 if VtfObj.ResetBin.replace('$(WORKSPACE)', '').find('$') == -1:
3831 #check for file path
3832 ErrorCode, ErrorInfo = PathClass(NormPath(VtfObj.ResetBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()
3833 if ErrorCode != 0:
3834 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
3835
3836 while self.__GetComponentStatement(VtfObj):
3837 pass
3838
3839 self.Profile.VtfList.append(VtfObj)
3840 return True
3841
3842 ## __GetComponentStatement() method
3843 #
3844 # Get components in VTF
3845 #
3846 # @param self The object pointer
3847 # @param VtfObj for whom component is got
3848 # @retval True Successfully find a component
3849 # @retval False Not able to find a component
3850 #
3851 def __GetComponentStatement(self, VtfObj):
3852
3853 if not self.__IsKeyword("COMP_NAME"):
3854 return False
3855
3856 if not self.__IsToken("="):
3857 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3858
3859 if not self.__GetNextWord():
3860 raise Warning("expected Component Name", self.FileName, self.CurrentLineNumber)
3861
3862 CompStatementObj = ComponentStatement.ComponentStatement()
3863 CompStatementObj.CompName = self.__Token
3864
3865 if not self.__IsKeyword("COMP_LOC"):
3866 raise Warning("expected COMP_LOC", self.FileName, self.CurrentLineNumber)
3867
3868 if not self.__IsToken("="):
3869 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3870
3871 CompStatementObj.CompLoc = ""
3872 if self.__GetNextWord():
3873 CompStatementObj.CompLoc = self.__Token
3874 if self.__IsToken('|'):
3875 if not self.__GetNextWord():
3876 raise Warning("Expected Region Name", self.FileName, self.CurrentLineNumber)
3877
3878 if self.__Token not in ("F", "N", "S"): #, "H", "L", "PH", "PL"): not support
3879 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3880
3881 CompStatementObj.FilePos = self.__Token
3882 else:
3883 self.CurrentLineNumber += 1
3884 self.CurrentOffsetWithinLine = 0
3885
3886 if not self.__IsKeyword("COMP_TYPE"):
3887 raise Warning("expected COMP_TYPE", self.FileName, self.CurrentLineNumber)
3888
3889 if not self.__IsToken("="):
3890 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3891
3892 if not self.__GetNextToken():
3893 raise Warning("expected Component type", self.FileName, self.CurrentLineNumber)
3894 if self.__Token not in ("FIT", "PAL_B", "PAL_A", "OEM"):
3895 if not self.__Token.startswith("0x") or len(self.__Token) < 3 or len(self.__Token) > 4 or \
3896 not self.__HexDigit(self.__Token[2]) or not self.__HexDigit(self.__Token[-1]):
3897 raise Warning("Unknown location type '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3898 CompStatementObj.CompType = self.__Token
3899
3900 if not self.__IsKeyword("COMP_VER"):
3901 raise Warning("expected COMP_VER", self.FileName, self.CurrentLineNumber)
3902
3903 if not self.__IsToken("="):
3904 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3905
3906 if not self.__GetNextToken():
3907 raise Warning("expected Component version", self.FileName, self.CurrentLineNumber)
3908
3909 Pattern = re.compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', re.DOTALL)
3910 if Pattern.match(self.__Token) == None:
3911 raise Warning("Unknown version format '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3912 CompStatementObj.CompVer = self.__Token
3913
3914 if not self.__IsKeyword("COMP_CS"):
3915 raise Warning("expected COMP_CS", self.FileName, self.CurrentLineNumber)
3916
3917 if not self.__IsToken("="):
3918 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3919
3920 if not self.__GetNextToken():
3921 raise Warning("expected Component CS", self.FileName, self.CurrentLineNumber)
3922 if self.__Token not in ("1", "0"):
3923 raise Warning("Unknown Component CS '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3924 CompStatementObj.CompCs = self.__Token
3925
3926
3927 if not self.__IsKeyword("COMP_BIN"):
3928 raise Warning("expected COMP_BIN", self.FileName, self.CurrentLineNumber)
3929
3930 if not self.__IsToken("="):
3931 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3932
3933 if not self.__GetNextToken():
3934 raise Warning("expected Component file", self.FileName, self.CurrentLineNumber)
3935
3936 CompStatementObj.CompBin = self.__Token
3937 if CompStatementObj.CompBin != '-' and CompStatementObj.CompBin.replace('$(WORKSPACE)', '').find('$') == -1:
3938 #check for file path
3939 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompBin), GenFdsGlobalVariable.WorkSpaceDir).Validate()
3940 if ErrorCode != 0:
3941 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
3942
3943 if not self.__IsKeyword("COMP_SYM"):
3944 raise Warning("expected COMP_SYM", self.FileName, self.CurrentLineNumber)
3945
3946 if not self.__IsToken("="):
3947 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3948
3949 if not self.__GetNextToken():
3950 raise Warning("expected Component symbol file", self.FileName, self.CurrentLineNumber)
3951
3952 CompStatementObj.CompSym = self.__Token
3953 if CompStatementObj.CompSym != '-' and CompStatementObj.CompSym.replace('$(WORKSPACE)', '').find('$') == -1:
3954 #check for file path
3955 ErrorCode, ErrorInfo = PathClass(NormPath(CompStatementObj.CompSym), GenFdsGlobalVariable.WorkSpaceDir).Validate()
3956 if ErrorCode != 0:
3957 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
3958
3959 if not self.__IsKeyword("COMP_SIZE"):
3960 raise Warning("expected COMP_SIZE", self.FileName, self.CurrentLineNumber)
3961
3962 if not self.__IsToken("="):
3963 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
3964
3965 if self.__IsToken("-"):
3966 CompStatementObj.CompSize = self.__Token
3967 elif self.__GetNextDecimalNumber():
3968 CompStatementObj.CompSize = self.__Token
3969 elif self.__GetNextHexNumber():
3970 CompStatementObj.CompSize = self.__Token
3971 else:
3972 raise Warning("Unknown size '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3973
3974 VtfObj.ComponentStatementList.append(CompStatementObj)
3975 return True
3976
3977 ## __GetOptionRom() method
3978 #
3979 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
3980 #
3981 # @param self The object pointer
3982 # @retval True Successfully find a OptionROM
3983 # @retval False Not able to find a OptionROM
3984 #
3985 def __GetOptionRom(self):
3986
3987 if not self.__GetNextToken():
3988 return False
3989
3990 S = self.__Token.upper()
3991 if S.startswith("[") and not S.startswith("[OPTIONROM."):
3992 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.])", self.FileName, self.CurrentLineNumber)
3993
3994 self.__UndoToken()
3995 if not self.__IsToken("[OptionRom.", True):
3996 raise Warning("Unknown Keyword '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
3997
3998 OptRomName = self.__GetUiName()
3999
4000 if not self.__IsToken( "]"):
4001 raise Warning("expected ']'", self.FileName, self.CurrentLineNumber)
4002
4003 OptRomObj = OptionRom.OPTIONROM()
4004 OptRomObj.DriverName = OptRomName
4005 self.Profile.OptRomDict[OptRomName] = OptRomObj
4006
4007 while True:
4008 isInf = self.__GetOptRomInfStatement(OptRomObj)
4009 isFile = self.__GetOptRomFileStatement(OptRomObj)
4010 if not isInf and not isFile:
4011 break
4012
4013 return True
4014
4015 ## __GetOptRomInfStatement() method
4016 #
4017 # Get INF statements
4018 #
4019 # @param self The object pointer
4020 # @param Obj for whom inf statement is got
4021 # @retval True Successfully find inf statement
4022 # @retval False Not able to find inf statement
4023 #
4024 def __GetOptRomInfStatement(self, Obj):
4025
4026 if not self.__IsKeyword( "INF"):
4027 return False
4028
4029 ffsInf = OptRomInfStatement.OptRomInfStatement()
4030 self.__GetInfOptions( ffsInf)
4031
4032 if not self.__GetNextToken():
4033 raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)
4034 ffsInf.InfFileName = self.__Token
4035 if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:
4036 #check for file path
4037 ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
4038 if ErrorCode != 0:
4039 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
4040
4041 if not ffsInf.InfFileName in self.Profile.InfList:
4042 self.Profile.InfList.append(ffsInf.InfFileName)
4043 FileLineTuple = GetRealFileLine(self.FileName, self.CurrentLineNumber)
4044 self.Profile.InfFileLineList.append(FileLineTuple)
4045
4046
4047 self.__GetOptRomOverrides (ffsInf)
4048
4049 Obj.FfsList.append(ffsInf)
4050 return True
4051
4052 ## __GetOptRomOverrides() method
4053 #
4054 # Get overrides for OptROM INF & FILE
4055 #
4056 # @param self The object pointer
4057 # @param FfsInfObj for whom overrides is got
4058 #
4059 def __GetOptRomOverrides(self, Obj):
4060 if self.__IsToken('{'):
4061 Overrides = OptionRom.OverrideAttribs()
4062 while True:
4063 if self.__IsKeyword( "PCI_VENDOR_ID"):
4064 if not self.__IsToken( "="):
4065 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4066 if not self.__GetNextHexNumber():
4067 raise Warning("expected Hex vendor id", self.FileName, self.CurrentLineNumber)
4068 Overrides.PciVendorId = self.__Token
4069 continue
4070
4071 if self.__IsKeyword( "PCI_CLASS_CODE"):
4072 if not self.__IsToken( "="):
4073 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4074 if not self.__GetNextHexNumber():
4075 raise Warning("expected Hex class code", self.FileName, self.CurrentLineNumber)
4076 Overrides.PciClassCode = self.__Token
4077 continue
4078
4079 if self.__IsKeyword( "PCI_DEVICE_ID"):
4080 if not self.__IsToken( "="):
4081 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4082 if not self.__GetNextHexNumber():
4083 raise Warning("expected Hex device id", self.FileName, self.CurrentLineNumber)
4084
4085 Overrides.PciDeviceId = self.__Token
4086 continue
4087
4088 if self.__IsKeyword( "PCI_REVISION"):
4089 if not self.__IsToken( "="):
4090 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4091 if not self.__GetNextHexNumber():
4092 raise Warning("expected Hex revision", self.FileName, self.CurrentLineNumber)
4093 Overrides.PciRevision = self.__Token
4094 continue
4095
4096 if self.__IsKeyword( "PCI_COMPRESS"):
4097 if not self.__IsToken( "="):
4098 raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
4099 if not self.__GetNextToken():
4100 raise Warning("expected TRUE/FALSE for compress", self.FileName, self.CurrentLineNumber)
4101 Overrides.NeedCompress = self.__Token.upper() == 'TRUE'
4102 continue
4103
4104 if self.__IsToken( "}"):
4105 break
4106 else:
4107 EdkLogger.error("FdfParser", FORMAT_INVALID, File=self.FileName, Line=self.CurrentLineNumber)
4108
4109 Obj.OverrideAttribs = Overrides
4110
4111 ## __GetOptRomFileStatement() method
4112 #
4113 # Get FILE statements
4114 #
4115 # @param self The object pointer
4116 # @param Obj for whom FILE statement is got
4117 # @retval True Successfully find FILE statement
4118 # @retval False Not able to find FILE statement
4119 #
4120 def __GetOptRomFileStatement(self, Obj):
4121
4122 if not self.__IsKeyword( "FILE"):
4123 return False
4124
4125 FfsFileObj = OptRomFileStatement.OptRomFileStatement()
4126
4127 if not self.__IsKeyword("EFI") and not self.__IsKeyword("BIN"):
4128 raise Warning("expected Binary type (EFI/BIN)", self.FileName, self.CurrentLineNumber)
4129 FfsFileObj.FileType = self.__Token
4130
4131 if not self.__GetNextToken():
4132 raise Warning("expected File path", self.FileName, self.CurrentLineNumber)
4133 FfsFileObj.FileName = self.__Token
4134 if FfsFileObj.FileName.replace('$(WORKSPACE)', '').find('$') == -1:
4135 #check for file path
4136 ErrorCode, ErrorInfo = PathClass(NormPath(FfsFileObj.FileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
4137 if ErrorCode != 0:
4138 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
4139
4140 if FfsFileObj.FileType == 'EFI':
4141 self.__GetOptRomOverrides(FfsFileObj)
4142
4143 Obj.FfsList.append(FfsFileObj)
4144
4145 return True
4146
4147 ## __GetCapInFd() method
4148 #
4149 # Get Cap list contained in FD
4150 #
4151 # @param self The object pointer
4152 # @param FdName FD name
4153 # @retval CapList List of Capsule in FD
4154 #
4155 def __GetCapInFd (self, FdName):
4156
4157 CapList = []
4158 if FdName.upper() in self.Profile.FdDict.keys():
4159 FdObj = self.Profile.FdDict[FdName.upper()]
4160 for elementRegion in FdObj.RegionList:
4161 if elementRegion.RegionType == 'CAPSULE':
4162 for elementRegionData in elementRegion.RegionDataList:
4163 if elementRegionData.endswith(".cap"):
4164 continue
4165 if elementRegionData != None and elementRegionData.upper() not in CapList:
4166 CapList.append(elementRegionData.upper())
4167 return CapList
4168
4169 ## __GetReferencedFdCapTuple() method
4170 #
4171 # Get FV and FD list referenced by a capsule image
4172 #
4173 # @param self The object pointer
4174 # @param CapObj Capsule section to be searched
4175 # @param RefFdList referenced FD by section
4176 # @param RefFvList referenced FV by section
4177 #
4178 def __GetReferencedFdCapTuple(self, CapObj, RefFdList = [], RefFvList = []):
4179
4180 for CapsuleDataObj in CapObj.CapsuleDataList :
4181 if hasattr(CapsuleDataObj, 'FvName') and CapsuleDataObj.FvName != None and CapsuleDataObj.FvName.upper() not in RefFvList:
4182 RefFvList.append (CapsuleDataObj.FvName.upper())
4183 elif hasattr(CapsuleDataObj, 'FdName') and CapsuleDataObj.FdName != None and CapsuleDataObj.FdName.upper() not in RefFdList:
4184 RefFdList.append (CapsuleDataObj.FdName.upper())
4185 elif CapsuleDataObj.Ffs != None:
4186 if isinstance(CapsuleDataObj.Ffs, FfsFileStatement.FileStatement):
4187 if CapsuleDataObj.Ffs.FvName != None and CapsuleDataObj.Ffs.FvName.upper() not in RefFvList:
4188 RefFvList.append(CapsuleDataObj.Ffs.FvName.upper())
4189 elif CapsuleDataObj.Ffs.FdName != None and CapsuleDataObj.Ffs.FdName.upper() not in RefFdList:
4190 RefFdList.append(CapsuleDataObj.Ffs.FdName.upper())
4191 else:
4192 self.__GetReferencedFdFvTupleFromSection(CapsuleDataObj.Ffs, RefFdList, RefFvList)
4193
4194 ## __GetFvInFd() method
4195 #
4196 # Get FV list contained in FD
4197 #
4198 # @param self The object pointer
4199 # @param FdName FD name
4200 # @retval FvList list of FV in FD
4201 #
4202 def __GetFvInFd (self, FdName):
4203
4204 FvList = []
4205 if FdName.upper() in self.Profile.FdDict.keys():
4206 FdObj = self.Profile.FdDict[FdName.upper()]
4207 for elementRegion in FdObj.RegionList:
4208 if elementRegion.RegionType == 'FV':
4209 for elementRegionData in elementRegion.RegionDataList:
4210 if elementRegionData.endswith(".fv"):
4211 continue
4212 if elementRegionData != None and elementRegionData.upper() not in FvList:
4213 FvList.append(elementRegionData.upper())
4214 return FvList
4215
4216 ## __GetReferencedFdFvTuple() method
4217 #
4218 # Get FD and FV list referenced by a FFS file
4219 #
4220 # @param self The object pointer
4221 # @param FfsFile contains sections to be searched
4222 # @param RefFdList referenced FD by section
4223 # @param RefFvList referenced FV by section
4224 #
4225 def __GetReferencedFdFvTuple(self, FvObj, RefFdList = [], RefFvList = []):
4226
4227 for FfsObj in FvObj.FfsList:
4228 if isinstance(FfsObj, FfsFileStatement.FileStatement):
4229 if FfsObj.FvName != None and FfsObj.FvName.upper() not in RefFvList:
4230 RefFvList.append(FfsObj.FvName.upper())
4231 elif FfsObj.FdName != None and FfsObj.FdName.upper() not in RefFdList:
4232 RefFdList.append(FfsObj.FdName.upper())
4233 else:
4234 self.__GetReferencedFdFvTupleFromSection(FfsObj, RefFdList, RefFvList)
4235
4236 ## __GetReferencedFdFvTupleFromSection() method
4237 #
4238 # Get FD and FV list referenced by a FFS section
4239 #
4240 # @param self The object pointer
4241 # @param FfsFile contains sections to be searched
4242 # @param FdList referenced FD by section
4243 # @param FvList referenced FV by section
4244 #
4245 def __GetReferencedFdFvTupleFromSection(self, FfsFile, FdList = [], FvList = []):
4246
4247 SectionStack = []
4248 SectionStack.extend(FfsFile.SectionList)
4249 while SectionStack != []:
4250 SectionObj = SectionStack.pop()
4251 if isinstance(SectionObj, FvImageSection.FvImageSection):
4252 if SectionObj.FvName != None and SectionObj.FvName.upper() not in FvList:
4253 FvList.append(SectionObj.FvName.upper())
4254 if SectionObj.Fv != None and SectionObj.Fv.UiFvName != None and SectionObj.Fv.UiFvName.upper() not in FvList:
4255 FvList.append(SectionObj.Fv.UiFvName.upper())
4256 self.__GetReferencedFdFvTuple(SectionObj.Fv, FdList, FvList)
4257
4258 if isinstance(SectionObj, CompressSection.CompressSection) or isinstance(SectionObj, GuidSection.GuidSection):
4259 SectionStack.extend(SectionObj.SectionList)
4260
4261 ## CycleReferenceCheck() method
4262 #
4263 # Check whether cycle reference exists in FDF
4264 #
4265 # @param self The object pointer
4266 # @retval True cycle reference exists
4267 # @retval False Not exists cycle reference
4268 #
4269 def CycleReferenceCheck(self):
4270 #
4271 # Check the cycle between FV and FD image
4272 #
4273 MaxLength = len (self.Profile.FvDict)
4274 for FvName in self.Profile.FvDict.keys():
4275 LogStr = "\nCycle Reference Checking for FV: %s\n" % FvName
4276 RefFvStack = []
4277 RefFvStack.append(FvName)
4278 FdAnalyzedList = []
4279
4280 Index = 0
4281 while RefFvStack != [] and Index < MaxLength:
4282 Index = Index + 1
4283 FvNameFromStack = RefFvStack.pop()
4284 if FvNameFromStack.upper() in self.Profile.FvDict.keys():
4285 FvObj = self.Profile.FvDict[FvNameFromStack.upper()]
4286 else:
4287 continue
4288
4289 RefFdList = []
4290 RefFvList = []
4291 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
4292
4293 for RefFdName in RefFdList:
4294 if RefFdName in FdAnalyzedList:
4295 continue
4296
4297 LogStr += "FV %s contains FD %s\n" % (FvNameFromStack, RefFdName)
4298 FvInFdList = self.__GetFvInFd(RefFdName)
4299 if FvInFdList != []:
4300 for FvNameInFd in FvInFdList:
4301 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)
4302 if FvNameInFd not in RefFvStack:
4303 RefFvStack.append(FvNameInFd)
4304
4305 if FvName in RefFvStack or FvNameFromStack in RefFvStack:
4306 EdkLogger.info(LogStr)
4307 return True
4308 FdAnalyzedList.append(RefFdName)
4309
4310 for RefFvName in RefFvList:
4311 LogStr += "FV %s contains FV %s\n" % (FvNameFromStack, RefFvName)
4312 if RefFvName not in RefFvStack:
4313 RefFvStack.append(RefFvName)
4314
4315 if FvName in RefFvStack or FvNameFromStack in RefFvStack:
4316 EdkLogger.info(LogStr)
4317 return True
4318
4319 #
4320 # Check the cycle between Capsule and FD image
4321 #
4322 MaxLength = len (self.Profile.CapsuleDict)
4323 for CapName in self.Profile.CapsuleDict.keys():
4324 #
4325 # Capsule image to be checked.
4326 #
4327 LogStr = "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4328 RefCapStack = []
4329 RefCapStack.append(CapName)
4330 FdAnalyzedList = []
4331 FvAnalyzedList = []
4332
4333 Index = 0
4334 while RefCapStack != [] and Index < MaxLength:
4335 Index = Index + 1
4336 CapNameFromStack = RefCapStack.pop()
4337 if CapNameFromStack.upper() in self.Profile.CapsuleDict.keys():
4338 CapObj = self.Profile.CapsuleDict[CapNameFromStack.upper()]
4339 else:
4340 continue
4341
4342 RefFvList = []
4343 RefFdList = []
4344 self.__GetReferencedFdCapTuple(CapObj, RefFdList, RefFvList)
4345
4346 FvListLength = 0
4347 FdListLength = 0
4348 while FvListLength < len (RefFvList) or FdListLength < len (RefFdList):
4349 for RefFdName in RefFdList:
4350 if RefFdName in FdAnalyzedList:
4351 continue
4352
4353 LogStr += "Capsule %s contains FD %s\n" % (CapNameFromStack, RefFdName)
4354 CapInFdList = self.__GetCapInFd(RefFdName)
4355 if CapInFdList != []:
4356 for CapNameInFd in CapInFdList:
4357 LogStr += "FD %s contains Capsule %s\n" % (RefFdName,CapNameInFd)
4358 if CapNameInFd not in RefCapStack:
4359 RefCapStack.append(CapNameInFd)
4360
4361 if CapName in RefCapStack or CapNameFromStack in RefCapStack:
4362 EdkLogger.info(LogStr)
4363 return True
4364
4365 FvInFdList = self.__GetFvInFd(RefFdName)
4366 if FvInFdList != []:
4367 for FvNameInFd in FvInFdList:
4368 LogStr += "FD %s contains FV %s\n" % (RefFdName,FvNameInFd)
4369 if FvNameInFd not in RefFvList:
4370 RefFvList.append(FvNameInFd)
4371
4372 FdAnalyzedList.append(RefFdName)
4373 #
4374 # the number of the parsed FV and FD image
4375 #
4376 FvListLength = len (RefFvList)
4377 FdListLength = len (RefFdList)
4378 for RefFvName in RefFvList:
4379 if RefFvName in FvAnalyzedList:
4380 continue
4381 LogStr += "Capsule %s contains FV %s\n" % (CapNameFromStack, RefFvName)
4382 if RefFvName.upper() in self.Profile.FvDict.keys():
4383 FvObj = self.Profile.FvDict[RefFvName.upper()]
4384 else:
4385 continue
4386 self.__GetReferencedFdFvTuple(FvObj, RefFdList, RefFvList)
4387 FvAnalyzedList.append(RefFvName)
4388
4389 return False
4390
4391 if __name__ == "__main__":
4392 import sys
4393 try:
4394 test_file = sys.argv[1]
4395 except IndexError, v:
4396 print "Usage: %s filename" % sys.argv[0]
4397 sys.exit(1)
4398
4399 parser = FdfParser(test_file)
4400 try:
4401 parser.ParseFile()
4402 parser.CycleReferenceCheck()
4403 except Warning, X:
4404 print str(X)
4405 else:
4406 print "Success!"
4407