4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 # Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
7 # This program and the accompanying materials
8 # are licensed and made available under the terms and conditions of the BSD License
9 # which accompanies this distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 from __future__
import print_function
20 from __future__
import absolute_import
21 from re
import compile, DOTALL
22 from string
import hexdigits
25 from Common
.BuildToolError
import *
26 from Common
import EdkLogger
27 from Common
.Misc
import PathClass
, tdict
28 from Common
.StringUtils
import NormPath
, ReplaceMacro
29 from Common
import GlobalData
30 from Common
.Expression
import *
31 from Common
.DataType
import *
32 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
33 import Common
.LongFilePathOs
as os
34 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
35 from Common
.RangeExpression
import RangeExpression
36 from collections
import OrderedDict
39 from .Region
import Region
41 from .AprioriSection
import AprioriSection
42 from .FfsInfStatement
import FfsInfStatement
43 from .FfsFileStatement
import FileStatement
44 from .VerSection
import VerSection
45 from .UiSection
import UiSection
46 from .FvImageSection
import FvImageSection
47 from .DataSection
import DataSection
48 from .DepexSection
import DepexSection
49 from .CompressSection
import CompressSection
50 from .GuidSection
import GuidSection
51 from .Capsule
import EFI_CERT_TYPE_PKCS7_GUID
, EFI_CERT_TYPE_RSA2048_SHA256_GUID
, Capsule
52 from .CapsuleData
import CapsuleFfs
, CapsulePayload
, CapsuleFv
, CapsuleFd
, CapsuleAnyFile
, CapsuleAfile
53 from .RuleComplexFile
import RuleComplexFile
54 from .RuleSimpleFile
import RuleSimpleFile
55 from .EfiSection
import EfiSection
57 from .ComponentStatement
import ComponentStatement
58 from .OptionRom
import OPTIONROM
59 from .OptRomInfStatement
import OptRomInfStatement
, OverrideAttribs
60 from .OptRomFileStatement
import OptRomFileStatement
61 from .GenFdsGlobalVariable
import GenFdsGlobalVariable
65 T_CHAR_DOUBLE_QUOTE
= '\"'
66 T_CHAR_SINGLE_QUOTE
= '\''
69 SEPARATORS
= {TAB_EQUAL_SPLIT
, TAB_VALUE_SPLIT
, TAB_COMMA_SPLIT
, '{', '}'}
70 ALIGNMENTS
= {"Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K", "64K", "128K",
71 "256K", "512K", "1M", "2M", "4M", "8M", "16M"}
72 ALIGNMENT_NOAUTO
= ALIGNMENTS
- {"Auto"}
73 CR_LB_SET
= {T_CHAR_CR
, TAB_LINE_BREAK
}
75 RegionSizePattern
= compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
76 RegionSizeGuidPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*")
77 RegionOffsetPcdPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$")
78 ShortcutPcdPattern
= compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
79 BaseAddrValuePattern
= compile('^0[xX][0-9a-fA-F]+')
80 FileExtensionPattern
= compile(r
'([a-zA-Z][a-zA-Z0-9]*)')
81 TokenFindPattern
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
82 AllIncludeFileList
= []
84 # Get the closest parent
85 def GetParentAtLine (Line
):
86 for Profile
in AllIncludeFileList
:
87 if Profile
.IsLineInFile(Line
):
92 def IsValidInclude (File
, Line
):
93 for Profile
in AllIncludeFileList
:
94 if Profile
.IsLineInFile(Line
) and Profile
.FileName
== File
:
99 def GetRealFileLine (File
, Line
):
101 for Profile
in AllIncludeFileList
:
102 if Profile
.IsLineInFile(Line
):
103 return Profile
.GetLineInFile(Line
)
104 elif Line
>= Profile
.InsertStartLineNumber
and Profile
.Level
== 1:
105 InsertedLines
+= Profile
.GetTotalLines()
107 return (File
, Line
- InsertedLines
)
109 ## The exception class that used to report error messages when parsing FDF
111 # Currently the "ToolName" is set to be "FdfParser".
113 class Warning (Exception):
116 # @param self The object pointer
117 # @param Str The message to record
118 # @param File The FDF name
119 # @param Line The Line number that error occurs
121 def __init__(self
, Str
, File
= None, Line
= None):
122 FileLineTuple
= GetRealFileLine(File
, Line
)
123 self
.FileName
= FileLineTuple
[0]
124 self
.LineNumber
= FileLineTuple
[1]
125 self
.OriginalLineNumber
= Line
127 self
.ToolName
= 'FdfParser'
132 ## The Include file content class that used to record file data when parsing include file
134 # May raise Exception when opening file.
136 class IncludeFileProfile
:
139 # @param self The object pointer
140 # @param FileName The file that to be parsed
142 def __init__(self
, FileName
):
143 self
.FileName
= FileName
144 self
.FileLinesList
= []
146 with
open(FileName
, "rb", 0) as fsock
:
147 self
.FileLinesList
= fsock
.readlines()
148 for index
, line
in enumerate(self
.FileLinesList
):
149 if not line
.endswith(TAB_LINE_BREAK
):
150 self
.FileLinesList
[index
] += TAB_LINE_BREAK
152 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
154 self
.InsertStartLineNumber
= None
155 self
.InsertAdjust
= 0
156 self
.IncludeFileList
= []
157 self
.Level
= 1 # first level include file
159 def GetTotalLines(self
):
160 TotalLines
= self
.InsertAdjust
+ len(self
.FileLinesList
)
162 for Profile
in self
.IncludeFileList
:
163 TotalLines
+= Profile
.GetTotalLines()
167 def IsLineInFile(self
, Line
):
168 if Line
>= self
.InsertStartLineNumber
and Line
< self
.InsertStartLineNumber
+ self
.GetTotalLines():
173 def GetLineInFile(self
, Line
):
174 if not self
.IsLineInFile (Line
):
175 return (self
.FileName
, -1)
177 InsertedLines
= self
.InsertStartLineNumber
179 for Profile
in self
.IncludeFileList
:
180 if Profile
.IsLineInFile(Line
):
181 return Profile
.GetLineInFile(Line
)
182 elif Line
>= Profile
.InsertStartLineNumber
:
183 InsertedLines
+= Profile
.GetTotalLines()
185 return (self
.FileName
, Line
- InsertedLines
+ 1)
189 ## The FDF content class that used to record file data when parsing FDF
191 # May raise Exception when opening file.
196 # @param self The object pointer
197 # @param FileName The file that to be parsed
199 def __init__(self
, FileName
):
200 self
.FileLinesList
= []
202 with
open(FileName
, "rb", 0) as fsock
:
203 self
.FileLinesList
= fsock
.readlines()
206 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
208 self
.FileName
= FileName
209 self
.PcdDict
= OrderedDict()
210 self
.PcdLocalDict
= OrderedDict()
212 self
.InfDict
= {'ArchTBD':[]}
213 # ECC will use this Dict and List information
214 self
.PcdFileLineDict
= {}
215 self
.InfFileLineList
= []
218 self
.FdNameNotSet
= False
220 self
.CapsuleDict
= {}
224 self
.FmpPayloadDict
= {}
226 ## The syntax parser for FDF
228 # PreprocessFile method should be called prior to ParseFile
229 # CycleReferenceCheck method can detect cycles in FDF contents
231 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
232 # Get*** procedures mean these procedures will make judgement on current token only.
237 # @param self The object pointer
238 # @param FileName The file that to be parsed
240 def __init__(self
, FileName
):
241 self
.Profile
= FileProfile(FileName
)
242 self
.FileName
= FileName
243 self
.CurrentLineNumber
= 1
244 self
.CurrentOffsetWithinLine
= 0
245 self
.CurrentFdName
= None
246 self
.CurrentFvName
= None
248 self
._SkippedChars
= ""
249 GlobalData
.gFdfParser
= self
251 # Used to section info
252 self
._CurSection
= []
253 # Key: [section name, UI name, arch]
254 # Value: {MACRO_NAME: MACRO_VALUE}
255 self
._MacroDict
= tdict(True, 3)
256 self
._PcdDict
= OrderedDict()
258 self
._WipeOffArea
= []
259 if GenFdsGlobalVariable
.WorkSpaceDir
== '':
260 GenFdsGlobalVariable
.WorkSpaceDir
= os
.getenv("WORKSPACE")
262 ## _SkipWhiteSpace() method
264 # Skip white spaces from current char.
266 # @param self The object pointer
268 def _SkipWhiteSpace(self
):
269 while not self
._EndOfFile
():
270 if self
._CurrentChar
() in {TAB_PRINTCHAR_NUL
, T_CHAR_CR
, TAB_LINE_BREAK
, TAB_SPACE_SPLIT
, T_CHAR_TAB
}:
271 self
._SkippedChars
+= str(self
._CurrentChar
())
277 ## _EndOfFile() method
279 # Judge current buffer pos is at file end
281 # @param self The object pointer
282 # @retval True Current File buffer position is at file end
283 # @retval False Current File buffer position is NOT at file end
285 def _EndOfFile(self
):
286 NumberOfLines
= len(self
.Profile
.FileLinesList
)
287 SizeOfLastLine
= len(self
.Profile
.FileLinesList
[-1])
288 if self
.CurrentLineNumber
== NumberOfLines
and self
.CurrentOffsetWithinLine
>= SizeOfLastLine
- 1:
290 if self
.CurrentLineNumber
> NumberOfLines
:
294 ## _EndOfLine() method
296 # Judge current buffer pos is at line end
298 # @param self The object pointer
299 # @retval True Current File buffer position is at line end
300 # @retval False Current File buffer position is NOT at line end
302 def _EndOfLine(self
):
303 if self
.CurrentLineNumber
> len(self
.Profile
.FileLinesList
):
305 SizeOfCurrentLine
= len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
306 if self
.CurrentOffsetWithinLine
>= SizeOfCurrentLine
:
312 # Reset file data buffer to the initial state
314 # @param self The object pointer
315 # @param DestLine Optional new destination line number.
316 # @param DestOffset Optional new destination offset.
318 def Rewind(self
, DestLine
= 1, DestOffset
= 0):
319 self
.CurrentLineNumber
= DestLine
320 self
.CurrentOffsetWithinLine
= DestOffset
322 ## _UndoOneChar() method
324 # Go back one char in the file buffer
326 # @param self The object pointer
327 # @retval True Successfully go back one char
328 # @retval False Not able to go back one char as file beginning reached
330 def _UndoOneChar(self
):
331 if self
.CurrentLineNumber
== 1 and self
.CurrentOffsetWithinLine
== 0:
333 elif self
.CurrentOffsetWithinLine
== 0:
334 self
.CurrentLineNumber
-= 1
335 self
.CurrentOffsetWithinLine
= len(self
._CurrentLine
()) - 1
337 self
.CurrentOffsetWithinLine
-= 1
340 ## _GetOneChar() method
342 # Move forward one char in the file buffer
344 # @param self The object pointer
346 def _GetOneChar(self
):
347 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
348 self
.CurrentLineNumber
+= 1
349 self
.CurrentOffsetWithinLine
= 0
351 self
.CurrentOffsetWithinLine
+= 1
353 ## _CurrentChar() method
355 # Get the char pointed to by the file buffer pointer
357 # @param self The object pointer
358 # @retval Char Current char
360 def _CurrentChar(self
):
361 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
]
363 ## _NextChar() method
365 # Get the one char pass the char pointed to by the file buffer pointer
367 # @param self The object pointer
368 # @retval Char Next char
371 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
372 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
][0]
373 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
+ 1]
375 ## _SetCurrentCharValue() method
377 # Modify the value of current char
379 # @param self The object pointer
380 # @param Value The new value of current char
382 def _SetCurrentCharValue(self
, Value
):
383 self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
] = Value
385 ## _CurrentLine() method
387 # Get the list that contains current line contents
389 # @param self The object pointer
390 # @retval List current line contents
392 def _CurrentLine(self
):
393 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
395 def _StringToList(self
):
396 self
.Profile
.FileLinesList
= [list(s
) for s
in self
.Profile
.FileLinesList
]
397 if not self
.Profile
.FileLinesList
:
398 EdkLogger
.error('FdfParser', FILE_READ_FAILURE
, 'The file is empty!', File
=self
.FileName
)
399 self
.Profile
.FileLinesList
[-1].append(' ')
401 def _ReplaceFragment(self
, StartPos
, EndPos
, Value
= ' '):
402 if StartPos
[0] == EndPos
[0]:
404 while Offset
<= EndPos
[1]:
405 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
410 while self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] not in CR_LB_SET
:
411 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
415 while Line
< EndPos
[0]:
417 while self
.Profile
.FileLinesList
[Line
][Offset
] not in CR_LB_SET
:
418 self
.Profile
.FileLinesList
[Line
][Offset
] = Value
423 while Offset
<= EndPos
[1]:
424 self
.Profile
.FileLinesList
[EndPos
[0]][Offset
] = Value
427 def _SetMacroValue(self
, Macro
, Value
):
428 if not self
._CurSection
:
432 if not self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]:
433 self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]] = MacroDict
435 MacroDict
= self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]
436 MacroDict
[Macro
] = Value
438 def _GetMacroValue(self
, Macro
):
440 if Macro
in GlobalData
.gCommandLineDefines
:
441 return GlobalData
.gCommandLineDefines
[Macro
]
442 if Macro
in GlobalData
.gGlobalDefines
:
443 return GlobalData
.gGlobalDefines
[Macro
]
446 MacroDict
= self
._MacroDict
[
451 if MacroDict
and Macro
in MacroDict
:
452 return MacroDict
[Macro
]
455 if Macro
in GlobalData
.gPlatformDefines
:
456 return GlobalData
.gPlatformDefines
[Macro
]
459 def _SectionHeaderParser(self
, Section
):
461 # [FD.UiName]: use dummy instead if UI name is optional
464 # [Rule]: don't take rule section into account, macro is not allowed in this section
465 # [VTF.arch.UiName, arch]
466 # [OptionRom.DriverName]
467 self
._CurSection
= []
468 Section
= Section
.strip()[1:-1].upper().replace(' ', '').strip(TAB_SPLIT
)
469 ItemList
= Section
.split(TAB_SPLIT
)
471 if Item
== '' or Item
== 'RULE':
474 if Item
== TAB_COMMON_DEFINES
.upper():
475 self
._CurSection
= [TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
476 elif Item
== 'VTF' and len(ItemList
) == 3:
478 Pos
= UiName
.find(TAB_COMMA_SPLIT
)
480 UiName
= UiName
[:Pos
]
481 self
._CurSection
= ['VTF', UiName
, ItemList
[1]]
482 elif len(ItemList
) > 1:
483 self
._CurSection
= [ItemList
[0], ItemList
[1], TAB_COMMON
]
484 elif len(ItemList
) > 0:
485 self
._CurSection
= [ItemList
[0], 'DUMMY', TAB_COMMON
]
487 ## PreprocessFile() method
489 # Preprocess file contents, replace comments with spaces.
490 # In the end, rewind the file buffer pointer to the beginning
491 # BUGBUG: No !include statement processing contained in this procedure
492 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
494 # @param self The object pointer
496 def PreprocessFile(self
):
499 DoubleSlashComment
= False
501 # HashComment in quoted string " " is ignored.
504 while not self
._EndOfFile
():
506 if self
._CurrentChar
() == T_CHAR_DOUBLE_QUOTE
and not InComment
:
507 InString
= not InString
508 # meet new line, then no longer in a comment for // and '#'
509 if self
._CurrentChar
() == TAB_LINE_BREAK
:
510 self
.CurrentLineNumber
+= 1
511 self
.CurrentOffsetWithinLine
= 0
512 if InComment
and DoubleSlashComment
:
514 DoubleSlashComment
= False
515 if InComment
and HashComment
:
518 # check for */ comment end
519 elif InComment
and not DoubleSlashComment
and not HashComment
and self
._CurrentChar
() == T_CHAR_STAR
and self
._NextChar
() == TAB_BACK_SLASH
:
520 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
522 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
525 # set comments to spaces
527 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
529 # check for // comment
530 elif self
._CurrentChar
() == TAB_BACK_SLASH
and self
._NextChar
() == TAB_BACK_SLASH
and not self
._EndOfLine
():
532 DoubleSlashComment
= True
533 # check for '#' comment
534 elif self
._CurrentChar
() == TAB_COMMENT_SPLIT
and not self
._EndOfLine
() and not InString
:
537 # check for /* comment start
538 elif self
._CurrentChar
() == TAB_BACK_SLASH
and self
._NextChar
() == T_CHAR_STAR
:
539 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
541 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
547 # restore from ListOfList to ListOfString
548 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
551 ## PreprocessIncludeFile() method
553 # Preprocess file contents, replace !include statements with file contents.
554 # In the end, rewind the file buffer pointer to the beginning
556 # @param self The object pointer
558 def PreprocessIncludeFile(self
):
559 # nested include support
562 while self
._GetNextToken
():
564 if self
._Token
== TAB_DEFINE
:
565 if not self
._GetNextToken
():
566 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
568 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
569 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
570 Value
= self
._GetExpression
()
571 MacroDict
[Macro
] = Value
573 elif self
._Token
== TAB_INCLUDE
:
575 IncludeLine
= self
.CurrentLineNumber
576 IncludeOffset
= self
.CurrentOffsetWithinLine
- len(TAB_INCLUDE
)
577 if not self
._GetNextToken
():
578 raise Warning("expected include file name", self
.FileName
, self
.CurrentLineNumber
)
579 IncFileName
= self
._Token
581 StartPos
= IncFileName
.find('$(', PreIndex
)
582 EndPos
= IncFileName
.find(')', StartPos
+2)
583 while StartPos
!= -1 and EndPos
!= -1:
584 Macro
= IncFileName
[StartPos
+2: EndPos
]
585 MacroVal
= self
._GetMacroValue
(Macro
)
587 if Macro
in MacroDict
:
588 MacroVal
= MacroDict
[Macro
]
589 if MacroVal
is not None:
590 IncFileName
= IncFileName
.replace('$(' + Macro
+ ')', MacroVal
, 1)
591 if MacroVal
.find('$(') != -1:
594 PreIndex
= StartPos
+ len(MacroVal
)
596 raise Warning("The Macro %s is not defined" %Macro
, self
.FileName
, self
.CurrentLineNumber
)
597 StartPos
= IncFileName
.find('$(', PreIndex
)
598 EndPos
= IncFileName
.find(')', StartPos
+2)
600 IncludedFile
= NormPath(IncFileName
)
602 # First search the include file under the same directory as FDF file
604 IncludedFile1
= PathClass(IncludedFile
, os
.path
.dirname(self
.FileName
))
605 ErrorCode
= IncludedFile1
.Validate()[0]
608 # Then search the include file under the same directory as DSC file
611 if GenFdsGlobalVariable
.ActivePlatform
:
612 PlatformDir
= GenFdsGlobalVariable
.ActivePlatform
.Dir
613 elif GlobalData
.gActivePlatform
:
614 PlatformDir
= GlobalData
.gActivePlatform
.MetaFile
.Dir
615 IncludedFile1
= PathClass(IncludedFile
, PlatformDir
)
616 ErrorCode
= IncludedFile1
.Validate()[0]
619 # Also search file under the WORKSPACE directory
621 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
622 ErrorCode
= IncludedFile1
.Validate()[0]
624 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
),
625 self
.FileName
, self
.CurrentLineNumber
)
627 if not IsValidInclude (IncludedFile1
.Path
, self
.CurrentLineNumber
):
628 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1
.Path
), self
.FileName
, self
.CurrentLineNumber
)
630 IncFileProfile
= IncludeFileProfile(IncludedFile1
.Path
)
632 CurrentLine
= self
.CurrentLineNumber
633 CurrentOffset
= self
.CurrentOffsetWithinLine
634 # list index of the insertion, note that line number is 'CurrentLine + 1'
635 InsertAtLine
= CurrentLine
636 ParentProfile
= GetParentAtLine (CurrentLine
)
637 if ParentProfile
is not None:
638 ParentProfile
.IncludeFileList
.insert(0, IncFileProfile
)
639 IncFileProfile
.Level
= ParentProfile
.Level
+ 1
640 IncFileProfile
.InsertStartLineNumber
= InsertAtLine
+ 1
641 # deal with remaining portions after "!include filename", if exists.
642 if self
._GetNextToken
():
643 if self
.CurrentLineNumber
== CurrentLine
:
644 RemainingLine
= self
._CurrentLine
()[CurrentOffset
:]
645 self
.Profile
.FileLinesList
.insert(self
.CurrentLineNumber
, RemainingLine
)
646 IncFileProfile
.InsertAdjust
+= 1
647 self
.CurrentLineNumber
+= 1
648 self
.CurrentOffsetWithinLine
= 0
650 for Line
in IncFileProfile
.FileLinesList
:
651 self
.Profile
.FileLinesList
.insert(InsertAtLine
, Line
)
652 self
.CurrentLineNumber
+= 1
655 # reversely sorted to better determine error in file
656 AllIncludeFileList
.insert(0, IncFileProfile
)
658 # comment out the processed include file statement
659 TempList
= list(self
.Profile
.FileLinesList
[IncludeLine
- 1])
660 TempList
.insert(IncludeOffset
, TAB_COMMENT_SPLIT
)
661 self
.Profile
.FileLinesList
[IncludeLine
- 1] = ''.join(TempList
)
662 if Processed
: # Nested and back-to-back support
663 self
.Rewind(DestLine
= IncFileProfile
.InsertStartLineNumber
- 1)
669 def _GetIfListCurrentItemStat(IfList
):
679 ## PreprocessConditionalStatement() method
681 # Preprocess conditional statement.
682 # In the end, rewind the file buffer pointer to the beginning
684 # @param self The object pointer
686 def PreprocessConditionalStatement(self
):
687 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
691 while self
._GetNextToken
():
692 # Determine section name and the location dependent macro
693 if self
._GetIfListCurrentItemStat
(IfList
):
694 if self
._Token
.startswith(TAB_SECTION_START
):
696 if not self
._Token
.endswith(TAB_SECTION_END
):
697 self
._SkipToToken
(TAB_SECTION_END
)
698 Header
+= self
._SkippedChars
699 if Header
.find('$(') != -1:
700 raise Warning("macro cannot be used in section header", self
.FileName
, self
.CurrentLineNumber
)
701 self
._SectionHeaderParser
(Header
)
703 # Replace macros except in RULE section or out of section
704 elif self
._CurSection
and ReplacedLine
!= self
.CurrentLineNumber
:
705 ReplacedLine
= self
.CurrentLineNumber
707 CurLine
= self
.Profile
.FileLinesList
[ReplacedLine
- 1]
709 StartPos
= CurLine
.find('$(', PreIndex
)
710 EndPos
= CurLine
.find(')', StartPos
+2)
711 while StartPos
!= -1 and EndPos
!= -1 and self
._Token
not in {TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_IF
, TAB_ELSE_IF
}:
712 MacroName
= CurLine
[StartPos
+2: EndPos
]
713 MacorValue
= self
._GetMacroValue
(MacroName
)
714 if MacorValue
is not None:
715 CurLine
= CurLine
.replace('$(' + MacroName
+ ')', MacorValue
, 1)
716 if MacorValue
.find('$(') != -1:
719 PreIndex
= StartPos
+ len(MacorValue
)
721 PreIndex
= EndPos
+ 1
722 StartPos
= CurLine
.find('$(', PreIndex
)
723 EndPos
= CurLine
.find(')', StartPos
+2)
724 self
.Profile
.FileLinesList
[ReplacedLine
- 1] = CurLine
727 if self
._Token
== TAB_DEFINE
:
728 if self
._GetIfListCurrentItemStat
(IfList
):
729 if not self
._CurSection
:
730 raise Warning("macro cannot be defined in Rule section or out of section", self
.FileName
, self
.CurrentLineNumber
)
731 DefineLine
= self
.CurrentLineNumber
- 1
732 DefineOffset
= self
.CurrentOffsetWithinLine
- len(TAB_DEFINE
)
733 if not self
._GetNextToken
():
734 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
736 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
737 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
739 Value
= self
._GetExpression
()
740 self
._SetMacroValue
(Macro
, Value
)
741 self
._WipeOffArea
.append(((DefineLine
, DefineOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
742 elif self
._Token
== 'SET':
743 if not self
._GetIfListCurrentItemStat
(IfList
):
745 SetLine
= self
.CurrentLineNumber
- 1
746 SetOffset
= self
.CurrentOffsetWithinLine
- len('SET')
747 PcdPair
= self
._GetNextPcdSettings
()
748 PcdName
= "%s.%s" % (PcdPair
[1], PcdPair
[0])
749 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
750 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
752 Value
= self
._GetExpression
()
753 Value
= self
._EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
755 self
._PcdDict
[PcdName
] = Value
757 self
.Profile
.PcdDict
[PcdPair
] = Value
758 self
.SetPcdLocalation(PcdPair
)
759 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
760 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
762 self
._WipeOffArea
.append(((SetLine
, SetOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
763 elif self
._Token
in {TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_IF
}:
764 IfStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
._Token
))
765 IfList
.append([IfStartPos
, None, None])
767 CondLabel
= self
._Token
768 Expression
= self
._GetExpression
()
770 if CondLabel
== TAB_IF
:
771 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
773 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'in')
774 if CondLabel
== TAB_IF_N_DEF
:
775 ConditionSatisfied
= not ConditionSatisfied
777 BranchDetermined
= ConditionSatisfied
778 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, BranchDetermined
]
779 if ConditionSatisfied
:
780 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
781 elif self
._Token
in {TAB_ELSE_IF
, TAB_ELSE
}:
782 ElseStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
._Token
))
784 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
787 IfList
[-1] = [ElseStartPos
, False, True]
788 self
._WipeOffArea
.append((ElseStartPos
, (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
790 self
._WipeOffArea
.append((IfList
[-1][0], ElseStartPos
))
791 IfList
[-1] = [ElseStartPos
, True, IfList
[-1][2]]
792 if self
._Token
== TAB_ELSE_IF
:
793 Expression
= self
._GetExpression
()
794 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
795 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, IfList
[-1][2]]
799 IfList
[-1][1] = False
802 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
803 elif self
._Token
== '!endif':
805 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
807 self
._WipeOffArea
.append(((self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len('!endif')), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
809 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
812 elif not IfList
: # Don't use PCDs inside conditional directive
813 if self
.CurrentLineNumber
<= RegionLayoutLine
:
814 # Don't try the same line twice
816 SetPcd
= ShortcutPcdPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
818 self
._PcdDict
[SetPcd
.group('name')] = SetPcd
.group('value')
819 RegionLayoutLine
= self
.CurrentLineNumber
821 RegionSize
= RegionSizePattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
823 RegionLayoutLine
= self
.CurrentLineNumber
825 RegionSizeGuid
= RegionSizeGuidPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
])
826 if not RegionSizeGuid
:
827 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
829 self
._PcdDict
[RegionSizeGuid
.group('base')] = RegionSize
.group('base')
830 self
._PcdDict
[RegionSizeGuid
.group('size')] = RegionSize
.group('size')
831 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
834 raise Warning("Missing !endif", self
.FileName
, self
.CurrentLineNumber
)
837 def _CollectMacroPcd(self
):
841 MacroDict
.update(GlobalData
.gPlatformPcds
)
842 MacroDict
.update(self
._PcdDict
)
845 MacroDict
.update(GlobalData
.gPlatformDefines
)
849 ScopeMacro
= self
._MacroDict
[TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
851 MacroDict
.update(ScopeMacro
)
854 ScopeMacro
= self
._MacroDict
[
860 MacroDict
.update(ScopeMacro
)
862 MacroDict
.update(GlobalData
.gGlobalDefines
)
863 MacroDict
.update(GlobalData
.gCommandLineDefines
)
864 for Item
in GlobalData
.BuildOptionPcd
:
865 if isinstance(Item
, tuple):
867 PcdName
, TmpValue
= Item
.split(TAB_EQUAL_SPLIT
)
868 TmpValue
= BuildOptionValue(TmpValue
, {})
869 MacroDict
[PcdName
.strip()] = TmpValue
874 def _EvaluateConditional(self
, Expression
, Line
, Op
= None, Value
= None):
875 MacroPcdDict
= self
._CollectMacroPcd
()
879 return ValueExpression(Expression
, MacroPcdDict
)(True)
881 return ValueExpression(Expression
, MacroPcdDict
)()
882 except WrnExpression
as Excpt
:
884 # Catch expression evaluation warning here. We need to report
885 # the precise number of line and return the evaluation result
887 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
888 File
=self
.FileName
, ExtraData
=self
._CurrentLine
(),
891 except Exception as Excpt
:
892 if hasattr(Excpt
, 'Pcd'):
893 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
894 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
895 raise Warning("Cannot use this PCD (%s) in an expression as"
896 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
897 " of the DSC file (%s), and it is currently defined in this section:"
898 " %s, line #: %d." % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE'], Info
[0], Info
[1]),
901 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE']),
904 raise Warning(str(Excpt
), self
.FileName
, Line
)
906 if Expression
.startswith('$(') and Expression
[-1] == ')':
907 Expression
= Expression
[2:-1]
908 return Expression
in MacroPcdDict
912 # Check whether input string is found from current char position along
913 # If found, the string value is put into self._Token
915 # @param self The object pointer
916 # @param String The string to search
917 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
918 # @retval True Successfully find string, file buffer pointer moved forward
919 # @retval False Not able to find string, file buffer pointer not changed
921 def _IsToken(self
, String
, IgnoreCase
= False):
922 self
._SkipWhiteSpace
()
924 # Only consider the same line, no multi-line token allowed
925 StartPos
= self
.CurrentOffsetWithinLine
928 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
930 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
932 self
.CurrentOffsetWithinLine
+= len(String
)
933 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
937 ## _IsKeyword() method
939 # Check whether input keyword is found from current char position along, whole word only!
940 # If found, the string value is put into self._Token
942 # @param self The object pointer
943 # @param Keyword The string to search
944 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
945 # @retval True Successfully find string, file buffer pointer moved forward
946 # @retval False Not able to find string, file buffer pointer not changed
948 def _IsKeyword(self
, KeyWord
, IgnoreCase
= False):
949 self
._SkipWhiteSpace
()
951 # Only consider the same line, no multi-line token allowed
952 StartPos
= self
.CurrentOffsetWithinLine
955 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(KeyWord
.upper())
957 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(KeyWord
)
959 followingChar
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
+ len(KeyWord
)]
960 if not str(followingChar
).isspace() and followingChar
not in SEPARATORS
:
962 self
.CurrentOffsetWithinLine
+= len(KeyWord
)
963 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
967 def _GetExpression(self
):
968 Line
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
969 Index
= len(Line
) - 1
970 while Line
[Index
] in CR_LB_SET
:
972 ExpressionString
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:Index
+1]
973 self
.CurrentOffsetWithinLine
+= len(ExpressionString
)
974 ExpressionString
= ExpressionString
.strip()
975 return ExpressionString
977 ## _GetNextWord() method
979 # Get next C name from file lines
980 # If found, the string value is put into self._Token
982 # @param self The object pointer
983 # @retval True Successfully find a C name string, file buffer pointer moved forward
984 # @retval False Not able to find a C name string, file buffer pointer not changed
986 def _GetNextWord(self
):
987 self
._SkipWhiteSpace
()
988 if self
._EndOfFile
():
991 TempChar
= self
._CurrentChar
()
992 StartPos
= self
.CurrentOffsetWithinLine
993 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_':
995 while not self
._EndOfLine
():
996 TempChar
= self
._CurrentChar
()
997 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
998 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-':
1004 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1009 def _GetNextPcdWord(self
):
1010 self
._SkipWhiteSpace
()
1011 if self
._EndOfFile
():
1014 TempChar
= self
._CurrentChar
()
1015 StartPos
= self
.CurrentOffsetWithinLine
1016 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_' or TempChar
== TAB_SECTION_START
or TempChar
== TAB_SECTION_END
:
1018 while not self
._EndOfLine
():
1019 TempChar
= self
._CurrentChar
()
1020 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1021 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-' or TempChar
== TAB_SECTION_START
or TempChar
== TAB_SECTION_END
:
1027 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1032 ## _GetNextToken() method
1034 # Get next token unit before a seperator
1035 # If found, the string value is put into self._Token
1037 # @param self The object pointer
1038 # @retval True Successfully find a token unit, file buffer pointer moved forward
1039 # @retval False Not able to find a token unit, file buffer pointer not changed
1041 def _GetNextToken(self
):
1042 # Skip leading spaces, if exist.
1043 self
._SkipWhiteSpace
()
1044 if self
._EndOfFile
():
1046 # Record the token start position, the position of the first non-space char.
1047 StartPos
= self
.CurrentOffsetWithinLine
1048 StartLine
= self
.CurrentLineNumber
1049 while StartLine
== self
.CurrentLineNumber
:
1050 TempChar
= self
._CurrentChar
()
1051 # Try to find the end char that is not a space and not in seperator tuple.
1052 # That is, when we got a space or any char in the tuple, we got the end of token.
1053 if not str(TempChar
).isspace() and TempChar
not in SEPARATORS
:
1055 # if we happen to meet a seperator as the first char, we must proceed to get it.
1056 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1057 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPARATORS
:
1065 EndPos
= self
.CurrentOffsetWithinLine
1066 if self
.CurrentLineNumber
!= StartLine
:
1067 EndPos
= len(self
.Profile
.FileLinesList
[StartLine
-1])
1068 self
._Token
= self
.Profile
.FileLinesList
[StartLine
-1][StartPos
: EndPos
]
1069 if self
._Token
.lower() in {TAB_IF
, TAB_END_IF
, TAB_ELSE_IF
, TAB_ELSE
, TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_ERROR
, TAB_INCLUDE
}:
1070 self
._Token
= self
._Token
.lower()
1071 if StartPos
!= self
.CurrentOffsetWithinLine
:
1076 ## _GetNextGuid() method
1078 # Get next token unit before a seperator
1079 # If found, the GUID string is put into self._Token
1081 # @param self The object pointer
1082 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
1083 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
1085 def _GetNextGuid(self
):
1086 if not self
._GetNextToken
():
1088 if gGuidPattern
.match(self
._Token
) is not None:
1095 def _Verify(Name
, Value
, Scope
):
1096 # value verification only applies to numeric values.
1097 if Scope
not in TAB_PCD_NUMERIC_TYPES
:
1102 ValueNumber
= int(Value
, 0)
1104 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value is not valid dec or hex number for %s." % Name
)
1106 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value can't be set to negative value for %s." % Name
)
1107 if ValueNumber
> MAX_VAL_TYPE
[Scope
]:
1108 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "Too large value for %s." % Name
)
1111 ## _UndoToken() method
1113 # Go back one token unit in file buffer
1115 # @param self The object pointer
1117 def _UndoToken(self
):
1119 while self
._CurrentChar
().isspace():
1120 if not self
._UndoOneChar
():
1125 StartPos
= self
.CurrentOffsetWithinLine
1126 CurrentLine
= self
.CurrentLineNumber
1127 while CurrentLine
== self
.CurrentLineNumber
:
1129 TempChar
= self
._CurrentChar
()
1130 # Try to find the end char that is not a space and not in seperator tuple.
1131 # That is, when we got a space or any char in the tuple, we got the end of token.
1132 if not str(TempChar
).isspace() and not TempChar
in SEPARATORS
:
1133 if not self
._UndoOneChar
():
1135 # if we happen to meet a seperator as the first char, we must proceed to get it.
1136 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1137 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPARATORS
:
1144 ## _GetNextHexNumber() method
1146 # Get next HEX data before a seperator
1147 # If found, the HEX data is put into self._Token
1149 # @param self The object pointer
1150 # @retval True Successfully find a HEX data, file buffer pointer moved forward
1151 # @retval False Not able to find a HEX data, file buffer pointer not changed
1153 def _GetNextHexNumber(self
):
1154 if not self
._GetNextToken
():
1156 if gHexPatternAll
.match(self
._Token
):
1162 ## _GetNextDecimalNumber() method
1164 # Get next decimal data before a seperator
1165 # If found, the decimal data is put into self._Token
1167 # @param self The object pointer
1168 # @retval True Successfully find a decimal data, file buffer pointer moved forward
1169 # @retval False Not able to find a decimal data, file buffer pointer not changed
1171 def _GetNextDecimalNumber(self
):
1172 if not self
._GetNextToken
():
1174 if self
._Token
.isdigit():
1180 def _GetNextPcdSettings(self
):
1181 if not self
._GetNextWord
():
1182 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1183 pcdTokenSpaceCName
= self
._Token
1185 if not self
._IsToken
(TAB_SPLIT
):
1186 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1188 if not self
._GetNextWord
():
1189 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1190 pcdCName
= self
._Token
1193 while self
._IsToken
(TAB_SPLIT
):
1194 if not self
._GetNextPcdWord
():
1195 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1196 Fields
.append(self
._Token
)
1198 return (pcdCName
, pcdTokenSpaceCName
,TAB_SPLIT
.join(Fields
))
1200 ## _GetStringData() method
1202 # Get string contents quoted in ""
1203 # If found, the decimal data is put into self._Token
1205 # @param self The object pointer
1206 # @retval True Successfully find a string data, file buffer pointer moved forward
1207 # @retval False Not able to find a string data, file buffer pointer not changed
1209 def _GetStringData(self
):
1210 if self
._Token
.startswith(T_CHAR_DOUBLE_QUOTE
) or self
._Token
.startswith("L\""):
1212 self
._SkipToToken
(T_CHAR_DOUBLE_QUOTE
)
1213 currentLineNumber
= self
.CurrentLineNumber
1215 if not self
._SkipToToken
(T_CHAR_DOUBLE_QUOTE
):
1216 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1217 if currentLineNumber
!= self
.CurrentLineNumber
:
1218 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1219 self
._Token
= self
._SkippedChars
.rstrip(T_CHAR_DOUBLE_QUOTE
)
1222 elif self
._Token
.startswith(T_CHAR_SINGLE_QUOTE
) or self
._Token
.startswith("L\'"):
1224 self
._SkipToToken
(T_CHAR_SINGLE_QUOTE
)
1225 currentLineNumber
= self
.CurrentLineNumber
1227 if not self
._SkipToToken
(T_CHAR_SINGLE_QUOTE
):
1228 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1229 if currentLineNumber
!= self
.CurrentLineNumber
:
1230 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1231 self
._Token
= self
._SkippedChars
.rstrip(T_CHAR_SINGLE_QUOTE
)
1237 ## _SkipToToken() method
1239 # Search forward in file buffer for the string
1240 # The skipped chars are put into self._SkippedChars
1242 # @param self The object pointer
1243 # @param String The string to search
1244 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1245 # @retval True Successfully find the string, file buffer pointer moved forward
1246 # @retval False Not able to find the string, file buffer pointer not changed
1248 def _SkipToToken(self
, String
, IgnoreCase
= False):
1249 StartPos
= self
.GetFileBufferPos()
1251 self
._SkippedChars
= ""
1252 while not self
._EndOfFile
():
1255 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
1257 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
1259 self
.CurrentOffsetWithinLine
+= len(String
)
1260 self
._SkippedChars
+= String
1262 self
._SkippedChars
+= str(self
._CurrentChar
())
1265 self
.SetFileBufferPos(StartPos
)
1266 self
._SkippedChars
= ""
1269 ## GetFileBufferPos() method
1271 # Return the tuple of current line and offset within the line
1273 # @param self The object pointer
1274 # @retval Tuple Line number and offset pair
1276 def GetFileBufferPos(self
):
1277 return (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
)
1279 ## SetFileBufferPos() method
1281 # Restore the file buffer position
1283 # @param self The object pointer
1284 # @param Pos The new file buffer position
1286 def SetFileBufferPos(self
, Pos
):
1287 (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
) = Pos
1289 ## Preprocess() method
1291 # Preprocess comment, conditional directive, include directive, replace macro.
1292 # Exception will be raised if syntax error found
1294 # @param self The object pointer
1296 def Preprocess(self
):
1297 self
._StringToList
()
1298 self
.PreprocessFile()
1299 self
.PreprocessIncludeFile()
1300 self
._StringToList
()
1301 self
.PreprocessFile()
1302 self
.PreprocessConditionalStatement()
1303 self
._StringToList
()
1304 for Pos
in self
._WipeOffArea
:
1305 self
._ReplaceFragment
(Pos
[0], Pos
[1])
1306 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
1308 while self
._GetDefines
():
1311 ## ParseFile() method
1313 # Parse the file profile buffer to extract fd, fv ... information
1314 # Exception will be raised if syntax error found
1316 # @param self The object pointer
1318 def ParseFile(self
):
1323 # Keep processing sections of the FDF until no new sections or a syntax error is found
1325 while self
._GetFd
() or self
._GetFv
() or self
._GetFmp
() or self
._GetCapsule
() or self
._GetVtf
() or self
._GetRule
() or self
._GetOptionRom
():
1328 except Warning as X
:
1330 #'\n\tGot Token: \"%s\" from File %s\n' % (self._Token, FileLineTuple[0]) + \
1331 # At this point, the closest parent would be the included file itself
1332 Profile
= GetParentAtLine(X
.OriginalLineNumber
)
1333 if Profile
is not None:
1334 X
.Message
+= ' near line %d, column %d: %s' \
1335 % (X
.LineNumber
, 0, Profile
.FileLinesList
[X
.LineNumber
-1])
1337 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1338 X
.Message
+= ' near line %d, column %d: %s' \
1339 % (FileLineTuple
[1], self
.CurrentOffsetWithinLine
+ 1, self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:].rstrip(TAB_LINE_BREAK
).rstrip(T_CHAR_CR
))
1342 ## SectionParser() method
1344 # Parse the file section info
1345 # Exception will be raised if syntax error found
1347 # @param self The object pointer
1348 # @param section The section string
1350 def SectionParser(self
, section
):
1352 if not S
.startswith("[DEFINES") and not S
.startswith("[FD.") and not S
.startswith("[FV.") and not S
.startswith("[CAPSULE.") \
1353 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM.") and not S
.startswith('[FMPPAYLOAD.'):
1354 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self
.FileName
, self
.CurrentLineNumber
)
1356 ## _GetDefines() method
1358 # Get Defines section contents and store its data into AllMacrosList
1360 # @param self The object pointer
1361 # @retval True Successfully find a Defines
1362 # @retval False Not able to find a Defines
1364 def _GetDefines(self
):
1365 if not self
._GetNextToken
():
1368 S
= self
._Token
.upper()
1369 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[DEFINES"):
1370 self
.SectionParser(S
)
1375 if not self
._IsToken
("[DEFINES", True):
1376 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1377 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1378 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1379 raise Warning("expected [DEFINES", self
.FileName
, self
.CurrentLineNumber
)
1381 if not self
._IsToken
(TAB_SECTION_END
):
1382 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1384 while self
._GetNextWord
():
1385 # handle the SET statement
1386 if self
._Token
== 'SET':
1388 self
._GetSetStatement
(None)
1393 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1394 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1395 if not self
._GetNextToken
() or self
._Token
.startswith(TAB_SECTION_START
):
1396 raise Warning("expected MACRO value", self
.FileName
, self
.CurrentLineNumber
)
1401 ##_GetError() method
1402 def _GetError(self
):
1403 #save the Current information
1404 CurrentLine
= self
.CurrentLineNumber
1405 CurrentOffset
= self
.CurrentOffsetWithinLine
1406 while self
._GetNextToken
():
1407 if self
._Token
== TAB_ERROR
:
1408 EdkLogger
.error('FdfParser', ERROR_STATEMENT
, self
._CurrentLine
().replace(TAB_ERROR
, '', 1), File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
1409 self
.CurrentLineNumber
= CurrentLine
1410 self
.CurrentOffsetWithinLine
= CurrentOffset
1414 # Get FD section contents and store its data into FD dictionary of self.Profile
1416 # @param self The object pointer
1417 # @retval True Successfully find a FD
1418 # @retval False Not able to find a FD
1421 if not self
._GetNextToken
():
1424 S
= self
._Token
.upper()
1425 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FD."):
1426 if not S
.startswith("[FV.") and not S
.startswith('[FMPPAYLOAD.') and not S
.startswith("[CAPSULE.") \
1427 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM."):
1428 raise Warning("Unknown section", self
.FileName
, self
.CurrentLineNumber
)
1433 if not self
._IsToken
("[FD.", True):
1434 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1435 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1436 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1437 raise Warning("expected [FD.]", self
.FileName
, self
.CurrentLineNumber
)
1439 FdName
= self
._GetUiName
()
1441 if len (self
.Profile
.FdDict
) == 0:
1442 FdName
= GenFdsGlobalVariable
.PlatformName
1443 if FdName
== "" and GlobalData
.gActivePlatform
:
1444 FdName
= GlobalData
.gActivePlatform
.PlatformName
1445 self
.Profile
.FdNameNotSet
= True
1447 raise Warning("expected FdName in [FD.] section", self
.FileName
, self
.CurrentLineNumber
)
1448 self
.CurrentFdName
= FdName
.upper()
1450 if self
.CurrentFdName
in self
.Profile
.FdDict
:
1451 raise Warning("Unexpected the same FD name", self
.FileName
, self
.CurrentLineNumber
)
1453 if not self
._IsToken
(TAB_SECTION_END
):
1454 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1457 FdObj
.FdUiName
= self
.CurrentFdName
1458 self
.Profile
.FdDict
[self
.CurrentFdName
] = FdObj
1460 if len (self
.Profile
.FdDict
) > 1 and self
.Profile
.FdNameNotSet
:
1461 raise Warning("expected all FDs have their name", self
.FileName
, self
.CurrentLineNumber
)
1463 Status
= self
._GetCreateFile
(FdObj
)
1465 raise Warning("FD name error", self
.FileName
, self
.CurrentLineNumber
)
1467 while self
._GetTokenStatements
(FdObj
):
1469 for Attr
in ("BaseAddress", "Size", "ErasePolarity"):
1470 if getattr(FdObj
, Attr
) is None:
1471 self
._GetNextToken
()
1472 raise Warning("Keyword %s missing" % Attr
, self
.FileName
, self
.CurrentLineNumber
)
1474 if not FdObj
.BlockSizeList
:
1475 FdObj
.BlockSizeList
.append((1, FdObj
.Size
, None))
1477 self
._GetDefineStatements
(FdObj
)
1479 self
._GetSetStatements
(FdObj
)
1481 if not self
._GetRegionLayout
(FdObj
):
1482 raise Warning("expected region layout", self
.FileName
, self
.CurrentLineNumber
)
1484 while self
._GetRegionLayout
(FdObj
):
1488 ## _GetUiName() method
1490 # Return the UI name of a section
1492 # @param self The object pointer
1493 # @retval FdName UI name
1495 def _GetUiName(self
):
1497 if self
._GetNextWord
():
1502 ## _GetCreateFile() method
1504 # Return the output file name of object
1506 # @param self The object pointer
1507 # @param Obj object whose data will be stored in file
1508 # @retval FdName UI name
1510 def _GetCreateFile(self
, Obj
):
1511 if self
._IsKeyword
("CREATE_FILE"):
1512 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1513 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1515 if not self
._GetNextToken
():
1516 raise Warning("expected file name", self
.FileName
, self
.CurrentLineNumber
)
1518 FileName
= self
._Token
1519 Obj
.CreateFileName
= FileName
1523 def SetPcdLocalation(self
,pcdpair
):
1524 self
.Profile
.PcdLocalDict
[pcdpair
] = (self
.Profile
.FileName
,self
.CurrentLineNumber
)
1526 ## _GetTokenStatements() method
1528 # Get token statements
1530 # @param self The object pointer
1531 # @param Obj for whom token statement is got
1533 def _GetTokenStatements(self
, Obj
):
1534 if self
._IsKeyword
("BaseAddress"):
1535 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1536 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1538 if not self
._GetNextHexNumber
():
1539 raise Warning("expected Hex base address", self
.FileName
, self
.CurrentLineNumber
)
1541 Obj
.BaseAddress
= self
._Token
1543 if self
._IsToken
(TAB_VALUE_SPLIT
):
1544 pcdPair
= self
._GetNextPcdSettings
()
1545 Obj
.BaseAddressPcd
= pcdPair
1546 self
.Profile
.PcdDict
[pcdPair
] = Obj
.BaseAddress
1547 self
.SetPcdLocalation(pcdPair
)
1548 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1549 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1552 if self
._IsKeyword
("Size"):
1553 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1554 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1556 if not self
._GetNextHexNumber
():
1557 raise Warning("expected Hex size", self
.FileName
, self
.CurrentLineNumber
)
1560 if self
._IsToken
(TAB_VALUE_SPLIT
):
1561 pcdPair
= self
._GetNextPcdSettings
()
1562 Obj
.SizePcd
= pcdPair
1563 self
.Profile
.PcdDict
[pcdPair
] = Size
1564 self
.SetPcdLocalation(pcdPair
)
1565 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1566 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1567 Obj
.Size
= long(Size
, 0)
1570 if self
._IsKeyword
("ErasePolarity"):
1571 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1572 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1574 if not self
._GetNextToken
():
1575 raise Warning("expected Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1577 if self
._Token
!= "1" and self
._Token
!= "0":
1578 raise Warning("expected 1 or 0 Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1580 Obj
.ErasePolarity
= self
._Token
1583 return self
._GetBlockStatements
(Obj
)
1585 ## _GetAddressStatements() method
1587 # Get address statements
1589 # @param self The object pointer
1590 # @param Obj for whom address statement is got
1591 # @retval True Successfully find
1592 # @retval False Not able to find
1594 def _GetAddressStatements(self
, Obj
):
1595 if self
._IsKeyword
("BsBaseAddress"):
1596 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1597 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1599 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1600 raise Warning("expected address", self
.FileName
, self
.CurrentLineNumber
)
1602 BsAddress
= long(self
._Token
, 0)
1603 Obj
.BsBaseAddress
= BsAddress
1605 if self
._IsKeyword
("RtBaseAddress"):
1606 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1607 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1609 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1610 raise Warning("expected address", self
.FileName
, self
.CurrentLineNumber
)
1612 RtAddress
= long(self
._Token
, 0)
1613 Obj
.RtBaseAddress
= RtAddress
1615 ## _GetBlockStatements() method
1617 # Get block statements
1619 # @param self The object pointer
1620 # @param Obj for whom block statement is got
1622 def _GetBlockStatements(self
, Obj
):
1624 while self
._GetBlockStatement
(Obj
):
1627 Item
= Obj
.BlockSizeList
[-1]
1628 if Item
[0] is None or Item
[1] is None:
1629 raise Warning("expected block statement", self
.FileName
, self
.CurrentLineNumber
)
1632 ## _GetBlockStatement() method
1634 # Get block statement
1636 # @param self The object pointer
1637 # @param Obj for whom block statement is got
1638 # @retval True Successfully find
1639 # @retval False Not able to find
1641 def _GetBlockStatement(self
, Obj
):
1642 if not self
._IsKeyword
("BlockSize"):
1645 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1646 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1648 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
1649 raise Warning("expected Hex or Integer block size", self
.FileName
, self
.CurrentLineNumber
)
1651 BlockSize
= self
._Token
1653 if self
._IsToken
(TAB_VALUE_SPLIT
):
1654 PcdPair
= self
._GetNextPcdSettings
()
1655 BlockSizePcd
= PcdPair
1656 self
.Profile
.PcdDict
[PcdPair
] = BlockSize
1657 self
.SetPcdLocalation(PcdPair
)
1658 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1659 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1660 BlockSize
= long(BlockSize
, 0)
1663 if self
._IsKeyword
("NumBlocks"):
1664 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1665 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1667 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1668 raise Warning("expected block numbers", self
.FileName
, self
.CurrentLineNumber
)
1670 BlockNumber
= long(self
._Token
, 0)
1672 Obj
.BlockSizeList
.append((BlockSize
, BlockNumber
, BlockSizePcd
))
1675 ## _GetDefineStatements() method
1677 # Get define statements
1679 # @param self The object pointer
1680 # @param Obj for whom define statement is got
1681 # @retval True Successfully find
1682 # @retval False Not able to find
1684 def _GetDefineStatements(self
, Obj
):
1685 while self
._GetDefineStatement
(Obj
):
1688 ## _GetDefineStatement() method
1690 # Get define statement
1692 # @param self The object pointer
1693 # @param Obj for whom define statement is got
1694 # @retval True Successfully find
1695 # @retval False Not able to find
1697 def _GetDefineStatement(self
, Obj
):
1698 if self
._IsKeyword
(TAB_DEFINE
):
1699 self
._GetNextToken
()
1701 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1702 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1704 if not self
._GetNextToken
():
1705 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
1708 Macro
= '$(' + Macro
+ ')'
1709 Obj
.DefineVarDict
[Macro
] = Value
1714 ## _GetSetStatements() method
1716 # Get set statements
1718 # @param self The object pointer
1719 # @param Obj for whom set statement is got
1720 # @retval True Successfully find
1721 # @retval False Not able to find
1723 def _GetSetStatements(self
, Obj
):
1724 while self
._GetSetStatement
(Obj
):
1727 ## _GetSetStatement() method
1731 # @param self The object pointer
1732 # @param Obj for whom set statement is got
1733 # @retval True Successfully find
1734 # @retval False Not able to find
1736 def _GetSetStatement(self
, Obj
):
1737 if self
._IsKeyword
("SET"):
1738 PcdPair
= self
._GetNextPcdSettings
()
1740 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1741 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1743 Value
= self
._GetExpression
()
1744 Value
= self
._EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
1747 Obj
.SetVarDict
[PcdPair
] = Value
1748 self
.Profile
.PcdDict
[PcdPair
] = Value
1749 self
.SetPcdLocalation(PcdPair
)
1750 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1751 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1756 ## _CalcRegionExpr(self)
1758 # Calculate expression for offset or size of a region
1760 # @return: None if invalid expression
1761 # Calculated number if successfully
1763 def _CalcRegionExpr(self
):
1764 StartPos
= self
.GetFileBufferPos()
1767 while not self
._EndOfFile
():
1768 CurCh
= self
._CurrentChar
()
1774 if CurCh
in '|\r\n' and PairCount
== 0:
1780 ValueExpression(Expr
,
1781 self
._CollectMacroPcd
()
1784 self
.SetFileBufferPos(StartPos
)
1787 ## _GetRegionLayout() method
1789 # Get region layout for FD
1791 # @param self The object pointer
1792 # @param theFd for whom region is got
1793 # @retval True Successfully find
1794 # @retval False Not able to find
1796 def _GetRegionLayout(self
, theFd
):
1797 Offset
= self
._CalcRegionExpr
()
1801 RegionObj
= Region()
1802 RegionObj
.Offset
= Offset
1803 theFd
.RegionList
.append(RegionObj
)
1805 if not self
._IsToken
(TAB_VALUE_SPLIT
):
1806 raise Warning("expected '|'", self
.FileName
, self
.CurrentLineNumber
)
1808 Size
= self
._CalcRegionExpr
()
1810 raise Warning("expected Region Size", self
.FileName
, self
.CurrentLineNumber
)
1811 RegionObj
.Size
= Size
1813 if not self
._GetNextWord
():
1816 if not self
._Token
in {"SET", BINARY_FILE_TYPE_FV
, "FILE", "DATA", "CAPSULE", "INF"}:
1818 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1819 # Or it might be next region's offset described by an expression which starts with a PCD.
1820 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1823 IsRegionPcd
= (RegionSizeGuidPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]) or
1824 RegionOffsetPcdPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]))
1826 RegionObj
.PcdOffset
= self
._GetNextPcdSettings
()
1827 self
.Profile
.PcdDict
[RegionObj
.PcdOffset
] = "0x%08X" % (RegionObj
.Offset
+ long(theFd
.BaseAddress
, 0))
1828 self
.SetPcdLocalation(RegionObj
.PcdOffset
)
1829 self
._PcdDict
['%s.%s' % (RegionObj
.PcdOffset
[1], RegionObj
.PcdOffset
[0])] = "0x%x" % RegionObj
.Offset
1830 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1831 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdOffset
] = FileLineTuple
1832 if self
._IsToken
(TAB_VALUE_SPLIT
):
1833 RegionObj
.PcdSize
= self
._GetNextPcdSettings
()
1834 self
.Profile
.PcdDict
[RegionObj
.PcdSize
] = "0x%08X" % RegionObj
.Size
1835 self
.SetPcdLocalation(RegionObj
.PcdSize
)
1836 self
._PcdDict
['%s.%s' % (RegionObj
.PcdSize
[1], RegionObj
.PcdSize
[0])] = "0x%x" % RegionObj
.Size
1837 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1838 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdSize
] = FileLineTuple
1840 if not self
._GetNextWord
():
1843 if self
._Token
== "SET":
1845 self
._GetSetStatements
(RegionObj
)
1846 if not self
._GetNextWord
():
1849 elif self
._Token
== BINARY_FILE_TYPE_FV
:
1851 self
._GetRegionFvType
(RegionObj
)
1853 elif self
._Token
== "CAPSULE":
1855 self
._GetRegionCapType
(RegionObj
)
1857 elif self
._Token
== "FILE":
1859 self
._GetRegionFileType
(RegionObj
)
1861 elif self
._Token
== "INF":
1863 RegionObj
.RegionType
= "INF"
1864 while self
._IsKeyword
("INF"):
1866 ffsInf
= self
._ParseInfStatement
()
1869 RegionObj
.RegionDataList
.append(ffsInf
)
1871 elif self
._Token
== "DATA":
1873 self
._GetRegionDataType
(RegionObj
)
1876 if self
._GetRegionLayout
(theFd
):
1878 raise Warning("A valid region type was not found. "
1879 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
1880 self
.FileName
, self
.CurrentLineNumber
)
1884 ## _GetRegionFvType() method
1886 # Get region fv data for region
1888 # @param self The object pointer
1889 # @param RegionObj for whom region data is got
1891 def _GetRegionFvType(self
, RegionObj
):
1892 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1893 raise Warning("expected Keyword BINARY_FILE_TYPE_FV", self
.FileName
, self
.CurrentLineNumber
)
1895 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1896 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1898 if not self
._GetNextToken
():
1899 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1901 RegionObj
.RegionType
= BINARY_FILE_TYPE_FV
1902 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1904 while self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1906 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1907 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1909 if not self
._GetNextToken
():
1910 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1912 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1914 ## _GetRegionCapType() method
1916 # Get region capsule data for region
1918 # @param self The object pointer
1919 # @param RegionObj for whom region data is got
1921 def _GetRegionCapType(self
, RegionObj
):
1922 if not self
._IsKeyword
("CAPSULE"):
1923 raise Warning("expected Keyword 'CAPSULE'", self
.FileName
, self
.CurrentLineNumber
)
1925 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1926 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1928 if not self
._GetNextToken
():
1929 raise Warning("expected CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1931 RegionObj
.RegionType
= "CAPSULE"
1932 RegionObj
.RegionDataList
.append(self
._Token
)
1934 while self
._IsKeyword
("CAPSULE"):
1936 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1937 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1939 if not self
._GetNextToken
():
1940 raise Warning("expected CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1942 RegionObj
.RegionDataList
.append(self
._Token
)
1944 ## _GetRegionFileType() method
1946 # Get region file data for region
1948 # @param self The object pointer
1949 # @param RegionObj for whom region data is got
1951 def _GetRegionFileType(self
, RegionObj
):
1952 if not self
._IsKeyword
("FILE"):
1953 raise Warning("expected Keyword 'FILE'", self
.FileName
, self
.CurrentLineNumber
)
1955 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1956 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1958 if not self
._GetNextToken
():
1959 raise Warning("expected File name", self
.FileName
, self
.CurrentLineNumber
)
1961 RegionObj
.RegionType
= "FILE"
1962 RegionObj
.RegionDataList
.append(self
._Token
)
1964 while self
._IsKeyword
("FILE"):
1966 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1967 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1969 if not self
._GetNextToken
():
1970 raise Warning("expected FILE name", self
.FileName
, self
.CurrentLineNumber
)
1972 RegionObj
.RegionDataList
.append(self
._Token
)
1974 ## _GetRegionDataType() method
1976 # Get region array data for region
1978 # @param self The object pointer
1979 # @param RegionObj for whom region data is got
1981 def _GetRegionDataType(self
, RegionObj
):
1982 if not self
._IsKeyword
("DATA"):
1983 raise Warning("expected Region Data type", self
.FileName
, self
.CurrentLineNumber
)
1985 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1986 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1988 if not self
._IsToken
("{"):
1989 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
1991 if not self
._GetNextHexNumber
():
1992 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
1994 if len(self
._Token
) > 18:
1995 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
1997 # convert hex string value to byte hex string array
1998 AllString
= self
._Token
1999 AllStrLen
= len (AllString
)
2001 while AllStrLen
> 4:
2002 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
2003 AllStrLen
= AllStrLen
- 2
2004 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
2007 if len (self
._Token
) <= 4:
2008 while self
._IsToken
(TAB_COMMA_SPLIT
):
2009 if not self
._GetNextHexNumber
():
2010 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2011 if len(self
._Token
) > 4:
2012 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2013 DataString
+= self
._Token
2014 DataString
+= TAB_COMMA_SPLIT
2016 if not self
._IsToken
("}"):
2017 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2019 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2020 RegionObj
.RegionType
= "DATA"
2021 RegionObj
.RegionDataList
.append(DataString
)
2023 while self
._IsKeyword
("DATA"):
2025 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2026 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2028 if not self
._IsToken
("{"):
2029 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2031 if not self
._GetNextHexNumber
():
2032 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2034 if len(self
._Token
) > 18:
2035 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2037 # convert hex string value to byte hex string array
2038 AllString
= self
._Token
2039 AllStrLen
= len (AllString
)
2041 while AllStrLen
> 4:
2042 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
2043 AllStrLen
= AllStrLen
- 2
2044 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
2047 if len (self
._Token
) <= 4:
2048 while self
._IsToken
(TAB_COMMA_SPLIT
):
2049 if not self
._GetNextHexNumber
():
2050 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2051 if len(self
._Token
) > 4:
2052 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2053 DataString
+= self
._Token
2054 DataString
+= TAB_COMMA_SPLIT
2056 if not self
._IsToken
("}"):
2057 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2059 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2060 RegionObj
.RegionDataList
.append(DataString
)
2064 # Get FV section contents and store its data into FV dictionary of self.Profile
2066 # @param self The object pointer
2067 # @retval True Successfully find a FV
2068 # @retval False Not able to find a FV
2071 if not self
._GetNextToken
():
2074 S
= self
._Token
.upper()
2075 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FV."):
2076 self
.SectionParser(S
)
2081 if not self
._IsToken
("[FV.", True):
2082 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2083 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2084 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2085 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2087 FvName
= self
._GetUiName
()
2088 self
.CurrentFvName
= FvName
.upper()
2090 if not self
._IsToken
(TAB_SECTION_END
):
2091 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
2093 FvObj
= FV(Name
=self
.CurrentFvName
)
2094 self
.Profile
.FvDict
[self
.CurrentFvName
] = FvObj
2096 Status
= self
._GetCreateFile
(FvObj
)
2098 raise Warning("FV name error", self
.FileName
, self
.CurrentLineNumber
)
2100 self
._GetDefineStatements
(FvObj
)
2102 self
._GetAddressStatements
(FvObj
)
2105 self
._GetSetStatements
(FvObj
)
2107 if not (self
._GetBlockStatement
(FvObj
) or self
._GetFvBaseAddress
(FvObj
) or
2108 self
._GetFvForceRebase
(FvObj
) or self
._GetFvAlignment
(FvObj
) or
2109 self
._GetFvAttributes
(FvObj
) or self
._GetFvNameGuid
(FvObj
) or
2110 self
._GetFvExtEntryStatement
(FvObj
) or self
._GetFvNameString
(FvObj
)):
2113 if FvObj
.FvNameString
== 'TRUE' and not FvObj
.FvNameGuid
:
2114 raise Warning("FvNameString found but FvNameGuid was not found", self
.FileName
, self
.CurrentLineNumber
)
2116 self
._GetAprioriSection
(FvObj
)
2117 self
._GetAprioriSection
(FvObj
)
2120 isInf
= self
._GetInfStatement
(FvObj
)
2121 isFile
= self
._GetFileStatement
(FvObj
)
2122 if not isInf
and not isFile
:
2127 ## _GetFvAlignment() method
2129 # Get alignment for FV
2131 # @param self The object pointer
2132 # @param Obj for whom alignment is got
2133 # @retval True Successfully find a alignment statement
2134 # @retval False Not able to find a alignment statement
2136 def _GetFvAlignment(self
, Obj
):
2137 if not self
._IsKeyword
("FvAlignment"):
2140 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2141 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2143 if not self
._GetNextToken
():
2144 raise Warning("expected alignment value", self
.FileName
, self
.CurrentLineNumber
)
2146 if self
._Token
.upper() not in {"1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2147 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2148 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2150 raise Warning("Unknown alignment value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2151 Obj
.FvAlignment
= self
._Token
2154 ## _GetFvBaseAddress() method
2156 # Get BaseAddress for FV
2158 # @param self The object pointer
2159 # @param Obj for whom FvBaseAddress is got
2160 # @retval True Successfully find a FvBaseAddress statement
2161 # @retval False Not able to find a FvBaseAddress statement
2163 def _GetFvBaseAddress(self
, Obj
):
2164 if not self
._IsKeyword
("FvBaseAddress"):
2167 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2168 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2170 if not self
._GetNextToken
():
2171 raise Warning("expected FV base address value", self
.FileName
, self
.CurrentLineNumber
)
2173 if not BaseAddrValuePattern
.match(self
._Token
.upper()):
2174 raise Warning("Unknown FV base address value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2175 Obj
.FvBaseAddress
= self
._Token
2178 ## _GetFvForceRebase() method
2180 # Get FvForceRebase for FV
2182 # @param self The object pointer
2183 # @param Obj for whom FvForceRebase is got
2184 # @retval True Successfully find a FvForceRebase statement
2185 # @retval False Not able to find a FvForceRebase statement
2187 def _GetFvForceRebase(self
, Obj
):
2188 if not self
._IsKeyword
("FvForceRebase"):
2191 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2192 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2194 if not self
._GetNextToken
():
2195 raise Warning("expected FvForceRebase value", self
.FileName
, self
.CurrentLineNumber
)
2197 if self
._Token
.upper() not in {"TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"}:
2198 raise Warning("Unknown FvForceRebase value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2200 if self
._Token
.upper() in {"TRUE", "1", "0X1", "0X01"}:
2201 Obj
.FvForceRebase
= True
2202 elif self
._Token
.upper() in {"FALSE", "0", "0X0", "0X00"}:
2203 Obj
.FvForceRebase
= False
2205 Obj
.FvForceRebase
= None
2210 ## _GetFvAttributes() method
2212 # Get attributes for FV
2214 # @param self The object pointer
2215 # @param Obj for whom attribute is got
2218 def _GetFvAttributes(self
, FvObj
):
2220 while self
._GetNextWord
():
2223 if name
not in {"ERASE_POLARITY", "MEMORY_MAPPED", \
2224 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2225 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2226 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2227 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2228 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"}:
2232 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2233 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2235 if not self
._GetNextToken
() or self
._Token
.upper() not in {"TRUE", "FALSE", "1", "0"}:
2236 raise Warning("expected TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
2238 FvObj
.FvAttributeDict
[name
] = self
._Token
2242 ## _GetFvNameGuid() method
2244 # Get FV GUID for FV
2246 # @param self The object pointer
2247 # @param Obj for whom GUID is got
2250 def _GetFvNameGuid(self
, FvObj
):
2251 if not self
._IsKeyword
("FvNameGuid"):
2254 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2255 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2257 if not self
._GetNextGuid
():
2258 raise Warning("expected FV GUID value", self
.FileName
, self
.CurrentLineNumber
)
2260 FvObj
.FvNameGuid
= self
._Token
2264 def _GetFvNameString(self
, FvObj
):
2265 if not self
._IsKeyword
("FvNameString"):
2268 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2269 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2271 if not self
._GetNextToken
() or self
._Token
not in {'TRUE', 'FALSE'}:
2272 raise Warning("expected TRUE or FALSE for FvNameString", self
.FileName
, self
.CurrentLineNumber
)
2274 FvObj
.FvNameString
= self
._Token
2278 def _GetFvExtEntryStatement(self
, FvObj
):
2279 if not (self
._IsKeyword
("FV_EXT_ENTRY") or self
._IsKeyword
("FV_EXT_ENTRY_TYPE")):
2282 if not self
._IsKeyword
("TYPE"):
2283 raise Warning("expected 'TYPE'", self
.FileName
, self
.CurrentLineNumber
)
2285 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2286 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2288 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
2289 raise Warning("expected Hex FV extension entry type value At Line ", self
.FileName
, self
.CurrentLineNumber
)
2291 FvObj
.FvExtEntryTypeValue
.append(self
._Token
)
2293 if not self
._IsToken
("{"):
2294 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2296 if not self
._IsKeyword
("FILE") and not self
._IsKeyword
("DATA"):
2297 raise Warning("expected 'FILE' or 'DATA'", self
.FileName
, self
.CurrentLineNumber
)
2299 FvObj
.FvExtEntryType
.append(self
._Token
)
2301 if self
._Token
== 'DATA':
2303 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2304 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2306 if not self
._IsToken
("{"):
2307 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2309 if not self
._GetNextHexNumber
():
2310 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2312 if len(self
._Token
) > 4:
2313 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2315 DataString
= self
._Token
2316 DataString
+= TAB_COMMA_SPLIT
2318 while self
._IsToken
(TAB_COMMA_SPLIT
):
2319 if not self
._GetNextHexNumber
():
2320 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2321 if len(self
._Token
) > 4:
2322 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2323 DataString
+= self
._Token
2324 DataString
+= TAB_COMMA_SPLIT
2326 if not self
._IsToken
("}"):
2327 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2329 if not self
._IsToken
("}"):
2330 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2332 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2333 FvObj
.FvExtEntryData
.append(DataString
)
2335 if self
._Token
== 'FILE':
2337 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2338 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2340 if not self
._GetNextToken
():
2341 raise Warning("expected FV Extension Entry file path At Line ", self
.FileName
, self
.CurrentLineNumber
)
2343 FvObj
.FvExtEntryData
.append(self
._Token
)
2345 if not self
._IsToken
("}"):
2346 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2350 ## _GetAprioriSection() method
2352 # Get token statements
2354 # @param self The object pointer
2355 # @param FvObj for whom apriori is got
2356 # @retval True Successfully find apriori statement
2357 # @retval False Not able to find apriori statement
2359 def _GetAprioriSection(self
, FvObj
):
2360 if not self
._IsKeyword
("APRIORI"):
2363 if not self
._IsKeyword
("PEI") and not self
._IsKeyword
("DXE"):
2364 raise Warning("expected Apriori file type", self
.FileName
, self
.CurrentLineNumber
)
2365 AprType
= self
._Token
2367 if not self
._IsToken
("{"):
2368 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2370 AprSectionObj
= AprioriSection()
2371 AprSectionObj
.AprioriType
= AprType
2373 self
._GetDefineStatements
(AprSectionObj
)
2376 IsInf
= self
._GetInfStatement
(AprSectionObj
)
2377 IsFile
= self
._GetFileStatement
(AprSectionObj
)
2378 if not IsInf
and not IsFile
:
2381 if not self
._IsToken
("}"):
2382 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2384 FvObj
.AprioriSectionList
.append(AprSectionObj
)
2387 def _ParseInfStatement(self
):
2388 if not self
._IsKeyword
("INF"):
2391 ffsInf
= FfsInfStatement()
2392 self
._GetInfOptions
(ffsInf
)
2394 if not self
._GetNextToken
():
2395 raise Warning("expected INF file path", self
.FileName
, self
.CurrentLineNumber
)
2396 ffsInf
.InfFileName
= self
._Token
2397 if not ffsInf
.InfFileName
.endswith('.inf'):
2398 raise Warning("expected .inf file path", self
.FileName
, self
.CurrentLineNumber
)
2400 ffsInf
.CurrentLineNum
= self
.CurrentLineNumber
2401 ffsInf
.CurrentLineContent
= self
._CurrentLine
()
2403 #Replace $(SAPCE) with real space
2404 ffsInf
.InfFileName
= ffsInf
.InfFileName
.replace('$(SPACE)', ' ')
2406 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
2407 #do case sensitive check for file path
2408 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2410 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2412 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
2413 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
2414 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2415 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
2417 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
2418 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
2420 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
2422 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
2424 if self
._IsToken
(TAB_VALUE_SPLIT
):
2425 if self
._IsKeyword
('RELOCS_STRIPPED'):
2426 ffsInf
.KeepReloc
= False
2427 elif self
._IsKeyword
('RELOCS_RETAINED'):
2428 ffsInf
.KeepReloc
= True
2430 raise Warning("Unknown reloc strip flag '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2433 ## _GetInfStatement() method
2435 # Get INF statements
2437 # @param self The object pointer
2438 # @param Obj for whom inf statement is got
2439 # @retval True Successfully find inf statement
2440 # @retval False Not able to find inf statement
2442 def _GetInfStatement(self
, Obj
, ForCapsule
=False):
2443 ffsInf
= self
._ParseInfStatement
()
2448 myCapsuleFfs
= CapsuleFfs()
2449 myCapsuleFfs
.Ffs
= ffsInf
2450 Obj
.CapsuleDataList
.append(myCapsuleFfs
)
2452 Obj
.FfsList
.append(ffsInf
)
2455 ## _GetInfOptions() method
2457 # Get options for INF
2459 # @param self The object pointer
2460 # @param FfsInfObj for whom option is got
2462 def _GetInfOptions(self
, FfsInfObj
):
2463 if self
._IsKeyword
("FILE_GUID"):
2464 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2465 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2466 if not self
._GetNextGuid
():
2467 raise Warning("expected GUID value", self
.FileName
, self
.CurrentLineNumber
)
2468 FfsInfObj
.OverrideGuid
= self
._Token
2470 if self
._IsKeyword
("RuleOverride"):
2471 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2472 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2473 if not self
._GetNextToken
():
2474 raise Warning("expected Rule name", self
.FileName
, self
.CurrentLineNumber
)
2475 FfsInfObj
.Rule
= self
._Token
2477 if self
._IsKeyword
("VERSION"):
2478 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2479 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2480 if not self
._GetNextToken
():
2481 raise Warning("expected Version", self
.FileName
, self
.CurrentLineNumber
)
2483 if self
._GetStringData
():
2484 FfsInfObj
.Version
= self
._Token
2486 if self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2487 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2488 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2489 if not self
._GetNextToken
():
2490 raise Warning("expected UI name", self
.FileName
, self
.CurrentLineNumber
)
2492 if self
._GetStringData
():
2493 FfsInfObj
.Ui
= self
._Token
2495 if self
._IsKeyword
("USE"):
2496 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2497 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2498 if not self
._GetNextToken
():
2499 raise Warning("expected ARCH name", self
.FileName
, self
.CurrentLineNumber
)
2500 FfsInfObj
.UseArch
= self
._Token
2503 if self
._GetNextToken
():
2504 p
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2505 if p
.match(self
._Token
) and p
.match(self
._Token
).span()[1] == len(self
._Token
):
2506 FfsInfObj
.KeyStringList
.append(self
._Token
)
2507 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2513 while self
._GetNextToken
():
2514 if not p
.match(self
._Token
):
2515 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2516 FfsInfObj
.KeyStringList
.append(self
._Token
)
2518 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2521 ## _GetFileStatement() method
2523 # Get FILE statements
2525 # @param self The object pointer
2526 # @param Obj for whom FILE statement is got
2527 # @retval True Successfully find FILE statement
2528 # @retval False Not able to find FILE statement
2530 def _GetFileStatement(self
, Obj
, ForCapsule
= False):
2531 if not self
._IsKeyword
("FILE"):
2534 if not self
._GetNextWord
():
2535 raise Warning("expected FFS type", self
.FileName
, self
.CurrentLineNumber
)
2537 if ForCapsule
and self
._Token
== 'DATA':
2542 FfsFileObj
= FileStatement()
2543 FfsFileObj
.FvFileType
= self
._Token
2545 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2546 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2548 if not self
._GetNextGuid
():
2549 if not self
._GetNextWord
():
2550 raise Warning("expected File GUID", self
.FileName
, self
.CurrentLineNumber
)
2551 if self
._Token
== 'PCD':
2552 if not self
._IsToken
("("):
2553 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
2554 PcdPair
= self
._GetNextPcdSettings
()
2555 if not self
._IsToken
(")"):
2556 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
2557 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
2559 FfsFileObj
.NameGuid
= self
._Token
2561 self
._GetFilePart
(FfsFileObj
)
2564 capsuleFfs
= CapsuleFfs()
2565 capsuleFfs
.Ffs
= FfsFileObj
2566 Obj
.CapsuleDataList
.append(capsuleFfs
)
2568 Obj
.FfsList
.append(FfsFileObj
)
2572 ## _FileCouldHaveRelocFlag() method
2574 # Check whether reloc strip flag can be set for a file type.
2576 # @param FileType The file type to check with
2577 # @retval True This type could have relocation strip flag
2578 # @retval False No way to have it
2581 def _FileCouldHaveRelocFlag (FileType
):
2582 if FileType
in {SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
, 'PEI_DXE_COMBO'}:
2587 ## _SectionCouldHaveRelocFlag() method
2589 # Check whether reloc strip flag can be set for a section type.
2591 # @param SectionType The section type to check with
2592 # @retval True This type could have relocation strip flag
2593 # @retval False No way to have it
2596 def _SectionCouldHaveRelocFlag (SectionType
):
2597 if SectionType
in {BINARY_FILE_TYPE_TE
, BINARY_FILE_TYPE_PE32
}:
2602 ## _GetFilePart() method
2604 # Get components for FILE statement
2606 # @param self The object pointer
2607 # @param FfsFileObj for whom component is got
2609 def _GetFilePart(self
, FfsFileObj
):
2610 self
._GetFileOpts
(FfsFileObj
)
2612 if not self
._IsToken
("{"):
2613 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2614 if self
._FileCouldHaveRelocFlag
(FfsFileObj
.FvFileType
):
2615 if self
._Token
== 'RELOCS_STRIPPED':
2616 FfsFileObj
.KeepReloc
= False
2618 FfsFileObj
.KeepReloc
= True
2620 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj
.FvFileType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
2622 if not self
._IsToken
("{"):
2623 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2625 if not self
._GetNextToken
():
2626 raise Warning("expected File name or section data", self
.FileName
, self
.CurrentLineNumber
)
2628 if self
._Token
== BINARY_FILE_TYPE_FV
:
2629 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2630 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2631 if not self
._GetNextToken
():
2632 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
2633 FfsFileObj
.FvName
= self
._Token
2635 elif self
._Token
== "FD":
2636 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2637 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2638 if not self
._GetNextToken
():
2639 raise Warning("expected FD name", self
.FileName
, self
.CurrentLineNumber
)
2640 FfsFileObj
.FdName
= self
._Token
2642 elif self
._Token
in {TAB_DEFINE
, "APRIORI", "SECTION"}:
2644 self
._GetSectionData
(FfsFileObj
)
2646 elif hasattr(FfsFileObj
, 'FvFileType') and FfsFileObj
.FvFileType
== 'RAW':
2648 self
._GetRAWData
(FfsFileObj
)
2651 FfsFileObj
.CurrentLineNum
= self
.CurrentLineNumber
2652 FfsFileObj
.CurrentLineContent
= self
._CurrentLine
()
2653 FfsFileObj
.FileName
= self
._Token
.replace('$(SPACE)', ' ')
2654 self
._VerifyFile
(FfsFileObj
.FileName
)
2656 if not self
._IsToken
("}"):
2657 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2659 ## _GetRAWData() method
2661 # Get RAW data for FILE statement
2663 # @param self The object pointer
2664 # @param FfsFileObj for whom section is got
2666 def _GetRAWData(self
, FfsFileObj
):
2667 FfsFileObj
.FileName
= []
2668 FfsFileObj
.SubAlignment
= []
2671 if self
._GetAlignment
():
2672 if self
._Token
not in ALIGNMENTS
:
2673 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2674 #For FFS, Auto is default option same to ""
2675 if not self
._Token
== "Auto":
2676 AlignValue
= self
._Token
2677 if not self
._GetNextToken
():
2678 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2680 FileName
= self
._Token
.replace('$(SPACE)', ' ')
2683 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2685 self
._VerifyFile
(FileName
)
2686 File
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
)
2687 FfsFileObj
.FileName
.append(File
.Path
)
2688 FfsFileObj
.SubAlignment
.append(AlignValue
)
2690 if self
._IsToken
("}"):
2694 if len(FfsFileObj
.SubAlignment
) == 1:
2695 FfsFileObj
.SubAlignment
= FfsFileObj
.SubAlignment
[0]
2696 if len(FfsFileObj
.FileName
) == 1:
2697 FfsFileObj
.FileName
= FfsFileObj
.FileName
[0]
2699 ## _GetFileOpts() method
2701 # Get options for FILE statement
2703 # @param self The object pointer
2704 # @param FfsFileObj for whom options is got
2706 def _GetFileOpts(self
, FfsFileObj
):
2707 if self
._GetNextToken
():
2708 if TokenFindPattern
.match(self
._Token
):
2709 FfsFileObj
.KeyStringList
.append(self
._Token
)
2710 if self
._IsToken
(TAB_COMMA_SPLIT
):
2711 while self
._GetNextToken
():
2712 if not TokenFindPattern
.match(self
._Token
):
2713 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2714 FfsFileObj
.KeyStringList
.append(self
._Token
)
2716 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2722 if self
._IsKeyword
("FIXED", True):
2723 FfsFileObj
.Fixed
= True
2725 if self
._IsKeyword
("CHECKSUM", True):
2726 FfsFileObj
.CheckSum
= True
2728 if self
._GetAlignment
():
2729 if self
._Token
not in ALIGNMENTS
:
2730 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2731 #For FFS, Auto is default option same to ""
2732 if not self
._Token
== "Auto":
2733 FfsFileObj
.Alignment
= self
._Token
2735 ## _GetAlignment() method
2737 # Return the alignment value
2739 # @param self The object pointer
2740 # @retval True Successfully find alignment
2741 # @retval False Not able to find alignment
2743 def _GetAlignment(self
):
2744 if self
._IsKeyword
("Align", True):
2745 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2746 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2748 if not self
._GetNextToken
():
2749 raise Warning("expected alignment value", self
.FileName
, self
.CurrentLineNumber
)
2754 ## _GetSectionData() method
2756 # Get section data for FILE statement
2758 # @param self The object pointer
2759 # @param FfsFileObj for whom section is got
2761 def _GetSectionData(self
, FfsFileObj
):
2762 self
._GetDefineStatements
(FfsFileObj
)
2765 IsLeafSection
= self
._GetLeafSection
(FfsFileObj
)
2766 IsEncapSection
= self
._GetEncapsulationSec
(FfsFileObj
)
2767 if not IsLeafSection
and not IsEncapSection
:
2770 ## _GetLeafSection() method
2772 # Get leaf section for Obj
2774 # @param self The object pointer
2775 # @param Obj for whom leaf section is got
2776 # @retval True Successfully find section statement
2777 # @retval False Not able to find section statement
2779 def _GetLeafSection(self
, Obj
):
2780 OldPos
= self
.GetFileBufferPos()
2782 if not self
._IsKeyword
("SECTION"):
2783 if len(Obj
.SectionList
) == 0:
2784 raise Warning("expected SECTION", self
.FileName
, self
.CurrentLineNumber
)
2789 if self
._GetAlignment
():
2790 if self
._Token
not in ALIGNMENTS
:
2791 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2792 AlignValue
= self
._Token
2795 if self
._IsKeyword
("BUILD_NUM"):
2796 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2797 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2799 if not self
._GetNextToken
():
2800 raise Warning("expected Build number value", self
.FileName
, self
.CurrentLineNumber
)
2802 BuildNum
= self
._Token
2804 if self
._IsKeyword
("VERSION"):
2805 if AlignValue
== 'Auto':
2806 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2807 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2808 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2809 if not self
._GetNextToken
():
2810 raise Warning("expected version", self
.FileName
, self
.CurrentLineNumber
)
2811 VerSectionObj
= VerSection()
2812 VerSectionObj
.Alignment
= AlignValue
2813 VerSectionObj
.BuildNum
= BuildNum
2814 if self
._GetStringData
():
2815 VerSectionObj
.StringData
= self
._Token
2817 VerSectionObj
.FileName
= self
._Token
2818 Obj
.SectionList
.append(VerSectionObj
)
2820 elif self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2821 if AlignValue
== 'Auto':
2822 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2823 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2824 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2825 if not self
._GetNextToken
():
2826 raise Warning("expected UI", self
.FileName
, self
.CurrentLineNumber
)
2827 UiSectionObj
= UiSection()
2828 UiSectionObj
.Alignment
= AlignValue
2829 if self
._GetStringData
():
2830 UiSectionObj
.StringData
= self
._Token
2832 UiSectionObj
.FileName
= self
._Token
2833 Obj
.SectionList
.append(UiSectionObj
)
2835 elif self
._IsKeyword
("FV_IMAGE"):
2836 if AlignValue
== 'Auto':
2837 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2838 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2839 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2840 if not self
._GetNextToken
():
2841 raise Warning("expected FV name or FV file path", self
.FileName
, self
.CurrentLineNumber
)
2843 FvName
= self
._Token
2846 if self
._IsToken
("{"):
2848 FvObj
.UiFvName
= FvName
.upper()
2849 self
._GetDefineStatements
(FvObj
)
2851 self
._GetBlockStatement
(FvObj
)
2852 self
._GetSetStatements
(FvObj
)
2853 self
._GetFvAlignment
(FvObj
)
2854 self
._GetFvAttributes
(FvObj
)
2857 IsInf
= self
._GetInfStatement
(FvObj
)
2858 IsFile
= self
._GetFileStatement
(FvObj
)
2859 if not IsInf
and not IsFile
:
2862 if not self
._IsToken
("}"):
2863 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2865 FvImageSectionObj
= FvImageSection()
2866 FvImageSectionObj
.Alignment
= AlignValue
2867 if FvObj
is not None:
2868 FvImageSectionObj
.Fv
= FvObj
2869 FvImageSectionObj
.FvName
= None
2871 FvImageSectionObj
.FvName
= FvName
.upper()
2872 FvImageSectionObj
.FvFileName
= FvName
2874 Obj
.SectionList
.append(FvImageSectionObj
)
2876 elif self
._IsKeyword
("PEI_DEPEX_EXP") or self
._IsKeyword
("DXE_DEPEX_EXP") or self
._IsKeyword
("SMM_DEPEX_EXP"):
2877 if AlignValue
== 'Auto':
2878 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2879 DepexSectionObj
= DepexSection()
2880 DepexSectionObj
.Alignment
= AlignValue
2881 DepexSectionObj
.DepexType
= self
._Token
2883 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2884 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2885 if not self
._IsToken
("{"):
2886 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2887 if not self
._SkipToToken
("}"):
2888 raise Warning("expected Depex expression ending '}'", self
.FileName
, self
.CurrentLineNumber
)
2890 DepexSectionObj
.Expression
= self
._SkippedChars
.rstrip('}')
2891 Obj
.SectionList
.append(DepexSectionObj
)
2894 if not self
._GetNextWord
():
2895 raise Warning("expected section type", self
.FileName
, self
.CurrentLineNumber
)
2897 # Encapsulation section appear, UndoToken and return
2898 if self
._Token
== "COMPRESS" or self
._Token
== "GUIDED":
2899 self
.SetFileBufferPos(OldPos
)
2902 if self
._Token
not in {"COMPAT16", BINARY_FILE_TYPE_PE32
, BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,\
2903 BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX
}:
2904 raise Warning("Unknown section type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2905 if AlignValue
== 'Auto'and (not self
._Token
== BINARY_FILE_TYPE_PE32
) and (not self
._Token
== BINARY_FILE_TYPE_TE
):
2906 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2909 DataSectionObj
= DataSection()
2910 DataSectionObj
.Alignment
= AlignValue
2911 DataSectionObj
.SecType
= self
._Token
2913 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2914 if self
._FileCouldHaveRelocFlag
(Obj
.FvFileType
) and self
._SectionCouldHaveRelocFlag
(DataSectionObj
.SecType
):
2915 if self
._Token
== 'RELOCS_STRIPPED':
2916 DataSectionObj
.KeepReloc
= False
2918 DataSectionObj
.KeepReloc
= True
2920 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
)
2922 if self
._IsToken
(TAB_EQUAL_SPLIT
):
2923 if not self
._GetNextToken
():
2924 raise Warning("expected section file path", self
.FileName
, self
.CurrentLineNumber
)
2925 DataSectionObj
.SectFileName
= self
._Token
2926 self
._VerifyFile
(DataSectionObj
.SectFileName
)
2928 if not self
._GetCglSection
(DataSectionObj
):
2931 Obj
.SectionList
.append(DataSectionObj
)
2937 # Check if file exists or not:
2938 # If current phase if GenFds, the file must exist;
2939 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
2940 # @param FileName: File path to be verified.
2942 def _VerifyFile(self
, FileName
):
2943 if FileName
.replace(TAB_WORKSPACE
, '').find('$') != -1:
2945 if not GlobalData
.gAutoGenPhase
or not self
._GetMacroValue
(TAB_DSC_DEFINES_OUTPUT_DIRECTORY
) in FileName
:
2946 ErrorCode
, ErrorInfo
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2948 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2950 ## _GetCglSection() method
2952 # Get compressed or GUIDed section for Obj
2954 # @param self The object pointer
2955 # @param Obj for whom leaf section is got
2956 # @param AlignValue alignment value for complex section
2957 # @retval True Successfully find section statement
2958 # @retval False Not able to find section statement
2960 def _GetCglSection(self
, Obj
, AlignValue
= None):
2962 if self
._IsKeyword
("COMPRESS"):
2964 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
2967 if not self
._IsToken
("{"):
2968 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2970 CompressSectionObj
= CompressSection()
2971 CompressSectionObj
.Alignment
= AlignValue
2972 CompressSectionObj
.CompType
= type
2973 # Recursive sections...
2975 IsLeafSection
= self
._GetLeafSection
(CompressSectionObj
)
2976 IsEncapSection
= self
._GetEncapsulationSec
(CompressSectionObj
)
2977 if not IsLeafSection
and not IsEncapSection
:
2981 if not self
._IsToken
("}"):
2982 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2983 Obj
.SectionList
.append(CompressSectionObj
)
2986 # raise Warning("Compress type not known")
2990 elif self
._IsKeyword
("GUIDED"):
2992 if self
._GetNextGuid
():
2993 GuidValue
= self
._Token
2995 AttribDict
= self
._GetGuidAttrib
()
2996 if not self
._IsToken
("{"):
2997 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2998 GuidSectionObj
= GuidSection()
2999 GuidSectionObj
.Alignment
= AlignValue
3000 GuidSectionObj
.NameGuid
= GuidValue
3001 GuidSectionObj
.SectionType
= "GUIDED"
3002 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
3003 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
3004 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
3005 # Recursive sections...
3007 IsLeafSection
= self
._GetLeafSection
(GuidSectionObj
)
3008 IsEncapSection
= self
._GetEncapsulationSec
(GuidSectionObj
)
3009 if not IsLeafSection
and not IsEncapSection
:
3012 if not self
._IsToken
("}"):
3013 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3014 Obj
.SectionList
.append(GuidSectionObj
)
3020 ## _GetGuidAttri() method
3022 # Get attributes for GUID section
3024 # @param self The object pointer
3025 # @retval AttribDict Dictionary of key-value pair of section attributes
3027 def _GetGuidAttrib(self
):
3029 AttribDict
["PROCESSING_REQUIRED"] = "NONE"
3030 AttribDict
["AUTH_STATUS_VALID"] = "NONE"
3031 AttribDict
["EXTRA_HEADER_SIZE"] = -1
3032 while self
._IsKeyword
("PROCESSING_REQUIRED") or self
._IsKeyword
("AUTH_STATUS_VALID") \
3033 or self
._IsKeyword
("EXTRA_HEADER_SIZE"):
3034 AttribKey
= self
._Token
3036 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3037 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3039 if not self
._GetNextToken
():
3040 raise Warning("expected TRUE(1)/FALSE(0)/Number", self
.FileName
, self
.CurrentLineNumber
)
3041 elif AttribKey
== "EXTRA_HEADER_SIZE":
3043 if self
._Token
[0:2].upper() == "0X":
3046 AttribDict
[AttribKey
] = int(self
._Token
, Base
)
3049 raise Warning("expected Number", self
.FileName
, self
.CurrentLineNumber
)
3050 elif self
._Token
.upper() not in {"TRUE", "FALSE", "1", "0"}:
3051 raise Warning("expected TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
3052 AttribDict
[AttribKey
] = self
._Token
3056 ## _GetEncapsulationSec() method
3058 # Get encapsulation section for FILE
3060 # @param self The object pointer
3061 # @param FfsFile for whom section is got
3062 # @retval True Successfully find section statement
3063 # @retval False Not able to find section statement
3065 def _GetEncapsulationSec(self
, FfsFileObj
):
3066 OldPos
= self
.GetFileBufferPos()
3067 if not self
._IsKeyword
("SECTION"):
3068 if len(FfsFileObj
.SectionList
) == 0:
3069 raise Warning("expected SECTION", self
.FileName
, self
.CurrentLineNumber
)
3074 if self
._GetAlignment
():
3075 if self
._Token
not in ALIGNMENT_NOAUTO
:
3076 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3077 AlignValue
= self
._Token
3079 if not self
._GetCglSection
(FfsFileObj
, AlignValue
):
3080 self
.SetFileBufferPos(OldPos
)
3086 if not self
._GetNextToken
():
3088 S
= self
._Token
.upper()
3089 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FMPPAYLOAD."):
3090 self
.SectionParser(S
)
3095 self
._SkipToToken
("[FMPPAYLOAD.", True)
3096 FmpUiName
= self
._GetUiName
().upper()
3097 if FmpUiName
in self
.Profile
.FmpPayloadDict
:
3098 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName
, self
.FileName
, self
.CurrentLineNumber
)
3100 FmpData
= CapsulePayload()
3101 FmpData
.UiName
= FmpUiName
3103 if not self
._IsToken
(TAB_SECTION_END
):
3104 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
3106 if not self
._GetNextToken
():
3107 raise Warning("The FMP payload section is empty!", self
.FileName
, self
.CurrentLineNumber
)
3108 FmpKeyList
= ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']
3109 while self
._Token
in FmpKeyList
:
3111 FmpKeyList
.remove(Name
)
3112 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3113 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3114 if Name
== 'IMAGE_TYPE_ID':
3115 if not self
._GetNextGuid
():
3116 raise Warning("expected GUID value for IMAGE_TYPE_ID.", self
.FileName
, self
.CurrentLineNumber
)
3117 FmpData
.ImageTypeId
= self
._Token
3118 elif Name
== 'CERTIFICATE_GUID':
3119 if not self
._GetNextGuid
():
3120 raise Warning("expected GUID value for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3121 FmpData
.Certificate_Guid
= self
._Token
3122 if UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_RSA2048_SHA256_GUID
and UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_PKCS7_GUID
:
3123 raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3125 if not self
._GetNextToken
():
3126 raise Warning("expected value of %s" % Name
, self
.FileName
, self
.CurrentLineNumber
)
3128 if Name
== 'IMAGE_HEADER_INIT_VERSION':
3129 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3130 FmpData
.Version
= Value
3131 elif Name
== 'IMAGE_INDEX':
3132 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3133 FmpData
.ImageIndex
= Value
3134 elif Name
== 'HARDWARE_INSTANCE':
3135 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3136 FmpData
.HardwareInstance
= Value
3137 elif Name
== 'MONOTONIC_COUNT':
3138 if FdfParser
._Verify
(Name
, Value
, 'UINT64'):
3139 FmpData
.MonotonicCount
= Value
3140 if FmpData
.MonotonicCount
.upper().startswith('0X'):
3141 FmpData
.MonotonicCount
= (long)(FmpData
.MonotonicCount
, 16)
3143 FmpData
.MonotonicCount
= (long)(FmpData
.MonotonicCount
)
3144 if not self
._GetNextToken
():
3149 if (FmpData
.MonotonicCount
and not FmpData
.Certificate_Guid
) or (not FmpData
.MonotonicCount
and FmpData
.Certificate_Guid
):
3150 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")
3152 # Only the IMAGE_TYPE_ID is required item
3153 if FmpKeyList
and 'IMAGE_TYPE_ID' in FmpKeyList
:
3154 raise Warning("Missing keywords IMAGE_TYPE_ID in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3155 # get the Image file and Vendor code file
3156 self
._GetFMPCapsuleData
(FmpData
)
3157 if not FmpData
.ImageFile
:
3158 raise Warning("Missing image file in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3159 # check whether more than one Vendor code file
3160 if len(FmpData
.VendorCodeFile
) > 1:
3161 raise Warning("At most one Image file and one Vendor code file are allowed in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3162 self
.Profile
.FmpPayloadDict
[FmpUiName
] = FmpData
3165 ## _GetCapsule() method
3167 # Get capsule section contents and store its data into capsule list of self.Profile
3169 # @param self The object pointer
3170 # @retval True Successfully find a capsule
3171 # @retval False Not able to find a capsule
3173 def _GetCapsule(self
):
3174 if not self
._GetNextToken
():
3177 S
= self
._Token
.upper()
3178 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[CAPSULE."):
3179 self
.SectionParser(S
)
3184 if not self
._IsToken
("[CAPSULE.", True):
3185 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3186 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3187 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3188 raise Warning("expected [Capsule.]", self
.FileName
, self
.CurrentLineNumber
)
3190 CapsuleObj
= Capsule()
3192 CapsuleName
= self
._GetUiName
()
3194 raise Warning("expected capsule name", self
.FileName
, self
.CurrentLineNumber
)
3196 CapsuleObj
.UiCapsuleName
= CapsuleName
.upper()
3198 if not self
._IsToken
(TAB_SECTION_END
):
3199 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
3201 if self
._IsKeyword
("CREATE_FILE"):
3202 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3203 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3205 if not self
._GetNextToken
():
3206 raise Warning("expected file name", self
.FileName
, self
.CurrentLineNumber
)
3208 CapsuleObj
.CreateFile
= self
._Token
3210 self
._GetCapsuleStatements
(CapsuleObj
)
3211 self
.Profile
.CapsuleDict
[CapsuleObj
.UiCapsuleName
] = CapsuleObj
3214 ## _GetCapsuleStatements() method
3216 # Get statements for capsule
3218 # @param self The object pointer
3219 # @param Obj for whom statements are got
3221 def _GetCapsuleStatements(self
, Obj
):
3222 self
._GetCapsuleTokens
(Obj
)
3223 self
._GetDefineStatements
(Obj
)
3224 self
._GetSetStatements
(Obj
)
3225 self
._GetCapsuleData
(Obj
)
3227 ## _GetCapsuleTokens() method
3229 # Get token statements for capsule
3231 # @param self The object pointer
3232 # @param Obj for whom token statements are got
3234 def _GetCapsuleTokens(self
, Obj
):
3235 if not self
._GetNextToken
():
3237 while self
._Token
in {"CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"}:
3238 Name
= self
._Token
.strip()
3239 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3240 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3241 if not self
._GetNextToken
():
3242 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
3243 if Name
== 'CAPSULE_FLAGS':
3244 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3245 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3246 Value
= self
._Token
.strip()
3247 while self
._IsToken
(TAB_COMMA_SPLIT
):
3248 Value
+= TAB_COMMA_SPLIT
3249 if not self
._GetNextToken
():
3250 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
3251 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3252 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3253 Value
+= self
._Token
.strip()
3254 elif Name
== 'OEM_CAPSULE_FLAGS':
3255 Value
= self
._Token
.strip()
3256 if not Value
.upper().startswith('0X'):
3257 raise Warning("expected hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3259 Value
= int(Value
, 0)
3261 raise Warning("expected hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3262 if not 0x0000 <= Value
<= 0xFFFF:
3263 raise Warning("expected hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3264 Value
= self
._Token
.strip()
3266 Value
= self
._Token
.strip()
3267 Obj
.TokensDict
[Name
] = Value
3268 if not self
._GetNextToken
():
3272 ## _GetCapsuleData() method
3274 # Get capsule data for capsule
3276 # @param self The object pointer
3277 # @param Obj for whom capsule data are got
3279 def _GetCapsuleData(self
, Obj
):
3281 IsInf
= self
._GetInfStatement
(Obj
, True)
3282 IsFile
= self
._GetFileStatement
(Obj
, True)
3283 IsFv
= self
._GetFvStatement
(Obj
)
3284 IsFd
= self
._GetFdStatement
(Obj
)
3285 IsAnyFile
= self
._GetAnyFileStatement
(Obj
)
3286 IsAfile
= self
._GetAfileStatement
(Obj
)
3287 IsFmp
= self
._GetFmpStatement
(Obj
)
3288 if not (IsInf
or IsFile
or IsFv
or IsFd
or IsAnyFile
or IsAfile
or IsFmp
):
3291 ## _GetFMPCapsuleData() method
3293 # Get capsule data for FMP capsule
3295 # @param self The object pointer
3296 # @param Obj for whom capsule data are got
3298 def _GetFMPCapsuleData(self
, Obj
):
3300 IsFv
= self
._GetFvStatement
(Obj
, True)
3301 IsFd
= self
._GetFdStatement
(Obj
, True)
3302 IsAnyFile
= self
._GetAnyFileStatement
(Obj
, True)
3303 if not (IsFv
or IsFd
or IsAnyFile
):
3306 ## _GetFvStatement() method
3308 # Get FV for capsule
3310 # @param self The object pointer
3311 # @param CapsuleObj for whom FV is got
3312 # @retval True Successfully find a FV statement
3313 # @retval False Not able to find a FV statement
3315 def _GetFvStatement(self
, CapsuleObj
, FMPCapsule
= False):
3316 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3319 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3320 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3322 if not self
._GetNextToken
():
3323 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
3325 if self
._Token
.upper() not in self
.Profile
.FvDict
:
3326 raise Warning("FV name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3328 myCapsuleFv
= CapsuleFv()
3329 myCapsuleFv
.FvName
= self
._Token
3331 if not CapsuleObj
.ImageFile
:
3332 CapsuleObj
.ImageFile
.append(myCapsuleFv
)
3334 CapsuleObj
.VendorCodeFile
.append(myCapsuleFv
)
3336 CapsuleObj
.CapsuleDataList
.append(myCapsuleFv
)
3339 ## _GetFdStatement() method
3341 # Get FD for capsule
3343 # @param self The object pointer
3344 # @param CapsuleObj for whom FD is got
3345 # @retval True Successfully find a FD statement
3346 # @retval False Not able to find a FD statement
3348 def _GetFdStatement(self
, CapsuleObj
, FMPCapsule
= False):
3349 if not self
._IsKeyword
("FD"):
3352 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3353 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3355 if not self
._GetNextToken
():
3356 raise Warning("expected FD name", self
.FileName
, self
.CurrentLineNumber
)
3358 if self
._Token
.upper() not in self
.Profile
.FdDict
:
3359 raise Warning("FD name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3361 myCapsuleFd
= CapsuleFd()
3362 myCapsuleFd
.FdName
= self
._Token
3364 if not CapsuleObj
.ImageFile
:
3365 CapsuleObj
.ImageFile
.append(myCapsuleFd
)
3367 CapsuleObj
.VendorCodeFile
.append(myCapsuleFd
)
3369 CapsuleObj
.CapsuleDataList
.append(myCapsuleFd
)
3372 def _GetFmpStatement(self
, CapsuleObj
):
3373 if not self
._IsKeyword
("FMP_PAYLOAD"):
3374 if not self
._IsKeyword
("FMP"):
3377 if not self
._IsKeyword
("PAYLOAD"):
3381 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3382 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3384 if not self
._GetNextToken
():
3385 raise Warning("expected payload name after FMP_PAYLOAD =", self
.FileName
, self
.CurrentLineNumber
)
3386 Payload
= self
._Token
.upper()
3387 if Payload
not in self
.Profile
.FmpPayloadDict
:
3388 raise Warning("This FMP Payload does not exist: %s" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3389 CapsuleObj
.FmpPayloadList
.append(self
.Profile
.FmpPayloadDict
[Payload
])
3392 def _ParseRawFileStatement(self
):
3393 if not self
._IsKeyword
("FILE"):
3396 if not self
._IsKeyword
("DATA"):
3400 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3401 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3403 if not self
._GetNextToken
():
3404 raise Warning("expected File name", self
.FileName
, self
.CurrentLineNumber
)
3406 AnyFileName
= self
._Token
3407 self
._VerifyFile
(AnyFileName
)
3409 if not os
.path
.isabs(AnyFileName
):
3410 AnyFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, AnyFileName
)
3414 ## _GetAnyFileStatement() method
3416 # Get AnyFile for capsule
3418 # @param self The object pointer
3419 # @param CapsuleObj for whom AnyFile is got
3420 # @retval True Successfully find a Anyfile statement
3421 # @retval False Not able to find a AnyFile statement
3423 def _GetAnyFileStatement(self
, CapsuleObj
, FMPCapsule
= False):
3424 AnyFileName
= self
._ParseRawFileStatement
()
3428 myCapsuleAnyFile
= CapsuleAnyFile()
3429 myCapsuleAnyFile
.FileName
= AnyFileName
3431 if not CapsuleObj
.ImageFile
:
3432 CapsuleObj
.ImageFile
.append(myCapsuleAnyFile
)
3434 CapsuleObj
.VendorCodeFile
.append(myCapsuleAnyFile
)
3436 CapsuleObj
.CapsuleDataList
.append(myCapsuleAnyFile
)
3439 ## _GetAfileStatement() method
3441 # Get Afile for capsule
3443 # @param self The object pointer
3444 # @param CapsuleObj for whom Afile is got
3445 # @retval True Successfully find a Afile statement
3446 # @retval False Not able to find a Afile statement
3448 def _GetAfileStatement(self
, CapsuleObj
):
3449 if not self
._IsKeyword
("APPEND"):
3452 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3453 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3455 if not self
._GetNextToken
():
3456 raise Warning("expected Afile name", self
.FileName
, self
.CurrentLineNumber
)
3458 AfileName
= self
._Token
3459 AfileBaseName
= os
.path
.basename(AfileName
)
3461 if os
.path
.splitext(AfileBaseName
)[1] not in {".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"}:
3462 raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \
3463 self
.FileName
, self
.CurrentLineNumber
)
3465 if not os
.path
.isabs(AfileName
):
3466 AfileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(AfileName
)
3467 self
._VerifyFile
(AfileName
)
3469 if not os
.path
.exists(AfileName
):
3470 raise Warning('%s does not exist' % AfileName
, self
.FileName
, self
.CurrentLineNumber
)
3474 myCapsuleAfile
= CapsuleAfile()
3475 myCapsuleAfile
.FileName
= AfileName
3476 CapsuleObj
.CapsuleDataList
.append(myCapsuleAfile
)
3479 ## _GetRule() method
3481 # Get Rule section contents and store its data into rule list of self.Profile
3483 # @param self The object pointer
3484 # @retval True Successfully find a Rule
3485 # @retval False Not able to find a Rule
3488 if not self
._GetNextToken
():
3491 S
= self
._Token
.upper()
3492 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[RULE."):
3493 self
.SectionParser(S
)
3497 if not self
._IsToken
("[Rule.", True):
3498 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3499 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3500 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3501 raise Warning("expected [Rule.]", self
.FileName
, self
.CurrentLineNumber
)
3503 if not self
._SkipToToken
(TAB_SPLIT
):
3504 raise Warning("expected '.'", self
.FileName
, self
.CurrentLineNumber
)
3506 Arch
= self
._SkippedChars
.rstrip(TAB_SPLIT
)
3507 if Arch
.upper() not in ARCH_SET_FULL
:
3508 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
3510 ModuleType
= self
._GetModuleType
()
3513 if self
._IsToken
(TAB_SPLIT
):
3514 if not self
._GetNextWord
():
3515 raise Warning("expected template name", self
.FileName
, self
.CurrentLineNumber
)
3516 TemplateName
= self
._Token
3518 if not self
._IsToken
(TAB_SECTION_END
):
3519 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
3521 RuleObj
= self
._GetRuleFileStatements
()
3522 RuleObj
.Arch
= Arch
.upper()
3523 RuleObj
.ModuleType
= ModuleType
3524 RuleObj
.TemplateName
= TemplateName
3525 if TemplateName
== '':
3526 self
.Profile
.RuleDict
['RULE' + \
3530 ModuleType
.upper() ] = RuleObj
3532 self
.Profile
.RuleDict
['RULE' + \
3536 ModuleType
.upper() + \
3538 TemplateName
.upper() ] = RuleObj
3541 ## _GetModuleType() method
3543 # Return the module type
3545 # @param self The object pointer
3546 # @retval string module type
3548 def _GetModuleType(self
):
3549 if not self
._GetNextWord
():
3550 raise Warning("expected Module type", self
.FileName
, self
.CurrentLineNumber
)
3551 if self
._Token
.upper() not in {
3552 SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3553 SUP_MODULE_DXE_CORE
, SUP_MODULE_DXE_DRIVER
,
3554 SUP_MODULE_DXE_SAL_DRIVER
, SUP_MODULE_DXE_SMM_DRIVER
,
3555 SUP_MODULE_DXE_RUNTIME_DRIVER
, SUP_MODULE_UEFI_DRIVER
,
3556 SUP_MODULE_UEFI_APPLICATION
, SUP_MODULE_USER_DEFINED
,
3557 TAB_DEFAULT
, SUP_MODULE_BASE
,
3558 EDK_COMPONENT_TYPE_SECURITY_CORE
,
3559 EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER
,
3560 EDK_COMPONENT_TYPE_PIC_PEIM
,
3561 EDK_COMPONENT_TYPE_RELOCATABLE_PEIM
, "PE32_PEIM",
3562 EDK_COMPONENT_TYPE_BS_DRIVER
, EDK_COMPONENT_TYPE_RT_DRIVER
,
3563 EDK_COMPONENT_TYPE_SAL_RT_DRIVER
,
3564 EDK_COMPONENT_TYPE_APPLICATION
, "ACPITABLE",
3565 SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3566 SUP_MODULE_MM_CORE_STANDALONE
}:
3567 raise Warning("Unknown Module type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3570 ## _GetFileExtension() method
3572 # Return the file extension
3574 # @param self The object pointer
3575 # @retval string file name extension
3577 def _GetFileExtension(self
):
3578 if not self
._IsToken
(TAB_SPLIT
):
3579 raise Warning("expected '.'", self
.FileName
, self
.CurrentLineNumber
)
3582 if self
._GetNextToken
():
3583 if FileExtensionPattern
.match(self
._Token
):
3585 return TAB_SPLIT
+ Ext
3587 raise Warning("Unknown file extension '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3590 raise Warning("expected file extension", self
.FileName
, self
.CurrentLineNumber
)
3592 ## _GetRuleFileStatement() method
3596 # @param self The object pointer
3597 # @retval Rule Rule object
3599 def _GetRuleFileStatements(self
):
3600 if not self
._IsKeyword
("FILE"):
3601 raise Warning("expected FILE", self
.FileName
, self
.CurrentLineNumber
)
3603 if not self
._GetNextWord
():
3604 raise Warning("expected FFS type", self
.FileName
, self
.CurrentLineNumber
)
3606 Type
= self
._Token
.strip().upper()
3607 if Type
not in {"RAW", "FREEFORM", SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3608 "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE
, EDK_COMPONENT_TYPE_APPLICATION
,
3609 "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3610 SUP_MODULE_MM_CORE_STANDALONE
}:
3611 raise Warning("Unknown FV type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3613 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3614 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3616 if not self
._IsKeyword
("$(NAMED_GUID)"):
3617 if not self
._GetNextWord
():
3618 raise Warning("expected $(NAMED_GUID)", self
.FileName
, self
.CurrentLineNumber
)
3619 if self
._Token
== 'PCD':
3620 if not self
._IsToken
("("):
3621 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
3622 PcdPair
= self
._GetNextPcdSettings
()
3623 if not self
._IsToken
(")"):
3624 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
3625 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3627 NameGuid
= self
._Token
3630 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3631 if self
._FileCouldHaveRelocFlag
(Type
):
3632 if self
._Token
== 'RELOCS_STRIPPED':
3637 raise Warning("File type %s could not have reloc strip flag%d" % (Type
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3640 if self
._GetNextToken
():
3641 if TokenFindPattern
.match(self
._Token
):
3642 KeyStringList
.append(self
._Token
)
3643 if self
._IsToken
(TAB_COMMA_SPLIT
):
3644 while self
._GetNextToken
():
3645 if not TokenFindPattern
.match(self
._Token
):
3646 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
3647 KeyStringList
.append(self
._Token
)
3649 if not self
._IsToken
(TAB_COMMA_SPLIT
):
3657 if self
._IsKeyword
("Fixed", True):
3661 if self
._IsKeyword
("CheckSum", True):
3665 if self
._GetAlignment
():
3666 if self
._Token
not in ALIGNMENTS
:
3667 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3668 #For FFS, Auto is default option same to ""
3669 if not self
._Token
== "Auto":
3670 AlignValue
= self
._Token
3672 if self
._IsToken
("{"):
3673 # Complex file rule expected
3674 NewRule
= RuleComplexFile()
3675 NewRule
.FvFileType
= Type
3676 NewRule
.NameGuid
= NameGuid
3677 NewRule
.Alignment
= AlignValue
3678 NewRule
.CheckSum
= CheckSum
3679 NewRule
.Fixed
= Fixed
3680 NewRule
.KeyStringList
= KeyStringList
3681 if KeepReloc
is not None:
3682 NewRule
.KeepReloc
= KeepReloc
3685 IsEncapsulate
= self
._GetRuleEncapsulationSection
(NewRule
)
3686 IsLeaf
= self
._GetEfiSection
(NewRule
)
3687 if not IsEncapsulate
and not IsLeaf
:
3690 if not self
._IsToken
("}"):
3691 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3696 # Simple file rule expected
3697 if not self
._GetNextWord
():
3698 raise Warning("expected leaf section type", self
.FileName
, self
.CurrentLineNumber
)
3700 SectionName
= self
._Token
3702 if SectionName
not in {
3703 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3704 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3705 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3706 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3707 BINARY_FILE_TYPE_SMM_DEPEX
}:
3708 raise Warning("Unknown leaf section name '%s'" % SectionName
, self
.FileName
, self
.CurrentLineNumber
)
3711 if self
._IsKeyword
("Fixed", True):
3714 if self
._IsKeyword
("CheckSum", True):
3718 if self
._GetAlignment
():
3719 if self
._Token
not in ALIGNMENTS
:
3720 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3721 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3722 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3723 SectAlignment
= self
._Token
3726 if self
._IsToken
(TAB_VALUE_SPLIT
):
3727 Ext
= self
._GetFileExtension
()
3728 elif not self
._GetNextToken
():
3729 raise Warning("expected File name", self
.FileName
, self
.CurrentLineNumber
)
3731 NewRule
= RuleSimpleFile()
3732 NewRule
.SectionType
= SectionName
3733 NewRule
.FvFileType
= Type
3734 NewRule
.NameGuid
= NameGuid
3735 NewRule
.Alignment
= AlignValue
3736 NewRule
.SectAlignment
= SectAlignment
3737 NewRule
.CheckSum
= CheckSum
3738 NewRule
.Fixed
= Fixed
3739 NewRule
.KeyStringList
= KeyStringList
3740 if KeepReloc
is not None:
3741 NewRule
.KeepReloc
= KeepReloc
3742 NewRule
.FileExtension
= Ext
3743 NewRule
.FileName
= self
._Token
3746 ## _GetEfiSection() method
3748 # Get section list for Rule
3750 # @param self The object pointer
3751 # @param Obj for whom section is got
3752 # @retval True Successfully find section statement
3753 # @retval False Not able to find section statement
3755 def _GetEfiSection(self
, Obj
):
3756 OldPos
= self
.GetFileBufferPos()
3757 if not self
._GetNextWord
():
3759 SectionName
= self
._Token
3761 if SectionName
not in {
3762 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3763 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3764 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3765 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3766 BINARY_FILE_TYPE_SMM_DEPEX
, BINARY_FILE_TYPE_GUID
}:
3770 if SectionName
== "FV_IMAGE":
3771 FvImageSectionObj
= FvImageSection()
3772 if self
._IsKeyword
("FV_IMAGE"):
3774 if self
._IsToken
("{"):
3776 self
._GetDefineStatements
(FvObj
)
3777 self
._GetBlockStatement
(FvObj
)
3778 self
._GetSetStatements
(FvObj
)
3779 self
._GetFvAlignment
(FvObj
)
3780 self
._GetFvAttributes
(FvObj
)
3781 self
._GetAprioriSection
(FvObj
)
3782 self
._GetAprioriSection
(FvObj
)
3785 IsInf
= self
._GetInfStatement
(FvObj
)
3786 IsFile
= self
._GetFileStatement
(FvObj
)
3787 if not IsInf
and not IsFile
:
3790 if not self
._IsToken
("}"):
3791 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3792 FvImageSectionObj
.Fv
= FvObj
3793 FvImageSectionObj
.FvName
= None
3796 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3797 raise Warning("expected 'FV'", self
.FileName
, self
.CurrentLineNumber
)
3798 FvImageSectionObj
.FvFileType
= self
._Token
3800 if self
._GetAlignment
():
3801 if self
._Token
not in ALIGNMENT_NOAUTO
:
3802 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3803 FvImageSectionObj
.Alignment
= self
._Token
3805 if self
._IsToken
(TAB_VALUE_SPLIT
):
3806 FvImageSectionObj
.FvFileExtension
= self
._GetFileExtension
()
3807 elif self
._GetNextToken
():
3808 if self
._Token
not in {
3809 "}", "COMPAT16", BINARY_FILE_TYPE_PE32
,
3810 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3811 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3812 BINARY_FILE_TYPE_UI
, "VERSION",
3813 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3814 BINARY_FILE_TYPE_SMM_DEPEX
}:
3815 FvImageSectionObj
.FvFileName
= self
._Token
3819 raise Warning("expected FV file name", self
.FileName
, self
.CurrentLineNumber
)
3821 Obj
.SectionList
.append(FvImageSectionObj
)
3824 EfiSectionObj
= EfiSection()
3825 EfiSectionObj
.SectionType
= SectionName
3827 if not self
._GetNextToken
():
3828 raise Warning("expected file type", self
.FileName
, self
.CurrentLineNumber
)
3830 if self
._Token
== "STRING":
3831 if not self
._RuleSectionCouldHaveString
(EfiSectionObj
.SectionType
):
3832 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3834 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3835 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3837 if not self
._GetNextToken
():
3838 raise Warning("expected Quoted String", self
.FileName
, self
.CurrentLineNumber
)
3840 if self
._GetStringData
():
3841 EfiSectionObj
.StringData
= self
._Token
3843 if self
._IsKeyword
("BUILD_NUM"):
3844 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3845 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3847 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3848 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3849 if not self
._GetNextToken
():
3850 raise Warning("expected Build number", self
.FileName
, self
.CurrentLineNumber
)
3851 EfiSectionObj
.BuildNum
= self
._Token
3854 EfiSectionObj
.FileType
= self
._Token
3855 self
._CheckRuleSectionFileType
(EfiSectionObj
.SectionType
, EfiSectionObj
.FileType
)
3857 if self
._IsKeyword
("Optional"):
3858 if not self
._RuleSectionCouldBeOptional
(EfiSectionObj
.SectionType
):
3859 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3860 EfiSectionObj
.Optional
= True
3862 if self
._IsKeyword
("BUILD_NUM"):
3863 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3864 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3866 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3867 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3868 if not self
._GetNextToken
():
3869 raise Warning("expected Build number", self
.FileName
, self
.CurrentLineNumber
)
3870 EfiSectionObj
.BuildNum
= self
._Token
3872 if self
._GetAlignment
():
3873 if self
._Token
not in ALIGNMENTS
:
3874 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3875 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3876 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3877 EfiSectionObj
.Alignment
= self
._Token
3879 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3880 if self
._SectionCouldHaveRelocFlag
(EfiSectionObj
.SectionType
):
3881 if self
._Token
== 'RELOCS_STRIPPED':
3882 EfiSectionObj
.KeepReloc
= False
3884 EfiSectionObj
.KeepReloc
= True
3885 if Obj
.KeepReloc
is not None and Obj
.KeepReloc
!= EfiSectionObj
.KeepReloc
:
3886 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3888 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3891 if self
._IsToken
(TAB_VALUE_SPLIT
):
3892 EfiSectionObj
.FileExtension
= self
._GetFileExtension
()
3893 elif self
._GetNextToken
():
3894 if self
._Token
not in {
3895 "}", "COMPAT16", BINARY_FILE_TYPE_PE32
,
3896 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3897 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3898 BINARY_FILE_TYPE_UI
, "VERSION",
3899 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3900 BINARY_FILE_TYPE_SMM_DEPEX
}:
3902 if self
._Token
.startswith('PCD'):
3906 if self
._Token
== 'PCD':
3907 if not self
._IsToken
("("):
3908 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
3909 PcdPair
= self
._GetNextPcdSettings
()
3910 if not self
._IsToken
(")"):
3911 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
3912 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3914 EfiSectionObj
.FileName
= self
._Token
3919 raise Warning("expected section file name", self
.FileName
, self
.CurrentLineNumber
)
3921 Obj
.SectionList
.append(EfiSectionObj
)
3924 ## _RuleSectionCouldBeOptional() method
3926 # Get whether a section could be optional
3928 # @param SectionType The section type to check
3929 # @retval True section could be optional
3930 # @retval False section never optional
3933 def _RuleSectionCouldBeOptional(SectionType
):
3934 if SectionType
in {BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "RAW", BINARY_FILE_TYPE_SMM_DEPEX
}:
3939 ## _RuleSectionCouldHaveBuildNum() method
3941 # Get whether a section could have build number information
3943 # @param SectionType The section type to check
3944 # @retval True section could have build number information
3945 # @retval False section never have build number information
3948 def _RuleSectionCouldHaveBuildNum(SectionType
):
3949 if SectionType
== "VERSION":
3954 ## _RuleSectionCouldHaveString() method
3956 # Get whether a section could have string
3958 # @param SectionType The section type to check
3959 # @retval True section could have string
3960 # @retval False section never have string
3963 def _RuleSectionCouldHaveString(SectionType
):
3964 if SectionType
in {BINARY_FILE_TYPE_UI
, "VERSION"}:
3969 ## _CheckRuleSectionFileType() method
3971 # Get whether a section matches a file type
3973 # @param self The object pointer
3974 # @param SectionType The section type to check
3975 # @param FileType The file type to check
3977 def _CheckRuleSectionFileType(self
, SectionType
, FileType
):
3978 if SectionType
== "COMPAT16":
3979 if FileType
not in {"COMPAT16", "SEC_COMPAT16"}:
3980 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3981 elif SectionType
== BINARY_FILE_TYPE_PE32
:
3982 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_PE32"}:
3983 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3984 elif SectionType
== BINARY_FILE_TYPE_PIC
:
3985 if FileType
not in {BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_PIC
}:
3986 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3987 elif SectionType
== BINARY_FILE_TYPE_TE
:
3988 if FileType
not in {BINARY_FILE_TYPE_TE
, "SEC_TE"}:
3989 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3990 elif SectionType
== "RAW":
3991 if FileType
not in {BINARY_FILE_TYPE_BIN
, "SEC_BIN", "RAW", "ASL", "ACPI"}:
3992 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3993 elif SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
or SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
3994 if FileType
not in {BINARY_FILE_TYPE_DXE_DEPEX
, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX
}:
3995 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3996 elif SectionType
== BINARY_FILE_TYPE_UI
:
3997 if FileType
not in {BINARY_FILE_TYPE_UI
, "SEC_UI"}:
3998 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3999 elif SectionType
== "VERSION":
4000 if FileType
not in {"VERSION", "SEC_VERSION"}:
4001 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
4002 elif SectionType
== BINARY_FILE_TYPE_PEI_DEPEX
:
4003 if FileType
not in {BINARY_FILE_TYPE_PEI_DEPEX
, "SEC_PEI_DEPEX"}:
4004 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
4005 elif SectionType
== BINARY_FILE_TYPE_GUID
:
4006 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_GUID"}:
4007 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
4009 ## _GetRuleEncapsulationSection() method
4011 # Get encapsulation section for Rule
4013 # @param self The object pointer
4014 # @param theRule for whom section is got
4015 # @retval True Successfully find section statement
4016 # @retval False Not able to find section statement
4018 def _GetRuleEncapsulationSection(self
, theRule
):
4019 if self
._IsKeyword
("COMPRESS"):
4021 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
4024 if not self
._IsToken
("{"):
4025 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
4027 CompressSectionObj
= CompressSection()
4029 CompressSectionObj
.CompType
= Type
4030 # Recursive sections...
4032 IsEncapsulate
= self
._GetRuleEncapsulationSection
(CompressSectionObj
)
4033 IsLeaf
= self
._GetEfiSection
(CompressSectionObj
)
4034 if not IsEncapsulate
and not IsLeaf
:
4037 if not self
._IsToken
("}"):
4038 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
4039 theRule
.SectionList
.append(CompressSectionObj
)
4043 elif self
._IsKeyword
("GUIDED"):
4045 if self
._GetNextGuid
():
4046 GuidValue
= self
._Token
4048 if self
._IsKeyword
("$(NAMED_GUID)"):
4049 GuidValue
= self
._Token
4051 AttribDict
= self
._GetGuidAttrib
()
4053 if not self
._IsToken
("{"):
4054 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
4055 GuidSectionObj
= GuidSection()
4056 GuidSectionObj
.NameGuid
= GuidValue
4057 GuidSectionObj
.SectionType
= "GUIDED"
4058 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
4059 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
4060 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
4064 IsEncapsulate
= self
._GetRuleEncapsulationSection
(GuidSectionObj
)
4065 IsLeaf
= self
._GetEfiSection
(GuidSectionObj
)
4066 if not IsEncapsulate
and not IsLeaf
:
4069 if not self
._IsToken
("}"):
4070 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
4071 theRule
.SectionList
.append(GuidSectionObj
)
4079 # Get VTF section contents and store its data into VTF list of self.Profile
4081 # @param self The object pointer
4082 # @retval True Successfully find a VTF
4083 # @retval False Not able to find a VTF
4086 HW_ARCH_SET
= {TAB_ARCH_IA32
, TAB_ARCH_X64
, TAB_ARCH_IPF
, TAB_ARCH_ARM
, TAB_ARCH_AARCH64
}
4087 if not self
._GetNextToken
():
4090 S
= self
._Token
.upper()
4091 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[VTF."):
4092 self
.SectionParser(S
)
4097 if not self
._IsToken
("[VTF.", True):
4098 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4099 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
4100 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
4101 raise Warning("expected [VTF.]", self
.FileName
, self
.CurrentLineNumber
)
4103 if not self
._SkipToToken
(TAB_SPLIT
):
4104 raise Warning("expected '.'", self
.FileName
, self
.CurrentLineNumber
)
4106 Arch
= self
._SkippedChars
.rstrip(TAB_SPLIT
).upper()
4107 if Arch
not in HW_ARCH_SET
:
4108 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
4110 if not self
._GetNextWord
():
4111 raise Warning("expected VTF name", self
.FileName
, self
.CurrentLineNumber
)
4112 Name
= self
._Token
.upper()
4115 VtfObj
.UiName
= Name
4116 VtfObj
.KeyArch
= Arch
4118 if self
._IsToken
(TAB_COMMA_SPLIT
):
4119 if not self
._GetNextWord
():
4120 raise Warning("expected Arch list", self
.FileName
, self
.CurrentLineNumber
)
4121 if self
._Token
.upper() not in HW_ARCH_SET
:
4122 raise Warning("Unknown Arch '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4123 VtfObj
.ArchList
= self
._Token
.upper()
4125 if not self
._IsToken
(TAB_SECTION_END
):
4126 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
4128 if self
._IsKeyword
("IA32_RST_BIN"):
4129 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4130 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4132 if not self
._GetNextToken
():
4133 raise Warning("expected Reset file", self
.FileName
, self
.CurrentLineNumber
)
4135 VtfObj
.ResetBin
= self
._Token
4136 if VtfObj
.ResetBin
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4137 #check for file path
4138 ErrorCode
, ErrorInfo
= PathClass(NormPath(VtfObj
.ResetBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4140 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4142 while self
._GetComponentStatement
(VtfObj
):
4145 self
.Profile
.VtfList
.append(VtfObj
)
4148 ## _GetComponentStatement() method
4150 # Get components in VTF
4152 # @param self The object pointer
4153 # @param VtfObj for whom component is got
4154 # @retval True Successfully find a component
4155 # @retval False Not able to find a component
4157 def _GetComponentStatement(self
, VtfObj
):
4158 if not self
._IsKeyword
("COMP_NAME"):
4161 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4162 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4164 if not self
._GetNextWord
():
4165 raise Warning("expected Component Name", self
.FileName
, self
.CurrentLineNumber
)
4167 CompStatementObj
= ComponentStatement()
4168 CompStatementObj
.CompName
= self
._Token
4170 if not self
._IsKeyword
("COMP_LOC"):
4171 raise Warning("expected COMP_LOC", self
.FileName
, self
.CurrentLineNumber
)
4173 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4174 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4176 CompStatementObj
.CompLoc
= ""
4177 if self
._GetNextWord
():
4178 CompStatementObj
.CompLoc
= self
._Token
4179 if self
._IsToken
(TAB_VALUE_SPLIT
):
4180 if not self
._GetNextWord
():
4181 raise Warning("Expected Region Name", self
.FileName
, self
.CurrentLineNumber
)
4183 if self
._Token
not in {"F", "N", "S"}: #, "H", "L", "PH", "PL"): not support
4184 raise Warning("Unknown location type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4186 CompStatementObj
.FilePos
= self
._Token
4188 self
.CurrentLineNumber
+= 1
4189 self
.CurrentOffsetWithinLine
= 0
4191 if not self
._IsKeyword
("COMP_TYPE"):
4192 raise Warning("expected COMP_TYPE", self
.FileName
, self
.CurrentLineNumber
)
4194 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4195 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4197 if not self
._GetNextToken
():
4198 raise Warning("expected Component type", self
.FileName
, self
.CurrentLineNumber
)
4199 if self
._Token
not in {"FIT", "PAL_B", "PAL_A", "OEM"}:
4200 if not self
._Token
.startswith("0x") or len(self
._Token
) < 3 or len(self
._Token
) > 4 or \
4201 not self
._Token
[2] in hexdigits
or not self
._Token
[-1] in hexdigits
:
4202 raise Warning("Unknown location type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4203 CompStatementObj
.CompType
= self
._Token
4205 if not self
._IsKeyword
("COMP_VER"):
4206 raise Warning("expected COMP_VER", self
.FileName
, self
.CurrentLineNumber
)
4208 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4209 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4211 if not self
._GetNextToken
():
4212 raise Warning("expected Component version", self
.FileName
, self
.CurrentLineNumber
)
4214 Pattern
= compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', DOTALL
)
4215 if Pattern
.match(self
._Token
) is None:
4216 raise Warning("Unknown version format '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4217 CompStatementObj
.CompVer
= self
._Token
4219 if not self
._IsKeyword
("COMP_CS"):
4220 raise Warning("expected COMP_CS", self
.FileName
, self
.CurrentLineNumber
)
4222 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4223 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4225 if not self
._GetNextToken
():
4226 raise Warning("expected Component CS", self
.FileName
, self
.CurrentLineNumber
)
4227 if self
._Token
not in {"1", "0"}:
4228 raise Warning("Unknown Component CS '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4229 CompStatementObj
.CompCs
= self
._Token
4232 if not self
._IsKeyword
("COMP_BIN"):
4233 raise Warning("expected COMP_BIN", self
.FileName
, self
.CurrentLineNumber
)
4235 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4236 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4238 if not self
._GetNextToken
():
4239 raise Warning("expected Component file", self
.FileName
, self
.CurrentLineNumber
)
4241 CompStatementObj
.CompBin
= self
._Token
4242 if CompStatementObj
.CompBin
!= '-' and CompStatementObj
.CompBin
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4243 #check for file path
4244 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4246 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4248 if not self
._IsKeyword
("COMP_SYM"):
4249 raise Warning("expected COMP_SYM", self
.FileName
, self
.CurrentLineNumber
)
4251 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4252 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4254 if not self
._GetNextToken
():
4255 raise Warning("expected Component symbol file", self
.FileName
, self
.CurrentLineNumber
)
4257 CompStatementObj
.CompSym
= self
._Token
4258 if CompStatementObj
.CompSym
!= '-' and CompStatementObj
.CompSym
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4259 #check for file path
4260 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompSym
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4262 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4264 if not self
._IsKeyword
("COMP_SIZE"):
4265 raise Warning("expected COMP_SIZE", self
.FileName
, self
.CurrentLineNumber
)
4267 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4268 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4270 if self
._IsToken
("-"):
4271 CompStatementObj
.CompSize
= self
._Token
4272 elif self
._GetNextDecimalNumber
():
4273 CompStatementObj
.CompSize
= self
._Token
4274 elif self
._GetNextHexNumber
():
4275 CompStatementObj
.CompSize
= self
._Token
4277 raise Warning("Unknown size '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4279 VtfObj
.ComponentStatementList
.append(CompStatementObj
)
4282 ## _GetOptionRom() method
4284 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
4286 # @param self The object pointer
4287 # @retval True Successfully find a OptionROM
4288 # @retval False Not able to find a OptionROM
4290 def _GetOptionRom(self
):
4291 if not self
._GetNextToken
():
4294 S
= self
._Token
.upper()
4295 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[OPTIONROM."):
4296 self
.SectionParser(S
)
4301 if not self
._IsToken
("[OptionRom.", True):
4302 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4304 OptRomName
= self
._GetUiName
()
4306 if not self
._IsToken
(TAB_SECTION_END
):
4307 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
4309 OptRomObj
= OPTIONROM(OptRomName
)
4310 self
.Profile
.OptRomDict
[OptRomName
] = OptRomObj
4313 isInf
= self
._GetOptRomInfStatement
(OptRomObj
)
4314 isFile
= self
._GetOptRomFileStatement
(OptRomObj
)
4315 if not isInf
and not isFile
:
4320 ## _GetOptRomInfStatement() method
4322 # Get INF statements
4324 # @param self The object pointer
4325 # @param Obj for whom inf statement is got
4326 # @retval True Successfully find inf statement
4327 # @retval False Not able to find inf statement
4329 def _GetOptRomInfStatement(self
, Obj
):
4330 if not self
._IsKeyword
("INF"):
4333 ffsInf
= OptRomInfStatement()
4334 self
._GetInfOptions
(ffsInf
)
4336 if not self
._GetNextToken
():
4337 raise Warning("expected INF file path", self
.FileName
, self
.CurrentLineNumber
)
4338 ffsInf
.InfFileName
= self
._Token
4339 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4340 #check for file path
4341 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4343 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4345 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
4346 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
4347 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4348 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
4350 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
4351 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
4353 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
4355 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
4358 self
._GetOptRomOverrides
(ffsInf
)
4360 Obj
.FfsList
.append(ffsInf
)
4363 ## _GetOptRomOverrides() method
4365 # Get overrides for OptROM INF & FILE
4367 # @param self The object pointer
4368 # @param FfsInfObj for whom overrides is got
4370 def _GetOptRomOverrides(self
, Obj
):
4371 if self
._IsToken
('{'):
4372 Overrides
= OverrideAttribs()
4374 if self
._IsKeyword
("PCI_VENDOR_ID"):
4375 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4376 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4377 if not self
._GetNextHexNumber
():
4378 raise Warning("expected Hex vendor id", self
.FileName
, self
.CurrentLineNumber
)
4379 Overrides
.PciVendorId
= self
._Token
4382 if self
._IsKeyword
("PCI_CLASS_CODE"):
4383 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4384 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4385 if not self
._GetNextHexNumber
():
4386 raise Warning("expected Hex class code", self
.FileName
, self
.CurrentLineNumber
)
4387 Overrides
.PciClassCode
= self
._Token
4390 if self
._IsKeyword
("PCI_DEVICE_ID"):
4391 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4392 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4393 if not self
._GetNextHexNumber
():
4394 raise Warning("expected Hex device id", self
.FileName
, self
.CurrentLineNumber
)
4396 Overrides
.PciDeviceId
= self
._Token
4399 if self
._IsKeyword
("PCI_REVISION"):
4400 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4401 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4402 if not self
._GetNextHexNumber
():
4403 raise Warning("expected Hex revision", self
.FileName
, self
.CurrentLineNumber
)
4404 Overrides
.PciRevision
= self
._Token
4407 if self
._IsKeyword
("PCI_COMPRESS"):
4408 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4409 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4410 if not self
._GetNextToken
():
4411 raise Warning("expected TRUE/FALSE for compress", self
.FileName
, self
.CurrentLineNumber
)
4412 Overrides
.NeedCompress
= self
._Token
.upper() == 'TRUE'
4415 if self
._IsToken
("}"):
4418 EdkLogger
.error("FdfParser", FORMAT_INVALID
, File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
4420 Obj
.OverrideAttribs
= Overrides
4422 ## _GetOptRomFileStatement() method
4424 # Get FILE statements
4426 # @param self The object pointer
4427 # @param Obj for whom FILE statement is got
4428 # @retval True Successfully find FILE statement
4429 # @retval False Not able to find FILE statement
4431 def _GetOptRomFileStatement(self
, Obj
):
4432 if not self
._IsKeyword
("FILE"):
4435 FfsFileObj
= OptRomFileStatement()
4437 if not self
._IsKeyword
("EFI") and not self
._IsKeyword
(BINARY_FILE_TYPE_BIN
):
4438 raise Warning("expected Binary type (EFI/BIN)", self
.FileName
, self
.CurrentLineNumber
)
4439 FfsFileObj
.FileType
= self
._Token
4441 if not self
._GetNextToken
():
4442 raise Warning("expected File path", self
.FileName
, self
.CurrentLineNumber
)
4443 FfsFileObj
.FileName
= self
._Token
4444 if FfsFileObj
.FileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4445 #check for file path
4446 ErrorCode
, ErrorInfo
= PathClass(NormPath(FfsFileObj
.FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4448 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4450 if FfsFileObj
.FileType
== 'EFI':
4451 self
._GetOptRomOverrides
(FfsFileObj
)
4453 Obj
.FfsList
.append(FfsFileObj
)
4457 ## _GetCapInFd() method
4459 # Get Cap list contained in FD
4461 # @param self The object pointer
4462 # @param FdName FD name
4463 # @retval CapList List of Capsule in FD
4465 def _GetCapInFd (self
, FdName
):
4467 if FdName
.upper() in self
.Profile
.FdDict
:
4468 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4469 for elementRegion
in FdObj
.RegionList
:
4470 if elementRegion
.RegionType
== 'CAPSULE':
4471 for elementRegionData
in elementRegion
.RegionDataList
:
4472 if elementRegionData
.endswith(".cap"):
4474 if elementRegionData
is not None and elementRegionData
.upper() not in CapList
:
4475 CapList
.append(elementRegionData
.upper())
4478 ## _GetReferencedFdCapTuple() method
4480 # Get FV and FD list referenced by a capsule image
4482 # @param self The object pointer
4483 # @param CapObj Capsule section to be searched
4484 # @param RefFdList referenced FD by section
4485 # @param RefFvList referenced FV by section
4487 def _GetReferencedFdCapTuple(self
, CapObj
, RefFdList
= [], RefFvList
= []):
4488 for CapsuleDataObj
in CapObj
.CapsuleDataList
:
4489 if hasattr(CapsuleDataObj
, 'FvName') and CapsuleDataObj
.FvName
is not None and CapsuleDataObj
.FvName
.upper() not in RefFvList
:
4490 RefFvList
.append (CapsuleDataObj
.FvName
.upper())
4491 elif hasattr(CapsuleDataObj
, 'FdName') and CapsuleDataObj
.FdName
is not None and CapsuleDataObj
.FdName
.upper() not in RefFdList
:
4492 RefFdList
.append (CapsuleDataObj
.FdName
.upper())
4493 elif CapsuleDataObj
.Ffs
is not None:
4494 if isinstance(CapsuleDataObj
.Ffs
, FileStatement
):
4495 if CapsuleDataObj
.Ffs
.FvName
is not None and CapsuleDataObj
.Ffs
.FvName
.upper() not in RefFvList
:
4496 RefFvList
.append(CapsuleDataObj
.Ffs
.FvName
.upper())
4497 elif CapsuleDataObj
.Ffs
.FdName
is not None and CapsuleDataObj
.Ffs
.FdName
.upper() not in RefFdList
:
4498 RefFdList
.append(CapsuleDataObj
.Ffs
.FdName
.upper())
4500 self
._GetReferencedFdFvTupleFromSection
(CapsuleDataObj
.Ffs
, RefFdList
, RefFvList
)
4502 ## _GetFvInFd() method
4504 # Get FV list contained in FD
4506 # @param self The object pointer
4507 # @param FdName FD name
4508 # @retval FvList list of FV in FD
4510 def _GetFvInFd (self
, FdName
):
4512 if FdName
.upper() in self
.Profile
.FdDict
:
4513 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4514 for elementRegion
in FdObj
.RegionList
:
4515 if elementRegion
.RegionType
== BINARY_FILE_TYPE_FV
:
4516 for elementRegionData
in elementRegion
.RegionDataList
:
4517 if elementRegionData
.endswith(".fv"):
4519 if elementRegionData
is not None and elementRegionData
.upper() not in FvList
:
4520 FvList
.append(elementRegionData
.upper())
4523 ## _GetReferencedFdFvTuple() method
4525 # Get FD and FV list referenced by a FFS file
4527 # @param self The object pointer
4528 # @param FfsFile contains sections to be searched
4529 # @param RefFdList referenced FD by section
4530 # @param RefFvList referenced FV by section
4532 def _GetReferencedFdFvTuple(self
, FvObj
, RefFdList
= [], RefFvList
= []):
4533 for FfsObj
in FvObj
.FfsList
:
4534 if isinstance(FfsObj
, FileStatement
):
4535 if FfsObj
.FvName
is not None and FfsObj
.FvName
.upper() not in RefFvList
:
4536 RefFvList
.append(FfsObj
.FvName
.upper())
4537 elif FfsObj
.FdName
is not None and FfsObj
.FdName
.upper() not in RefFdList
:
4538 RefFdList
.append(FfsObj
.FdName
.upper())
4540 self
._GetReferencedFdFvTupleFromSection
(FfsObj
, RefFdList
, RefFvList
)
4542 ## _GetReferencedFdFvTupleFromSection() method
4544 # Get FD and FV list referenced by a FFS section
4546 # @param self The object pointer
4547 # @param FfsFile contains sections to be searched
4548 # @param FdList referenced FD by section
4549 # @param FvList referenced FV by section
4551 def _GetReferencedFdFvTupleFromSection(self
, FfsFile
, FdList
= [], FvList
= []):
4552 SectionStack
= list(FfsFile
.SectionList
)
4553 while SectionStack
!= []:
4554 SectionObj
= SectionStack
.pop()
4555 if isinstance(SectionObj
, FvImageSection
):
4556 if SectionObj
.FvName
is not None and SectionObj
.FvName
.upper() not in FvList
:
4557 FvList
.append(SectionObj
.FvName
.upper())
4558 if SectionObj
.Fv
is not None and SectionObj
.Fv
.UiFvName
is not None and SectionObj
.Fv
.UiFvName
.upper() not in FvList
:
4559 FvList
.append(SectionObj
.Fv
.UiFvName
.upper())
4560 self
._GetReferencedFdFvTuple
(SectionObj
.Fv
, FdList
, FvList
)
4562 if isinstance(SectionObj
, CompressSection
) or isinstance(SectionObj
, GuidSection
):
4563 SectionStack
.extend(SectionObj
.SectionList
)
4565 ## CycleReferenceCheck() method
4567 # Check whether cycle reference exists in FDF
4569 # @param self The object pointer
4570 # @retval True cycle reference exists
4571 # @retval False Not exists cycle reference
4573 def CycleReferenceCheck(self
):
4575 # Check the cycle between FV and FD image
4577 MaxLength
= len (self
.Profile
.FvDict
)
4578 for FvName
in self
.Profile
.FvDict
:
4579 LogStr
= "\nCycle Reference Checking for FV: %s\n" % FvName
4580 RefFvStack
= set(FvName
)
4581 FdAnalyzedList
= set()
4584 while RefFvStack
and Index
< MaxLength
:
4586 FvNameFromStack
= RefFvStack
.pop()
4587 if FvNameFromStack
.upper() in self
.Profile
.FvDict
:
4588 FvObj
= self
.Profile
.FvDict
[FvNameFromStack
.upper()]
4594 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4596 for RefFdName
in RefFdList
:
4597 if RefFdName
in FdAnalyzedList
:
4600 LogStr
+= "FV %s contains FD %s\n" % (FvNameFromStack
, RefFdName
)
4601 FvInFdList
= self
._GetFvInFd
(RefFdName
)
4602 if FvInFdList
!= []:
4603 for FvNameInFd
in FvInFdList
:
4604 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4605 if FvNameInFd
not in RefFvStack
:
4606 RefFvStack
.add(FvNameInFd
)
4608 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4609 EdkLogger
.info(LogStr
)
4611 FdAnalyzedList
.add(RefFdName
)
4613 for RefFvName
in RefFvList
:
4614 LogStr
+= "FV %s contains FV %s\n" % (FvNameFromStack
, RefFvName
)
4615 if RefFvName
not in RefFvStack
:
4616 RefFvStack
.add(RefFvName
)
4618 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4619 EdkLogger
.info(LogStr
)
4623 # Check the cycle between Capsule and FD image
4625 MaxLength
= len (self
.Profile
.CapsuleDict
)
4626 for CapName
in self
.Profile
.CapsuleDict
:
4628 # Capsule image to be checked.
4630 LogStr
= "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4631 RefCapStack
= {CapName}
4632 FdAnalyzedList
= set()
4633 FvAnalyzedList
= set()
4636 while RefCapStack
and Index
< MaxLength
:
4638 CapNameFromStack
= RefCapStack
.pop()
4639 if CapNameFromStack
.upper() in self
.Profile
.CapsuleDict
:
4640 CapObj
= self
.Profile
.CapsuleDict
[CapNameFromStack
.upper()]
4646 self
._GetReferencedFdCapTuple
(CapObj
, RefFdList
, RefFvList
)
4650 while FvListLength
< len (RefFvList
) or FdListLength
< len (RefFdList
):
4651 for RefFdName
in RefFdList
:
4652 if RefFdName
in FdAnalyzedList
:
4655 LogStr
+= "Capsule %s contains FD %s\n" % (CapNameFromStack
, RefFdName
)
4656 for CapNameInFd
in self
._GetCapInFd
(RefFdName
):
4657 LogStr
+= "FD %s contains Capsule %s\n" % (RefFdName
, CapNameInFd
)
4658 if CapNameInFd
not in RefCapStack
:
4659 RefCapStack
.append(CapNameInFd
)
4661 if CapName
in RefCapStack
or CapNameFromStack
in RefCapStack
:
4662 EdkLogger
.info(LogStr
)
4665 for FvNameInFd
in self
._GetFvInFd
(RefFdName
):
4666 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4667 if FvNameInFd
not in RefFvList
:
4668 RefFvList
.append(FvNameInFd
)
4670 FdAnalyzedList
.add(RefFdName
)
4672 # the number of the parsed FV and FD image
4674 FvListLength
= len (RefFvList
)
4675 FdListLength
= len (RefFdList
)
4676 for RefFvName
in RefFvList
:
4677 if RefFvName
in FvAnalyzedList
:
4679 LogStr
+= "Capsule %s contains FV %s\n" % (CapNameFromStack
, RefFvName
)
4680 if RefFvName
.upper() in self
.Profile
.FvDict
:
4681 FvObj
= self
.Profile
.FvDict
[RefFvName
.upper()]
4684 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4685 FvAnalyzedList
.add(RefFvName
)
4689 def GetAllIncludedFile (self
):
4690 global AllIncludeFileList
4691 return AllIncludeFileList
4693 if __name__
== "__main__":
4696 test_file
= sys
.argv
[1]
4697 except IndexError as v
:
4698 print("Usage: %s filename" % sys
.argv
[0])
4701 parser
= FdfParser(test_file
)
4704 parser
.CycleReferenceCheck()
4705 except Warning as X
: