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