4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 # Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
7 # SPDX-License-Identifier: BSD-2-Clause-Patent
13 from __future__
import print_function
14 from __future__
import absolute_import
15 from re
import compile, DOTALL
16 from string
import hexdigits
19 from Common
.BuildToolError
import *
20 from Common
import EdkLogger
21 from Common
.Misc
import PathClass
, tdict
, ProcessDuplicatedInf
22 from Common
.StringUtils
import NormPath
, ReplaceMacro
23 from Common
import GlobalData
24 from Common
.Expression
import *
25 from Common
.DataType
import *
26 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
27 import Common
.LongFilePathOs
as os
28 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
29 from Common
.RangeExpression
import RangeExpression
30 from collections
import OrderedDict
33 from .Region
import Region
35 from .AprioriSection
import AprioriSection
36 from .FfsInfStatement
import FfsInfStatement
37 from .FfsFileStatement
import FileStatement
38 from .VerSection
import VerSection
39 from .UiSection
import UiSection
40 from .FvImageSection
import FvImageSection
41 from .DataSection
import DataSection
42 from .DepexSection
import DepexSection
43 from .CompressSection
import CompressSection
44 from .GuidSection
import GuidSection
45 from .Capsule
import EFI_CERT_TYPE_PKCS7_GUID
, EFI_CERT_TYPE_RSA2048_SHA256_GUID
, Capsule
46 from .CapsuleData
import CapsuleFfs
, CapsulePayload
, CapsuleFv
, CapsuleFd
, CapsuleAnyFile
, CapsuleAfile
47 from .RuleComplexFile
import RuleComplexFile
48 from .RuleSimpleFile
import RuleSimpleFile
49 from .EfiSection
import EfiSection
50 from .OptionRom
import OPTIONROM
51 from .OptRomInfStatement
import OptRomInfStatement
, OverrideAttribs
52 from .OptRomFileStatement
import OptRomFileStatement
53 from .GenFdsGlobalVariable
import GenFdsGlobalVariable
57 T_CHAR_DOUBLE_QUOTE
= '\"'
58 T_CHAR_SINGLE_QUOTE
= '\''
61 SEPARATORS
= {TAB_EQUAL_SPLIT
, TAB_VALUE_SPLIT
, TAB_COMMA_SPLIT
, '{', T_CHAR_BRACE_R
}
62 ALIGNMENTS
= {"Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K", "64K", "128K",
63 "256K", "512K", "1M", "2M", "4M", "8M", "16M"}
64 ALIGNMENT_NOAUTO
= ALIGNMENTS
- {"Auto"}
65 CR_LB_SET
= {T_CHAR_CR
, TAB_LINE_BREAK
}
67 RegionSizePattern
= compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
68 RegionSizeGuidPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*")
69 RegionOffsetPcdPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$")
70 ShortcutPcdPattern
= compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
71 BaseAddrValuePattern
= compile('^0[xX][0-9a-fA-F]+')
72 FileExtensionPattern
= compile(r
'([a-zA-Z][a-zA-Z0-9]*)')
73 TokenFindPattern
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
74 AllIncludeFileList
= []
76 # Get the closest parent
77 def GetParentAtLine (Line
):
78 for Profile
in AllIncludeFileList
:
79 if Profile
.IsLineInFile(Line
):
84 def IsValidInclude (File
, Line
):
85 for Profile
in AllIncludeFileList
:
86 if Profile
.IsLineInFile(Line
) and Profile
.FileName
== File
:
91 def GetRealFileLine (File
, Line
):
93 for Profile
in AllIncludeFileList
:
94 if Profile
.IsLineInFile(Line
):
95 return Profile
.GetLineInFile(Line
)
96 elif Line
>= Profile
.InsertStartLineNumber
and Profile
.Level
== 1:
97 InsertedLines
+= Profile
.GetTotalLines()
99 return (File
, Line
- InsertedLines
)
101 ## The exception class that used to report error messages when parsing FDF
103 # Currently the "ToolName" is set to be "FdfParser".
105 class Warning (Exception):
108 # @param self The object pointer
109 # @param Str The message to record
110 # @param File The FDF name
111 # @param Line The Line number that error occurs
113 def __init__(self
, Str
, File
= None, Line
= None):
114 FileLineTuple
= GetRealFileLine(File
, Line
)
115 self
.FileName
= FileLineTuple
[0]
116 self
.LineNumber
= FileLineTuple
[1]
117 self
.OriginalLineNumber
= Line
119 self
.ToolName
= 'FdfParser'
124 # helper functions to facilitate consistency in warnings
125 # each function is for a different common warning
127 def Expected(Str
, File
, Line
):
128 return Warning("expected {}".format(Str
), File
, Line
)
130 def ExpectedEquals(File
, Line
):
131 return Warning.Expected("'='", File
, Line
)
133 def ExpectedCurlyOpen(File
, Line
):
134 return Warning.Expected("'{'", File
, Line
)
136 def ExpectedCurlyClose(File
, Line
):
137 return Warning.Expected("'}'", File
, Line
)
139 def ExpectedBracketClose(File
, Line
):
140 return Warning.Expected("']'", File
, Line
)
142 ## The Include file content class that used to record file data when parsing include file
144 # May raise Exception when opening file.
146 class IncludeFileProfile
:
149 # @param self The object pointer
150 # @param FileName The file that to be parsed
152 def __init__(self
, FileName
):
153 self
.FileName
= FileName
154 self
.FileLinesList
= []
156 with
open(FileName
, "r") as fsock
:
157 self
.FileLinesList
= fsock
.readlines()
158 for index
, line
in enumerate(self
.FileLinesList
):
159 if not line
.endswith(TAB_LINE_BREAK
):
160 self
.FileLinesList
[index
] += TAB_LINE_BREAK
162 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
164 self
.InsertStartLineNumber
= None
165 self
.InsertAdjust
= 0
166 self
.IncludeFileList
= []
167 self
.Level
= 1 # first level include file
169 def GetTotalLines(self
):
170 TotalLines
= self
.InsertAdjust
+ len(self
.FileLinesList
)
172 for Profile
in self
.IncludeFileList
:
173 TotalLines
+= Profile
.GetTotalLines()
177 def IsLineInFile(self
, Line
):
178 if Line
>= self
.InsertStartLineNumber
and Line
< self
.InsertStartLineNumber
+ self
.GetTotalLines():
183 def GetLineInFile(self
, Line
):
184 if not self
.IsLineInFile (Line
):
185 return (self
.FileName
, -1)
187 InsertedLines
= self
.InsertStartLineNumber
189 for Profile
in self
.IncludeFileList
:
190 if Profile
.IsLineInFile(Line
):
191 return Profile
.GetLineInFile(Line
)
192 elif Line
>= Profile
.InsertStartLineNumber
:
193 InsertedLines
+= Profile
.GetTotalLines()
195 return (self
.FileName
, Line
- InsertedLines
+ 1)
197 ## The FDF content class that used to record file data when parsing FDF
199 # May raise Exception when opening file.
204 # @param self The object pointer
205 # @param FileName The file that to be parsed
207 def __init__(self
, FileName
):
208 self
.FileLinesList
= []
210 with
open(FileName
, "r") as fsock
:
211 self
.FileLinesList
= fsock
.readlines()
214 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
216 self
.FileName
= FileName
217 self
.PcdDict
= OrderedDict()
218 self
.PcdLocalDict
= OrderedDict()
220 self
.InfDict
= {'ArchTBD':[]}
221 # ECC will use this Dict and List information
222 self
.PcdFileLineDict
= {}
223 self
.InfFileLineList
= []
226 self
.FdNameNotSet
= False
228 self
.CapsuleDict
= {}
231 self
.FmpPayloadDict
= {}
233 ## The syntax parser for FDF
235 # PreprocessFile method should be called prior to ParseFile
236 # CycleReferenceCheck method can detect cycles in FDF contents
238 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
239 # Get*** procedures mean these procedures will make judgement on current token only.
244 # @param self The object pointer
245 # @param FileName The file that to be parsed
247 def __init__(self
, FileName
):
248 self
.Profile
= FileProfile(FileName
)
249 self
.FileName
= FileName
250 self
.CurrentLineNumber
= 1
251 self
.CurrentOffsetWithinLine
= 0
252 self
.CurrentFdName
= None
253 self
.CurrentFvName
= None
255 self
._SkippedChars
= ""
256 GlobalData
.gFdfParser
= self
258 # Used to section info
259 self
._CurSection
= []
260 # Key: [section name, UI name, arch]
261 # Value: {MACRO_NAME: MACRO_VALUE}
262 self
._MacroDict
= tdict(True, 3)
263 self
._PcdDict
= OrderedDict()
265 self
._WipeOffArea
= []
266 if GenFdsGlobalVariable
.WorkSpaceDir
== '':
267 GenFdsGlobalVariable
.WorkSpaceDir
= os
.getenv("WORKSPACE")
269 ## _SkipWhiteSpace() method
271 # Skip white spaces from current char.
273 # @param self The object pointer
275 def _SkipWhiteSpace(self
):
276 while not self
._EndOfFile
():
277 if self
._CurrentChar
() in {TAB_PRINTCHAR_NUL
, T_CHAR_CR
, TAB_LINE_BREAK
, TAB_SPACE_SPLIT
, T_CHAR_TAB
}:
278 self
._SkippedChars
+= str(self
._CurrentChar
())
284 ## _EndOfFile() method
286 # Judge current buffer pos is at file end
288 # @param self The object pointer
289 # @retval True Current File buffer position is at file end
290 # @retval False Current File buffer position is NOT at file end
292 def _EndOfFile(self
):
293 NumberOfLines
= len(self
.Profile
.FileLinesList
)
294 SizeOfLastLine
= len(self
.Profile
.FileLinesList
[-1])
295 if self
.CurrentLineNumber
== NumberOfLines
and self
.CurrentOffsetWithinLine
>= SizeOfLastLine
- 1:
297 if self
.CurrentLineNumber
> NumberOfLines
:
301 ## _EndOfLine() method
303 # Judge current buffer pos is at line end
305 # @param self The object pointer
306 # @retval True Current File buffer position is at line end
307 # @retval False Current File buffer position is NOT at line end
309 def _EndOfLine(self
):
310 if self
.CurrentLineNumber
> len(self
.Profile
.FileLinesList
):
312 SizeOfCurrentLine
= len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
313 if self
.CurrentOffsetWithinLine
>= SizeOfCurrentLine
:
319 # Reset file data buffer to the initial state
321 # @param self The object pointer
322 # @param DestLine Optional new destination line number.
323 # @param DestOffset Optional new destination offset.
325 def Rewind(self
, DestLine
= 1, DestOffset
= 0):
326 self
.CurrentLineNumber
= DestLine
327 self
.CurrentOffsetWithinLine
= DestOffset
329 ## _UndoOneChar() method
331 # Go back one char in the file buffer
333 # @param self The object pointer
334 # @retval True Successfully go back one char
335 # @retval False Not able to go back one char as file beginning reached
337 def _UndoOneChar(self
):
338 if self
.CurrentLineNumber
== 1 and self
.CurrentOffsetWithinLine
== 0:
340 elif self
.CurrentOffsetWithinLine
== 0:
341 self
.CurrentLineNumber
-= 1
342 self
.CurrentOffsetWithinLine
= len(self
._CurrentLine
()) - 1
344 self
.CurrentOffsetWithinLine
-= 1
347 ## _GetOneChar() method
349 # Move forward one char in the file buffer
351 # @param self The object pointer
353 def _GetOneChar(self
):
354 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
355 self
.CurrentLineNumber
+= 1
356 self
.CurrentOffsetWithinLine
= 0
358 self
.CurrentOffsetWithinLine
+= 1
360 ## _CurrentChar() method
362 # Get the char pointed to by the file buffer pointer
364 # @param self The object pointer
365 # @retval Char Current char
367 def _CurrentChar(self
):
368 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
]
370 ## _NextChar() method
372 # Get the one char pass the char pointed to by the file buffer pointer
374 # @param self The object pointer
375 # @retval Char Next char
378 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
379 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
][0]
380 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
+ 1]
382 ## _SetCurrentCharValue() method
384 # Modify the value of current char
386 # @param self The object pointer
387 # @param Value The new value of current char
389 def _SetCurrentCharValue(self
, Value
):
390 self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
] = Value
392 ## _CurrentLine() method
394 # Get the list that contains current line contents
396 # @param self The object pointer
397 # @retval List current line contents
399 def _CurrentLine(self
):
400 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
402 def _StringToList(self
):
403 self
.Profile
.FileLinesList
= [list(s
) for s
in self
.Profile
.FileLinesList
]
404 if not self
.Profile
.FileLinesList
:
405 EdkLogger
.error('FdfParser', FILE_READ_FAILURE
, 'The file is empty!', File
=self
.FileName
)
406 self
.Profile
.FileLinesList
[-1].append(' ')
408 def _ReplaceFragment(self
, StartPos
, EndPos
, Value
= ' '):
409 if StartPos
[0] == EndPos
[0]:
411 while Offset
<= EndPos
[1]:
412 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
417 while self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] not in CR_LB_SET
:
418 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
422 while Line
< EndPos
[0]:
424 while self
.Profile
.FileLinesList
[Line
][Offset
] not in CR_LB_SET
:
425 self
.Profile
.FileLinesList
[Line
][Offset
] = Value
430 while Offset
<= EndPos
[1]:
431 self
.Profile
.FileLinesList
[EndPos
[0]][Offset
] = Value
434 def _SetMacroValue(self
, Macro
, Value
):
435 if not self
._CurSection
:
439 if not self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]:
440 self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]] = MacroDict
442 MacroDict
= self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]
443 MacroDict
[Macro
] = Value
445 def _GetMacroValue(self
, Macro
):
447 if Macro
in GlobalData
.gCommandLineDefines
:
448 return GlobalData
.gCommandLineDefines
[Macro
]
449 if Macro
in GlobalData
.gGlobalDefines
:
450 return GlobalData
.gGlobalDefines
[Macro
]
453 MacroDict
= self
._MacroDict
[
458 if MacroDict
and Macro
in MacroDict
:
459 return MacroDict
[Macro
]
462 if Macro
in GlobalData
.gPlatformDefines
:
463 return GlobalData
.gPlatformDefines
[Macro
]
466 def _SectionHeaderParser(self
, Section
):
468 # [FD.UiName]: use dummy instead if UI name is optional
471 # [Rule]: don't take rule section into account, macro is not allowed in this section
472 # [OptionRom.DriverName]
473 self
._CurSection
= []
474 Section
= Section
.strip()[1:-1].upper().replace(' ', '').strip(TAB_SPLIT
)
475 ItemList
= Section
.split(TAB_SPLIT
)
477 if Item
== '' or Item
== 'RULE':
480 if Item
== TAB_COMMON_DEFINES
.upper():
481 self
._CurSection
= [TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
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
() == TAB_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
() == TAB_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.ExpectedEquals(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 MacroValue
= self
._GetMacroValue
(MacroName
)
714 if MacroValue
is not None:
715 CurLine
= CurLine
.replace('$(' + MacroName
+ ')', MacroValue
, 1)
716 if MacroValue
.find('$(') != -1:
719 PreIndex
= StartPos
+ len(MacroValue
)
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.ExpectedEquals(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.ExpectedEquals(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 separator
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 separator 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 separator as the first char, we must proceed to get it.
1056 # That is, we get a token that is a separator char. normally 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 separator
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 GlobalData
.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 separator 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 separator as the first char, we must proceed to get it.
1136 # That is, we get a token that is a separator char. normally 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 separator
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 GlobalData
.gHexPatternAll
.match(self
._Token
):
1162 ## _GetNextDecimalNumber() method
1164 # Get next decimal data before a separator
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("<PcdTokenSpaceCName>", self
.FileName
, self
.CurrentLineNumber
)
1183 pcdTokenSpaceCName
= self
._Token
1185 if not self
._IsToken
(TAB_SPLIT
):
1186 raise Warning.Expected(".", self
.FileName
, self
.CurrentLineNumber
)
1188 if not self
._GetNextWord
():
1189 raise Warning.Expected("<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1190 pcdCName
= self
._Token
1193 while self
._IsToken
(TAB_SPLIT
):
1194 if not self
._GetNextPcdWord
():
1195 raise Warning.Expected("Pcd Fields", 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
):
1211 if self
._Token
.startswith(T_CHAR_DOUBLE_QUOTE
) or self
._Token
.startswith("L\""):
1212 QuoteToUse
= T_CHAR_DOUBLE_QUOTE
1213 elif self
._Token
.startswith(T_CHAR_SINGLE_QUOTE
) or self
._Token
.startswith("L\'"):
1214 QuoteToUse
= T_CHAR_SINGLE_QUOTE
1219 self
._SkipToToken
(QuoteToUse
)
1220 currentLineNumber
= self
.CurrentLineNumber
1222 if not self
._SkipToToken
(QuoteToUse
):
1223 raise Warning(QuoteToUse
, self
.FileName
, self
.CurrentLineNumber
)
1224 if currentLineNumber
!= self
.CurrentLineNumber
:
1225 raise Warning(QuoteToUse
, self
.FileName
, self
.CurrentLineNumber
)
1226 self
._Token
= self
._SkippedChars
.rstrip(QuoteToUse
)
1229 ## _SkipToToken() method
1231 # Search forward in file buffer for the string
1232 # The skipped chars are put into self._SkippedChars
1234 # @param self The object pointer
1235 # @param String The string to search
1236 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1237 # @retval True Successfully find the string, file buffer pointer moved forward
1238 # @retval False Not able to find the string, file buffer pointer not changed
1240 def _SkipToToken(self
, String
, IgnoreCase
= False):
1241 StartPos
= self
.GetFileBufferPos()
1243 self
._SkippedChars
= ""
1244 while not self
._EndOfFile
():
1247 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
1249 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
1251 self
.CurrentOffsetWithinLine
+= len(String
)
1252 self
._SkippedChars
+= String
1254 self
._SkippedChars
+= str(self
._CurrentChar
())
1257 self
.SetFileBufferPos(StartPos
)
1258 self
._SkippedChars
= ""
1261 ## GetFileBufferPos() method
1263 # Return the tuple of current line and offset within the line
1265 # @param self The object pointer
1266 # @retval Tuple Line number and offset pair
1268 def GetFileBufferPos(self
):
1269 return (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
)
1271 ## SetFileBufferPos() method
1273 # Restore the file buffer position
1275 # @param self The object pointer
1276 # @param Pos The new file buffer position
1278 def SetFileBufferPos(self
, Pos
):
1279 (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
) = Pos
1281 ## Preprocess() method
1283 # Preprocess comment, conditional directive, include directive, replace macro.
1284 # Exception will be raised if syntax error found
1286 # @param self The object pointer
1288 def Preprocess(self
):
1289 self
._StringToList
()
1290 self
.PreprocessFile()
1291 self
.PreprocessIncludeFile()
1292 self
._StringToList
()
1293 self
.PreprocessFile()
1294 self
.PreprocessConditionalStatement()
1295 self
._StringToList
()
1296 for Pos
in self
._WipeOffArea
:
1297 self
._ReplaceFragment
(Pos
[0], Pos
[1])
1298 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
1300 while self
._GetDefines
():
1303 ## ParseFile() method
1305 # Parse the file profile buffer to extract fd, fv ... information
1306 # Exception will be raised if syntax error found
1308 # @param self The object pointer
1310 def ParseFile(self
):
1315 # Keep processing sections of the FDF until no new sections or a syntax error is found
1317 while self
._GetFd
() or self
._GetFv
() or self
._GetFmp
() or self
._GetCapsule
() or self
._GetRule
() or self
._GetOptionRom
():
1320 except Warning as X
:
1322 #'\n\tGot Token: \"%s\" from File %s\n' % (self._Token, FileLineTuple[0]) + \
1323 # At this point, the closest parent would be the included file itself
1324 Profile
= GetParentAtLine(X
.OriginalLineNumber
)
1325 if Profile
is not None:
1326 X
.Message
+= ' near line %d, column %d: %s' \
1327 % (X
.LineNumber
, 0, Profile
.FileLinesList
[X
.LineNumber
-1])
1329 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1330 X
.Message
+= ' near line %d, column %d: %s' \
1331 % (FileLineTuple
[1], self
.CurrentOffsetWithinLine
+ 1, self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:].rstrip(TAB_LINE_BREAK
).rstrip(T_CHAR_CR
))
1334 ## SectionParser() method
1336 # Parse the file section info
1337 # Exception will be raised if syntax error found
1339 # @param self The object pointer
1340 # @param section The section string
1342 def SectionParser(self
, section
):
1344 if not S
.startswith("[DEFINES") and not S
.startswith("[FD.") and not S
.startswith("[FV.") and not S
.startswith("[CAPSULE.") \
1345 and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM.") and not S
.startswith('[FMPPAYLOAD.'):
1346 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self
.FileName
, self
.CurrentLineNumber
)
1348 ## _GetDefines() method
1350 # Get Defines section contents and store its data into AllMacrosList
1352 # @param self The object pointer
1353 # @retval True Successfully find a Defines
1354 # @retval False Not able to find a Defines
1356 def _GetDefines(self
):
1357 if not self
._GetNextToken
():
1360 S
= self
._Token
.upper()
1361 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[DEFINES"):
1362 self
.SectionParser(S
)
1367 if not self
._IsToken
("[DEFINES", True):
1368 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1369 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1370 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1371 raise Warning.Expected("[DEFINES", self
.FileName
, self
.CurrentLineNumber
)
1373 if not self
._IsToken
(TAB_SECTION_END
):
1374 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
1376 while self
._GetNextWord
():
1377 # handle the SET statement
1378 if self
._Token
== 'SET':
1380 self
._GetSetStatement
(None)
1385 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1386 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1387 if not self
._GetNextToken
() or self
._Token
.startswith(TAB_SECTION_START
):
1388 raise Warning.Expected("MACRO value", self
.FileName
, self
.CurrentLineNumber
)
1393 ##_GetError() method
1394 def _GetError(self
):
1395 #save the Current information
1396 CurrentLine
= self
.CurrentLineNumber
1397 CurrentOffset
= self
.CurrentOffsetWithinLine
1398 while self
._GetNextToken
():
1399 if self
._Token
== TAB_ERROR
:
1400 EdkLogger
.error('FdfParser', ERROR_STATEMENT
, self
._CurrentLine
().replace(TAB_ERROR
, '', 1), File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
1401 self
.CurrentLineNumber
= CurrentLine
1402 self
.CurrentOffsetWithinLine
= CurrentOffset
1406 # Get FD section contents and store its data into FD dictionary of self.Profile
1408 # @param self The object pointer
1409 # @retval True Successfully find a FD
1410 # @retval False Not able to find a FD
1413 if not self
._GetNextToken
():
1416 S
= self
._Token
.upper()
1417 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FD."):
1418 if not S
.startswith("[FV.") and not S
.startswith('[FMPPAYLOAD.') and not S
.startswith("[CAPSULE.") \
1419 and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM."):
1420 raise Warning("Unknown section", self
.FileName
, self
.CurrentLineNumber
)
1425 if not self
._IsToken
("[FD.", True):
1426 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1427 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1428 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1429 raise Warning.Expected("[FD.]", self
.FileName
, self
.CurrentLineNumber
)
1431 FdName
= self
._GetUiName
()
1433 if len (self
.Profile
.FdDict
) == 0:
1434 FdName
= GenFdsGlobalVariable
.PlatformName
1435 if FdName
== "" and GlobalData
.gActivePlatform
:
1436 FdName
= GlobalData
.gActivePlatform
.PlatformName
1437 self
.Profile
.FdNameNotSet
= True
1439 raise Warning.Expected("FdName in [FD.] section", self
.FileName
, self
.CurrentLineNumber
)
1440 self
.CurrentFdName
= FdName
.upper()
1442 if self
.CurrentFdName
in self
.Profile
.FdDict
:
1443 raise Warning("Unexpected the same FD name", self
.FileName
, self
.CurrentLineNumber
)
1445 if not self
._IsToken
(TAB_SECTION_END
):
1446 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
1449 FdObj
.FdUiName
= self
.CurrentFdName
1450 self
.Profile
.FdDict
[self
.CurrentFdName
] = FdObj
1452 if len (self
.Profile
.FdDict
) > 1 and self
.Profile
.FdNameNotSet
:
1453 raise Warning.Expected("all FDs have their name", self
.FileName
, self
.CurrentLineNumber
)
1455 Status
= self
._GetCreateFile
(FdObj
)
1457 raise Warning("FD name error", self
.FileName
, self
.CurrentLineNumber
)
1459 while self
._GetTokenStatements
(FdObj
):
1461 for Attr
in ("BaseAddress", "Size", "ErasePolarity"):
1462 if getattr(FdObj
, Attr
) is None:
1463 self
._GetNextToken
()
1464 raise Warning("Keyword %s missing" % Attr
, self
.FileName
, self
.CurrentLineNumber
)
1466 if not FdObj
.BlockSizeList
:
1467 FdObj
.BlockSizeList
.append((1, FdObj
.Size
, None))
1469 self
._GetDefineStatements
(FdObj
)
1471 self
._GetSetStatements
(FdObj
)
1473 if not self
._GetRegionLayout
(FdObj
):
1474 raise Warning.Expected("region layout", self
.FileName
, self
.CurrentLineNumber
)
1476 while self
._GetRegionLayout
(FdObj
):
1480 ## _GetUiName() method
1482 # Return the UI name of a section
1484 # @param self The object pointer
1485 # @retval FdName UI name
1487 def _GetUiName(self
):
1489 if self
._GetNextWord
():
1494 ## _GetCreateFile() method
1496 # Return the output file name of object
1498 # @param self The object pointer
1499 # @param Obj object whose data will be stored in file
1500 # @retval FdName UI name
1502 def _GetCreateFile(self
, Obj
):
1503 if self
._IsKeyword
("CREATE_FILE"):
1504 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1505 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1507 if not self
._GetNextToken
():
1508 raise Warning.Expected("file name", self
.FileName
, self
.CurrentLineNumber
)
1510 FileName
= self
._Token
1511 Obj
.CreateFileName
= FileName
1515 def SetPcdLocalation(self
,pcdpair
):
1516 self
.Profile
.PcdLocalDict
[pcdpair
] = (self
.Profile
.FileName
,self
.CurrentLineNumber
)
1518 ## _GetTokenStatements() method
1520 # Get token statements
1522 # @param self The object pointer
1523 # @param Obj for whom token statement is got
1525 def _GetTokenStatements(self
, Obj
):
1526 if self
._IsKeyword
("BaseAddress"):
1527 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1528 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1530 if not self
._GetNextHexNumber
():
1531 raise Warning.Expected("Hex base address", self
.FileName
, self
.CurrentLineNumber
)
1533 Obj
.BaseAddress
= self
._Token
1535 if self
._IsToken
(TAB_VALUE_SPLIT
):
1536 pcdPair
= self
._GetNextPcdSettings
()
1537 Obj
.BaseAddressPcd
= pcdPair
1538 self
.Profile
.PcdDict
[pcdPair
] = Obj
.BaseAddress
1539 self
.SetPcdLocalation(pcdPair
)
1540 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1541 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1544 if self
._IsKeyword
("Size"):
1545 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1546 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1548 if not self
._GetNextHexNumber
():
1549 raise Warning.Expected("Hex size", self
.FileName
, self
.CurrentLineNumber
)
1552 if self
._IsToken
(TAB_VALUE_SPLIT
):
1553 pcdPair
= self
._GetNextPcdSettings
()
1554 Obj
.SizePcd
= pcdPair
1555 self
.Profile
.PcdDict
[pcdPair
] = Size
1556 self
.SetPcdLocalation(pcdPair
)
1557 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1558 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1559 Obj
.Size
= int(Size
, 0)
1562 if self
._IsKeyword
("ErasePolarity"):
1563 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1564 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1566 if not self
._GetNextToken
():
1567 raise Warning.Expected("Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1569 if not self
._Token
in {"1", "0"}:
1570 raise Warning.Expected("1 or 0 Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1572 Obj
.ErasePolarity
= self
._Token
1575 return self
._GetBlockStatements
(Obj
)
1577 ## _GetAddressStatements() method
1579 # Get address statements
1581 # @param self The object pointer
1582 # @param Obj for whom address statement is got
1583 # @retval True Successfully find
1584 # @retval False Not able to find
1586 def _GetAddressStatements(self
, Obj
):
1587 if self
._IsKeyword
("BsBaseAddress"):
1588 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1589 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1591 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1592 raise Warning.Expected("address", self
.FileName
, self
.CurrentLineNumber
)
1594 BsAddress
= int(self
._Token
, 0)
1595 Obj
.BsBaseAddress
= BsAddress
1597 if self
._IsKeyword
("RtBaseAddress"):
1598 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1599 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1601 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1602 raise Warning.Expected("address", self
.FileName
, self
.CurrentLineNumber
)
1604 RtAddress
= int(self
._Token
, 0)
1605 Obj
.RtBaseAddress
= RtAddress
1607 ## _GetBlockStatements() method
1609 # Get block statements
1611 # @param self The object pointer
1612 # @param Obj for whom block statement is got
1614 def _GetBlockStatements(self
, Obj
):
1616 while self
._GetBlockStatement
(Obj
):
1619 Item
= Obj
.BlockSizeList
[-1]
1620 if Item
[0] is None or Item
[1] is None:
1621 raise Warning.Expected("block statement", self
.FileName
, self
.CurrentLineNumber
)
1624 ## _GetBlockStatement() method
1626 # Get block statement
1628 # @param self The object pointer
1629 # @param Obj for whom block statement is got
1630 # @retval True Successfully find
1631 # @retval False Not able to find
1633 def _GetBlockStatement(self
, Obj
):
1634 if not self
._IsKeyword
("BlockSize"):
1637 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1638 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1640 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
1641 raise Warning.Expected("Hex or Integer block size", self
.FileName
, self
.CurrentLineNumber
)
1643 BlockSize
= self
._Token
1645 if self
._IsToken
(TAB_VALUE_SPLIT
):
1646 PcdPair
= self
._GetNextPcdSettings
()
1647 BlockSizePcd
= PcdPair
1648 self
.Profile
.PcdDict
[PcdPair
] = BlockSize
1649 self
.SetPcdLocalation(PcdPair
)
1650 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1651 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1652 BlockSize
= int(BlockSize
, 0)
1655 if self
._IsKeyword
("NumBlocks"):
1656 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1657 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1659 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1660 raise Warning.Expected("block numbers", self
.FileName
, self
.CurrentLineNumber
)
1662 BlockNumber
= int(self
._Token
, 0)
1664 Obj
.BlockSizeList
.append((BlockSize
, BlockNumber
, BlockSizePcd
))
1667 ## _GetDefineStatements() method
1669 # Get define statements
1671 # @param self The object pointer
1672 # @param Obj for whom define statement is got
1673 # @retval True Successfully find
1674 # @retval False Not able to find
1676 def _GetDefineStatements(self
, Obj
):
1677 while self
._GetDefineStatement
(Obj
):
1680 ## _GetDefineStatement() method
1682 # Get define statement
1684 # @param self The object pointer
1685 # @param Obj for whom define statement is got
1686 # @retval True Successfully find
1687 # @retval False Not able to find
1689 def _GetDefineStatement(self
, Obj
):
1690 if self
._IsKeyword
(TAB_DEFINE
):
1691 self
._GetNextToken
()
1693 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1694 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1696 if not self
._GetNextToken
():
1697 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
1700 Macro
= '$(' + Macro
+ ')'
1701 Obj
.DefineVarDict
[Macro
] = Value
1706 ## _GetSetStatements() method
1708 # Get set statements
1710 # @param self The object pointer
1711 # @param Obj for whom set statement is got
1712 # @retval True Successfully find
1713 # @retval False Not able to find
1715 def _GetSetStatements(self
, Obj
):
1716 while self
._GetSetStatement
(Obj
):
1719 ## _GetSetStatement() method
1723 # @param self The object pointer
1724 # @param Obj for whom set statement is got
1725 # @retval True Successfully find
1726 # @retval False Not able to find
1728 def _GetSetStatement(self
, Obj
):
1729 if self
._IsKeyword
("SET"):
1730 PcdPair
= self
._GetNextPcdSettings
()
1732 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1733 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1735 Value
= self
._GetExpression
()
1736 Value
= self
._EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
1739 Obj
.SetVarDict
[PcdPair
] = Value
1740 self
.Profile
.PcdDict
[PcdPair
] = Value
1741 self
.SetPcdLocalation(PcdPair
)
1742 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1743 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1748 ## _CalcRegionExpr(self)
1750 # Calculate expression for offset or size of a region
1752 # @return: None if invalid expression
1753 # Calculated number if successfully
1755 def _CalcRegionExpr(self
):
1756 StartPos
= self
.GetFileBufferPos()
1759 while not self
._EndOfFile
():
1760 CurCh
= self
._CurrentChar
()
1766 if CurCh
in '|\r\n' and PairCount
== 0:
1772 ValueExpression(Expr
,
1773 self
._CollectMacroPcd
()
1776 self
.SetFileBufferPos(StartPos
)
1779 ## _GetRegionLayout() method
1781 # Get region layout for FD
1783 # @param self The object pointer
1784 # @param theFd for whom region is got
1785 # @retval True Successfully find
1786 # @retval False Not able to find
1788 def _GetRegionLayout(self
, theFd
):
1789 Offset
= self
._CalcRegionExpr
()
1793 RegionObj
= Region()
1794 RegionObj
.Offset
= Offset
1795 theFd
.RegionList
.append(RegionObj
)
1797 if not self
._IsToken
(TAB_VALUE_SPLIT
):
1798 raise Warning.Expected("'|'", self
.FileName
, self
.CurrentLineNumber
)
1800 Size
= self
._CalcRegionExpr
()
1802 raise Warning.Expected("Region Size", self
.FileName
, self
.CurrentLineNumber
)
1803 RegionObj
.Size
= Size
1805 if not self
._GetNextWord
():
1808 if not self
._Token
in {"SET", BINARY_FILE_TYPE_FV
, "FILE", "DATA", "CAPSULE", "INF"}:
1810 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1811 # Or it might be next region's offset described by an expression which starts with a PCD.
1812 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1815 IsRegionPcd
= (RegionSizeGuidPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]) or
1816 RegionOffsetPcdPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]))
1818 RegionObj
.PcdOffset
= self
._GetNextPcdSettings
()
1819 self
.Profile
.PcdDict
[RegionObj
.PcdOffset
] = "0x%08X" % (RegionObj
.Offset
+ int(theFd
.BaseAddress
, 0))
1820 self
.SetPcdLocalation(RegionObj
.PcdOffset
)
1821 self
._PcdDict
['%s.%s' % (RegionObj
.PcdOffset
[1], RegionObj
.PcdOffset
[0])] = "0x%x" % RegionObj
.Offset
1822 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1823 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdOffset
] = FileLineTuple
1824 if self
._IsToken
(TAB_VALUE_SPLIT
):
1825 RegionObj
.PcdSize
= self
._GetNextPcdSettings
()
1826 self
.Profile
.PcdDict
[RegionObj
.PcdSize
] = "0x%08X" % RegionObj
.Size
1827 self
.SetPcdLocalation(RegionObj
.PcdSize
)
1828 self
._PcdDict
['%s.%s' % (RegionObj
.PcdSize
[1], RegionObj
.PcdSize
[0])] = "0x%x" % RegionObj
.Size
1829 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1830 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdSize
] = FileLineTuple
1832 if not self
._GetNextWord
():
1835 if self
._Token
== "SET":
1837 self
._GetSetStatements
(RegionObj
)
1838 if not self
._GetNextWord
():
1841 elif self
._Token
== BINARY_FILE_TYPE_FV
:
1843 self
._GetRegionFvType
(RegionObj
)
1845 elif self
._Token
== "CAPSULE":
1847 self
._GetRegionCapType
(RegionObj
)
1849 elif self
._Token
== "FILE":
1851 self
._GetRegionFileType
(RegionObj
)
1853 elif self
._Token
== "INF":
1855 RegionObj
.RegionType
= "INF"
1856 while self
._IsKeyword
("INF"):
1858 ffsInf
= self
._ParseInfStatement
()
1861 RegionObj
.RegionDataList
.append(ffsInf
)
1863 elif self
._Token
== "DATA":
1865 self
._GetRegionDataType
(RegionObj
)
1868 if self
._GetRegionLayout
(theFd
):
1870 raise Warning("A valid region type was not found. "
1871 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
1872 self
.FileName
, self
.CurrentLineNumber
)
1876 ## _GetRegionFvType() method
1878 # Get region fv data for region
1880 # @param self The object pointer
1881 # @param RegionObj for whom region data is got
1883 def _GetRegionFvType(self
, RegionObj
):
1884 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1885 raise Warning.Expected("'FV'", self
.FileName
, self
.CurrentLineNumber
)
1887 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1888 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1890 if not self
._GetNextToken
():
1891 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
1893 RegionObj
.RegionType
= BINARY_FILE_TYPE_FV
1894 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1896 while self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1898 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1899 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1901 if not self
._GetNextToken
():
1902 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
1904 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1906 ## _GetRegionCapType() method
1908 # Get region capsule data for region
1910 # @param self The object pointer
1911 # @param RegionObj for whom region data is got
1913 def _GetRegionCapType(self
, RegionObj
):
1914 if not self
._IsKeyword
("CAPSULE"):
1915 raise Warning.Expected("'CAPSULE'", self
.FileName
, self
.CurrentLineNumber
)
1917 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1918 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1920 if not self
._GetNextToken
():
1921 raise Warning.Expected("CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1923 RegionObj
.RegionType
= "CAPSULE"
1924 RegionObj
.RegionDataList
.append(self
._Token
)
1926 while self
._IsKeyword
("CAPSULE"):
1928 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1929 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1931 if not self
._GetNextToken
():
1932 raise Warning.Expected("CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1934 RegionObj
.RegionDataList
.append(self
._Token
)
1936 ## _GetRegionFileType() method
1938 # Get region file data for region
1940 # @param self The object pointer
1941 # @param RegionObj for whom region data is got
1943 def _GetRegionFileType(self
, RegionObj
):
1944 if not self
._IsKeyword
("FILE"):
1945 raise Warning.Expected("'FILE'", self
.FileName
, self
.CurrentLineNumber
)
1947 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1948 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1950 if not self
._GetNextToken
():
1951 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
1953 RegionObj
.RegionType
= "FILE"
1954 RegionObj
.RegionDataList
.append(self
._Token
)
1956 while self
._IsKeyword
("FILE"):
1958 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1959 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1961 if not self
._GetNextToken
():
1962 raise Warning.Expected("FILE name", self
.FileName
, self
.CurrentLineNumber
)
1964 RegionObj
.RegionDataList
.append(self
._Token
)
1966 ## _GetRegionDataType() method
1968 # Get region array data for region
1970 # @param self The object pointer
1971 # @param RegionObj for whom region data is got
1973 def _GetRegionDataType(self
, RegionObj
):
1974 if not self
._IsKeyword
("DATA"):
1975 raise Warning.Expected("Region Data type", self
.FileName
, self
.CurrentLineNumber
)
1977 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1978 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1980 if not self
._IsToken
("{"):
1981 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
1983 if not self
._GetNextHexNumber
():
1984 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
1986 if len(self
._Token
) > 18:
1987 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
1989 # convert hex string value to byte hex string array
1990 AllString
= self
._Token
1991 AllStrLen
= len (AllString
)
1993 while AllStrLen
> 4:
1994 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
1995 AllStrLen
= AllStrLen
- 2
1996 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
1999 if len (self
._Token
) <= 4:
2000 while self
._IsToken
(TAB_COMMA_SPLIT
):
2001 if not self
._GetNextHexNumber
():
2002 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2003 if len(self
._Token
) > 4:
2004 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2005 DataString
+= self
._Token
2006 DataString
+= TAB_COMMA_SPLIT
2008 if not self
._IsToken
(T_CHAR_BRACE_R
):
2009 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2011 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2012 RegionObj
.RegionType
= "DATA"
2013 RegionObj
.RegionDataList
.append(DataString
)
2015 while self
._IsKeyword
("DATA"):
2017 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2018 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2020 if not self
._IsToken
("{"):
2021 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2023 if not self
._GetNextHexNumber
():
2024 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2026 if len(self
._Token
) > 18:
2027 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2029 # convert hex string value to byte hex string array
2030 AllString
= self
._Token
2031 AllStrLen
= len (AllString
)
2033 while AllStrLen
> 4:
2034 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
2035 AllStrLen
= AllStrLen
- 2
2036 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
2039 if len (self
._Token
) <= 4:
2040 while self
._IsToken
(TAB_COMMA_SPLIT
):
2041 if not self
._GetNextHexNumber
():
2042 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2043 if len(self
._Token
) > 4:
2044 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2045 DataString
+= self
._Token
2046 DataString
+= TAB_COMMA_SPLIT
2048 if not self
._IsToken
(T_CHAR_BRACE_R
):
2049 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2051 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2052 RegionObj
.RegionDataList
.append(DataString
)
2056 # Get FV section contents and store its data into FV dictionary of self.Profile
2058 # @param self The object pointer
2059 # @retval True Successfully find a FV
2060 # @retval False Not able to find a FV
2063 if not self
._GetNextToken
():
2066 S
= self
._Token
.upper()
2067 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FV."):
2068 self
.SectionParser(S
)
2073 if not self
._IsToken
("[FV.", True):
2074 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2075 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2076 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2077 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2079 FvName
= self
._GetUiName
()
2080 self
.CurrentFvName
= FvName
.upper()
2082 if not self
._IsToken
(TAB_SECTION_END
):
2083 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
2085 FvObj
= FV(Name
=self
.CurrentFvName
)
2086 self
.Profile
.FvDict
[self
.CurrentFvName
] = FvObj
2088 Status
= self
._GetCreateFile
(FvObj
)
2090 raise Warning("FV name error", self
.FileName
, self
.CurrentLineNumber
)
2092 self
._GetDefineStatements
(FvObj
)
2094 self
._GetAddressStatements
(FvObj
)
2097 self
._GetSetStatements
(FvObj
)
2099 if not (self
._GetBlockStatement
(FvObj
) or self
._GetFvBaseAddress
(FvObj
) or
2100 self
._GetFvForceRebase
(FvObj
) or self
._GetFvAlignment
(FvObj
) or
2101 self
._GetFvAttributes
(FvObj
) or self
._GetFvNameGuid
(FvObj
) or
2102 self
._GetFvExtEntryStatement
(FvObj
) or self
._GetFvNameString
(FvObj
)):
2105 if FvObj
.FvNameString
== 'TRUE' and not FvObj
.FvNameGuid
:
2106 raise Warning("FvNameString found but FvNameGuid was not found", self
.FileName
, self
.CurrentLineNumber
)
2108 self
._GetAprioriSection
(FvObj
)
2109 self
._GetAprioriSection
(FvObj
)
2112 isInf
= self
._GetInfStatement
(FvObj
)
2113 isFile
= self
._GetFileStatement
(FvObj
)
2114 if not isInf
and not isFile
:
2119 ## _GetFvAlignment() method
2121 # Get alignment for FV
2123 # @param self The object pointer
2124 # @param Obj for whom alignment is got
2125 # @retval True Successfully find a alignment statement
2126 # @retval False Not able to find a alignment statement
2128 def _GetFvAlignment(self
, Obj
):
2129 if not self
._IsKeyword
("FvAlignment"):
2132 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2133 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2135 if not self
._GetNextToken
():
2136 raise Warning.Expected("alignment value", self
.FileName
, self
.CurrentLineNumber
)
2138 if self
._Token
.upper() not in {"1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2139 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2140 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2142 raise Warning("Unknown alignment value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2143 Obj
.FvAlignment
= self
._Token
2146 ## _GetFvBaseAddress() method
2148 # Get BaseAddress for FV
2150 # @param self The object pointer
2151 # @param Obj for whom FvBaseAddress is got
2152 # @retval True Successfully find a FvBaseAddress statement
2153 # @retval False Not able to find a FvBaseAddress statement
2155 def _GetFvBaseAddress(self
, Obj
):
2156 if not self
._IsKeyword
("FvBaseAddress"):
2159 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2160 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2162 if not self
._GetNextToken
():
2163 raise Warning.Expected("FV base address value", self
.FileName
, self
.CurrentLineNumber
)
2165 if not BaseAddrValuePattern
.match(self
._Token
.upper()):
2166 raise Warning("Unknown FV base address value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2167 Obj
.FvBaseAddress
= self
._Token
2170 ## _GetFvForceRebase() method
2172 # Get FvForceRebase for FV
2174 # @param self The object pointer
2175 # @param Obj for whom FvForceRebase is got
2176 # @retval True Successfully find a FvForceRebase statement
2177 # @retval False Not able to find a FvForceRebase statement
2179 def _GetFvForceRebase(self
, Obj
):
2180 if not self
._IsKeyword
("FvForceRebase"):
2183 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2184 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2186 if not self
._GetNextToken
():
2187 raise Warning.Expected("FvForceRebase value", self
.FileName
, self
.CurrentLineNumber
)
2189 if self
._Token
.upper() not in {"TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"}:
2190 raise Warning("Unknown FvForceRebase value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2192 if self
._Token
.upper() in {"TRUE", "1", "0X1", "0X01"}:
2193 Obj
.FvForceRebase
= True
2194 elif self
._Token
.upper() in {"FALSE", "0", "0X0", "0X00"}:
2195 Obj
.FvForceRebase
= False
2197 Obj
.FvForceRebase
= None
2202 ## _GetFvAttributes() method
2204 # Get attributes for FV
2206 # @param self The object pointer
2207 # @param Obj for whom attribute is got
2210 def _GetFvAttributes(self
, FvObj
):
2212 while self
._GetNextWord
():
2215 if name
not in {"ERASE_POLARITY", "MEMORY_MAPPED", \
2216 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2217 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2218 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2219 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2220 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"}:
2224 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2225 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2227 if not self
._GetNextToken
() or self
._Token
.upper() not in {"TRUE", "FALSE", "1", "0"}:
2228 raise Warning.Expected("TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
2230 FvObj
.FvAttributeDict
[name
] = self
._Token
2234 ## _GetFvNameGuid() method
2236 # Get FV GUID for FV
2238 # @param self The object pointer
2239 # @param Obj for whom GUID is got
2242 def _GetFvNameGuid(self
, FvObj
):
2243 if not self
._IsKeyword
("FvNameGuid"):
2246 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2247 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2249 if not self
._GetNextGuid
():
2250 raise Warning.Expected("GUID value", self
.FileName
, self
.CurrentLineNumber
)
2252 FvObj
.FvNameGuid
= self
._Token
2256 def _GetFvNameString(self
, FvObj
):
2257 if not self
._IsKeyword
("FvNameString"):
2260 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2261 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2263 if not self
._GetNextToken
() or self
._Token
.upper() not in {'TRUE', 'FALSE'}:
2264 raise Warning.Expected("TRUE or FALSE for FvNameString", self
.FileName
, self
.CurrentLineNumber
)
2266 FvObj
.FvNameString
= self
._Token
2270 def _GetFvExtEntryStatement(self
, FvObj
):
2271 if not (self
._IsKeyword
("FV_EXT_ENTRY") or self
._IsKeyword
("FV_EXT_ENTRY_TYPE")):
2274 if not self
._IsKeyword
("TYPE"):
2275 raise Warning.Expected("'TYPE'", self
.FileName
, self
.CurrentLineNumber
)
2277 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2278 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2280 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
2281 raise Warning.Expected("Hex FV extension entry type value At Line ", self
.FileName
, self
.CurrentLineNumber
)
2283 FvObj
.FvExtEntryTypeValue
.append(self
._Token
)
2285 if not self
._IsToken
("{"):
2286 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2288 if not self
._IsKeyword
("FILE") and not self
._IsKeyword
("DATA"):
2289 raise Warning.Expected("'FILE' or 'DATA'", self
.FileName
, self
.CurrentLineNumber
)
2291 FvObj
.FvExtEntryType
.append(self
._Token
)
2293 if self
._Token
== 'DATA':
2294 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2295 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2297 if not self
._IsToken
("{"):
2298 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2300 if not self
._GetNextHexNumber
():
2301 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2303 if len(self
._Token
) > 4:
2304 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2306 DataString
= self
._Token
2307 DataString
+= TAB_COMMA_SPLIT
2309 while self
._IsToken
(TAB_COMMA_SPLIT
):
2310 if not self
._GetNextHexNumber
():
2311 raise Warning("Invalid Hex number", 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
)
2314 DataString
+= self
._Token
2315 DataString
+= TAB_COMMA_SPLIT
2317 if not self
._IsToken
(T_CHAR_BRACE_R
):
2318 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2320 if not self
._IsToken
(T_CHAR_BRACE_R
):
2321 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2323 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2324 FvObj
.FvExtEntryData
.append(DataString
)
2326 if self
._Token
== 'FILE':
2327 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2328 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2330 if not self
._GetNextToken
():
2331 raise Warning.Expected("FV Extension Entry file path At Line ", self
.FileName
, self
.CurrentLineNumber
)
2333 FvObj
.FvExtEntryData
.append(self
._Token
)
2335 if not self
._IsToken
(T_CHAR_BRACE_R
):
2336 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2340 ## _GetAprioriSection() method
2342 # Get token statements
2344 # @param self The object pointer
2345 # @param FvObj for whom apriori is got
2346 # @retval True Successfully find apriori statement
2347 # @retval False Not able to find apriori statement
2349 def _GetAprioriSection(self
, FvObj
):
2350 if not self
._IsKeyword
("APRIORI"):
2353 if not self
._IsKeyword
("PEI") and not self
._IsKeyword
("DXE"):
2354 raise Warning.Expected("Apriori file type", self
.FileName
, self
.CurrentLineNumber
)
2355 AprType
= self
._Token
2357 if not self
._IsToken
("{"):
2358 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2360 AprSectionObj
= AprioriSection()
2361 AprSectionObj
.AprioriType
= AprType
2363 self
._GetDefineStatements
(AprSectionObj
)
2366 IsInf
= self
._GetInfStatement
(AprSectionObj
)
2367 IsFile
= self
._GetFileStatement
(AprSectionObj
)
2368 if not IsInf
and not IsFile
:
2371 if not self
._IsToken
(T_CHAR_BRACE_R
):
2372 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2374 FvObj
.AprioriSectionList
.append(AprSectionObj
)
2377 def _ParseInfStatement(self
):
2378 if not self
._IsKeyword
("INF"):
2381 ffsInf
= FfsInfStatement()
2382 self
._GetInfOptions
(ffsInf
)
2384 if not self
._GetNextToken
():
2385 raise Warning.Expected("INF file path", self
.FileName
, self
.CurrentLineNumber
)
2386 ffsInf
.InfFileName
= self
._Token
2387 if not ffsInf
.InfFileName
.endswith('.inf'):
2388 raise Warning.Expected(".inf file path", self
.FileName
, self
.CurrentLineNumber
)
2390 ffsInf
.CurrentLineNum
= self
.CurrentLineNumber
2391 ffsInf
.CurrentLineContent
= self
._CurrentLine
()
2393 #Replace $(SAPCE) with real space
2394 ffsInf
.InfFileName
= ffsInf
.InfFileName
.replace('$(SPACE)', ' ')
2396 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
2397 #do case sensitive check for file path
2398 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2400 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2402 NewFileName
= ffsInf
.InfFileName
2403 if ffsInf
.OverrideGuid
:
2404 NewFileName
= ProcessDuplicatedInf(PathClass(ffsInf
.InfFileName
,GenFdsGlobalVariable
.WorkSpaceDir
), ffsInf
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
).Path
2406 if not NewFileName
in self
.Profile
.InfList
:
2407 self
.Profile
.InfList
.append(NewFileName
)
2408 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2409 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
2411 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
2412 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
2414 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
2416 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
2418 if self
._IsToken
(TAB_VALUE_SPLIT
):
2419 if self
._IsKeyword
('RELOCS_STRIPPED'):
2420 ffsInf
.KeepReloc
= False
2421 elif self
._IsKeyword
('RELOCS_RETAINED'):
2422 ffsInf
.KeepReloc
= True
2424 raise Warning("Unknown reloc strip flag '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2427 ## _GetInfStatement() method
2429 # Get INF statements
2431 # @param self The object pointer
2432 # @param Obj for whom inf statement is got
2433 # @retval True Successfully find inf statement
2434 # @retval False Not able to find inf statement
2436 def _GetInfStatement(self
, Obj
, ForCapsule
=False):
2437 ffsInf
= self
._ParseInfStatement
()
2442 myCapsuleFfs
= CapsuleFfs()
2443 myCapsuleFfs
.Ffs
= ffsInf
2444 Obj
.CapsuleDataList
.append(myCapsuleFfs
)
2446 Obj
.FfsList
.append(ffsInf
)
2449 ## _GetInfOptions() method
2451 # Get options for INF
2453 # @param self The object pointer
2454 # @param FfsInfObj for whom option is got
2456 def _GetInfOptions(self
, FfsInfObj
):
2457 if self
._IsKeyword
("FILE_GUID"):
2458 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2459 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2460 if not self
._GetNextGuid
():
2461 raise Warning.Expected("GUID value", self
.FileName
, self
.CurrentLineNumber
)
2462 FfsInfObj
.OverrideGuid
= self
._Token
2464 if self
._IsKeyword
("RuleOverride"):
2465 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2466 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2467 if not self
._GetNextToken
():
2468 raise Warning.Expected("Rule name", self
.FileName
, self
.CurrentLineNumber
)
2469 FfsInfObj
.Rule
= self
._Token
2471 if self
._IsKeyword
("VERSION"):
2472 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2473 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2474 if not self
._GetNextToken
():
2475 raise Warning.Expected("Version", self
.FileName
, self
.CurrentLineNumber
)
2477 if self
._GetStringData
():
2478 FfsInfObj
.Version
= self
._Token
2480 if self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2481 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2482 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2483 if not self
._GetNextToken
():
2484 raise Warning.Expected("UI name", self
.FileName
, self
.CurrentLineNumber
)
2486 if self
._GetStringData
():
2487 FfsInfObj
.Ui
= self
._Token
2489 if self
._IsKeyword
("USE"):
2490 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2491 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2492 if not self
._GetNextToken
():
2493 raise Warning.Expected("ARCH name", self
.FileName
, self
.CurrentLineNumber
)
2494 FfsInfObj
.UseArch
= self
._Token
2497 if self
._GetNextToken
():
2498 p
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2499 if p
.match(self
._Token
) and p
.match(self
._Token
).span()[1] == len(self
._Token
):
2500 FfsInfObj
.KeyStringList
.append(self
._Token
)
2501 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2507 while self
._GetNextToken
():
2508 if not p
.match(self
._Token
):
2509 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2510 FfsInfObj
.KeyStringList
.append(self
._Token
)
2512 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2515 ## _GetFileStatement() method
2517 # Get FILE statements
2519 # @param self The object pointer
2520 # @param Obj for whom FILE statement is got
2521 # @retval True Successfully find FILE statement
2522 # @retval False Not able to find FILE statement
2524 def _GetFileStatement(self
, Obj
, ForCapsule
= False):
2525 if not self
._IsKeyword
("FILE"):
2528 if not self
._GetNextWord
():
2529 raise Warning.Expected("FFS type", self
.FileName
, self
.CurrentLineNumber
)
2531 if ForCapsule
and self
._Token
== 'DATA':
2536 FfsFileObj
= FileStatement()
2537 FfsFileObj
.FvFileType
= self
._Token
2539 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2540 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2542 if not self
._GetNextGuid
():
2543 if not self
._GetNextWord
():
2544 raise Warning.Expected("File GUID", self
.FileName
, self
.CurrentLineNumber
)
2545 if self
._Token
== 'PCD':
2546 if not self
._IsToken
("("):
2547 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
2548 PcdPair
= self
._GetNextPcdSettings
()
2549 if not self
._IsToken
(")"):
2550 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
2551 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
2553 FfsFileObj
.NameGuid
= self
._Token
2555 self
._GetFilePart
(FfsFileObj
)
2558 capsuleFfs
= CapsuleFfs()
2559 capsuleFfs
.Ffs
= FfsFileObj
2560 Obj
.CapsuleDataList
.append(capsuleFfs
)
2562 Obj
.FfsList
.append(FfsFileObj
)
2566 ## _FileCouldHaveRelocFlag() method
2568 # Check whether reloc strip flag can be set for a file type.
2570 # @param FileType The file type to check with
2571 # @retval True This type could have relocation strip flag
2572 # @retval False No way to have it
2575 def _FileCouldHaveRelocFlag (FileType
):
2576 if FileType
in {SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
, SUP_MODULE_MM_CORE_STANDALONE
, 'PEI_DXE_COMBO'}:
2581 ## _SectionCouldHaveRelocFlag() method
2583 # Check whether reloc strip flag can be set for a section type.
2585 # @param SectionType The section type to check with
2586 # @retval True This type could have relocation strip flag
2587 # @retval False No way to have it
2590 def _SectionCouldHaveRelocFlag (SectionType
):
2591 if SectionType
in {BINARY_FILE_TYPE_TE
, BINARY_FILE_TYPE_PE32
}:
2596 ## _GetFilePart() method
2598 # Get components for FILE statement
2600 # @param self The object pointer
2601 # @param FfsFileObj for whom component is got
2603 def _GetFilePart(self
, FfsFileObj
):
2604 self
._GetFileOpts
(FfsFileObj
)
2606 if not self
._IsToken
("{"):
2607 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2608 if self
._FileCouldHaveRelocFlag
(FfsFileObj
.FvFileType
):
2609 if self
._Token
== 'RELOCS_STRIPPED':
2610 FfsFileObj
.KeepReloc
= False
2612 FfsFileObj
.KeepReloc
= True
2614 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj
.FvFileType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
2616 if not self
._IsToken
("{"):
2617 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2619 if not self
._GetNextToken
():
2620 raise Warning.Expected("File name or section data", self
.FileName
, self
.CurrentLineNumber
)
2622 if self
._Token
== BINARY_FILE_TYPE_FV
:
2623 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2624 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2625 if not self
._GetNextToken
():
2626 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
2627 FfsFileObj
.FvName
= self
._Token
2629 elif self
._Token
== "FD":
2630 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2631 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2632 if not self
._GetNextToken
():
2633 raise Warning.Expected("FD name", self
.FileName
, self
.CurrentLineNumber
)
2634 FfsFileObj
.FdName
= self
._Token
2636 elif self
._Token
in {TAB_DEFINE
, "APRIORI", "SECTION"}:
2638 self
._GetSectionData
(FfsFileObj
)
2640 elif hasattr(FfsFileObj
, 'FvFileType') and FfsFileObj
.FvFileType
== 'RAW':
2642 self
._GetRAWData
(FfsFileObj
)
2645 FfsFileObj
.CurrentLineNum
= self
.CurrentLineNumber
2646 FfsFileObj
.CurrentLineContent
= self
._CurrentLine
()
2647 FfsFileObj
.FileName
= self
._Token
.replace('$(SPACE)', ' ')
2648 self
._VerifyFile
(FfsFileObj
.FileName
)
2650 if not self
._IsToken
(T_CHAR_BRACE_R
):
2651 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2653 ## _GetRAWData() method
2655 # Get RAW data for FILE statement
2657 # @param self The object pointer
2658 # @param FfsFileObj for whom section is got
2660 def _GetRAWData(self
, FfsFileObj
):
2661 FfsFileObj
.FileName
= []
2662 FfsFileObj
.SubAlignment
= []
2665 if self
._GetAlignment
():
2666 if self
._Token
not in ALIGNMENTS
:
2667 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2668 #For FFS, Auto is default option same to ""
2669 if not self
._Token
== "Auto":
2670 AlignValue
= self
._Token
2671 if not self
._GetNextToken
():
2672 raise Warning.Expected("Filename value", self
.FileName
, self
.CurrentLineNumber
)
2674 FileName
= self
._Token
.replace('$(SPACE)', ' ')
2675 if FileName
== T_CHAR_BRACE_R
:
2677 raise Warning.Expected("Filename value", self
.FileName
, self
.CurrentLineNumber
)
2679 self
._VerifyFile
(FileName
)
2680 File
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
)
2681 FfsFileObj
.FileName
.append(File
.Path
)
2682 FfsFileObj
.SubAlignment
.append(AlignValue
)
2684 if self
._IsToken
(T_CHAR_BRACE_R
):
2688 if len(FfsFileObj
.SubAlignment
) == 1:
2689 FfsFileObj
.SubAlignment
= FfsFileObj
.SubAlignment
[0]
2690 if len(FfsFileObj
.FileName
) == 1:
2691 FfsFileObj
.FileName
= FfsFileObj
.FileName
[0]
2693 ## _GetFileOpts() method
2695 # Get options for FILE statement
2697 # @param self The object pointer
2698 # @param FfsFileObj for whom options is got
2700 def _GetFileOpts(self
, FfsFileObj
):
2701 if self
._GetNextToken
():
2702 if TokenFindPattern
.match(self
._Token
):
2703 FfsFileObj
.KeyStringList
.append(self
._Token
)
2704 if self
._IsToken
(TAB_COMMA_SPLIT
):
2705 while self
._GetNextToken
():
2706 if not TokenFindPattern
.match(self
._Token
):
2707 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2708 FfsFileObj
.KeyStringList
.append(self
._Token
)
2710 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2716 if self
._IsKeyword
("FIXED", True):
2717 FfsFileObj
.Fixed
= True
2719 if self
._IsKeyword
("CHECKSUM", True):
2720 FfsFileObj
.CheckSum
= True
2722 if self
._GetAlignment
():
2723 if self
._Token
not in ALIGNMENTS
:
2724 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2725 #For FFS, Auto is default option same to ""
2726 if not self
._Token
== "Auto":
2727 FfsFileObj
.Alignment
= self
._Token
2729 ## _GetAlignment() method
2731 # Return the alignment value
2733 # @param self The object pointer
2734 # @retval True Successfully find alignment
2735 # @retval False Not able to find alignment
2737 def _GetAlignment(self
):
2738 if self
._IsKeyword
("Align", True):
2739 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2740 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2742 if not self
._GetNextToken
():
2743 raise Warning.Expected("alignment value", self
.FileName
, self
.CurrentLineNumber
)
2748 ## _GetSectionData() method
2750 # Get section data for FILE statement
2752 # @param self The object pointer
2753 # @param FfsFileObj for whom section is got
2755 def _GetSectionData(self
, FfsFileObj
):
2756 self
._GetDefineStatements
(FfsFileObj
)
2759 IsLeafSection
= self
._GetLeafSection
(FfsFileObj
)
2760 IsEncapSection
= self
._GetEncapsulationSec
(FfsFileObj
)
2761 if not IsLeafSection
and not IsEncapSection
:
2764 ## _GetLeafSection() method
2766 # Get leaf section for Obj
2768 # @param self The object pointer
2769 # @param Obj for whom leaf section is got
2770 # @retval True Successfully find section statement
2771 # @retval False Not able to find section statement
2773 def _GetLeafSection(self
, Obj
):
2774 OldPos
= self
.GetFileBufferPos()
2776 if not self
._IsKeyword
("SECTION"):
2777 if len(Obj
.SectionList
) == 0:
2778 raise Warning.Expected("SECTION", self
.FileName
, self
.CurrentLineNumber
)
2783 if self
._GetAlignment
():
2784 if self
._Token
not in ALIGNMENTS
:
2785 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2786 AlignValue
= self
._Token
2789 if self
._IsKeyword
("BUILD_NUM"):
2790 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2791 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2793 if not self
._GetNextToken
():
2794 raise Warning.Expected("Build number value", self
.FileName
, self
.CurrentLineNumber
)
2796 BuildNum
= self
._Token
2798 if self
._IsKeyword
("VERSION"):
2799 if AlignValue
== 'Auto':
2800 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2801 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2802 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2803 if not self
._GetNextToken
():
2804 raise Warning.Expected("version", self
.FileName
, self
.CurrentLineNumber
)
2805 VerSectionObj
= VerSection()
2806 VerSectionObj
.Alignment
= AlignValue
2807 VerSectionObj
.BuildNum
= BuildNum
2808 if self
._GetStringData
():
2809 VerSectionObj
.StringData
= self
._Token
2811 VerSectionObj
.FileName
= self
._Token
2812 Obj
.SectionList
.append(VerSectionObj
)
2814 elif self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2815 if AlignValue
== 'Auto':
2816 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2817 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2818 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2819 if not self
._GetNextToken
():
2820 raise Warning.Expected("UI", self
.FileName
, self
.CurrentLineNumber
)
2821 UiSectionObj
= UiSection()
2822 UiSectionObj
.Alignment
= AlignValue
2823 if self
._GetStringData
():
2824 UiSectionObj
.StringData
= self
._Token
2826 UiSectionObj
.FileName
= self
._Token
2827 Obj
.SectionList
.append(UiSectionObj
)
2829 elif self
._IsKeyword
("FV_IMAGE"):
2830 if AlignValue
== 'Auto':
2831 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2832 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2833 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2834 if not self
._GetNextToken
():
2835 raise Warning.Expected("FV name or FV file path", self
.FileName
, self
.CurrentLineNumber
)
2837 FvName
= self
._Token
2840 if self
._IsToken
("{"):
2842 FvObj
.UiFvName
= FvName
.upper()
2843 self
._GetDefineStatements
(FvObj
)
2845 self
._GetBlockStatement
(FvObj
)
2846 self
._GetSetStatements
(FvObj
)
2847 self
._GetFvAlignment
(FvObj
)
2848 self
._GetFvAttributes
(FvObj
)
2851 IsInf
= self
._GetInfStatement
(FvObj
)
2852 IsFile
= self
._GetFileStatement
(FvObj
)
2853 if not IsInf
and not IsFile
:
2856 if not self
._IsToken
(T_CHAR_BRACE_R
):
2857 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2859 FvImageSectionObj
= FvImageSection()
2860 FvImageSectionObj
.Alignment
= AlignValue
2861 if FvObj
is not None:
2862 FvImageSectionObj
.Fv
= FvObj
2863 FvImageSectionObj
.FvName
= None
2865 FvImageSectionObj
.FvName
= FvName
.upper()
2866 FvImageSectionObj
.FvFileName
= FvName
2868 Obj
.SectionList
.append(FvImageSectionObj
)
2870 elif self
._IsKeyword
("PEI_DEPEX_EXP") or self
._IsKeyword
("DXE_DEPEX_EXP") or self
._IsKeyword
("SMM_DEPEX_EXP"):
2871 if AlignValue
== 'Auto':
2872 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2873 DepexSectionObj
= DepexSection()
2874 DepexSectionObj
.Alignment
= AlignValue
2875 DepexSectionObj
.DepexType
= self
._Token
2877 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2878 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2879 if not self
._IsToken
("{"):
2880 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2881 if not self
._SkipToToken
(T_CHAR_BRACE_R
):
2882 raise Warning.Expected("Depex expression ending '}'", self
.FileName
, self
.CurrentLineNumber
)
2884 DepexSectionObj
.Expression
= self
._SkippedChars
.rstrip(T_CHAR_BRACE_R
)
2885 Obj
.SectionList
.append(DepexSectionObj
)
2888 if not self
._GetNextWord
():
2889 raise Warning.Expected("section type", self
.FileName
, self
.CurrentLineNumber
)
2891 # Encapsulation section appear, UndoToken and return
2892 if self
._Token
== "COMPRESS" or self
._Token
== "GUIDED":
2893 self
.SetFileBufferPos(OldPos
)
2896 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
,\
2897 BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX
}:
2898 raise Warning("Unknown section type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2899 if AlignValue
== 'Auto'and (not self
._Token
== BINARY_FILE_TYPE_PE32
) and (not self
._Token
== BINARY_FILE_TYPE_TE
):
2900 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2903 DataSectionObj
= DataSection()
2904 DataSectionObj
.Alignment
= AlignValue
2905 DataSectionObj
.SecType
= self
._Token
2907 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2908 if self
._FileCouldHaveRelocFlag
(Obj
.FvFileType
) and self
._SectionCouldHaveRelocFlag
(DataSectionObj
.SecType
):
2909 if self
._Token
== 'RELOCS_STRIPPED':
2910 DataSectionObj
.KeepReloc
= False
2912 DataSectionObj
.KeepReloc
= True
2914 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
)
2916 if self
._IsToken
(TAB_EQUAL_SPLIT
):
2917 if not self
._GetNextToken
():
2918 raise Warning.Expected("section file path", self
.FileName
, self
.CurrentLineNumber
)
2919 DataSectionObj
.SectFileName
= self
._Token
2920 self
._VerifyFile
(DataSectionObj
.SectFileName
)
2922 if not self
._GetCglSection
(DataSectionObj
):
2925 Obj
.SectionList
.append(DataSectionObj
)
2931 # Check if file exists or not:
2932 # If current phase if GenFds, the file must exist;
2933 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
2934 # @param FileName: File path to be verified.
2936 def _VerifyFile(self
, FileName
):
2937 if FileName
.replace(TAB_WORKSPACE
, '').find('$') != -1:
2939 if not GlobalData
.gAutoGenPhase
or not self
._GetMacroValue
(TAB_DSC_DEFINES_OUTPUT_DIRECTORY
) in FileName
:
2940 ErrorCode
, ErrorInfo
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2942 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2944 ## _GetCglSection() method
2946 # Get compressed or GUIDed section for Obj
2948 # @param self The object pointer
2949 # @param Obj for whom leaf section is got
2950 # @param AlignValue alignment value for complex section
2951 # @retval True Successfully find section statement
2952 # @retval False Not able to find section statement
2954 def _GetCglSection(self
, Obj
, AlignValue
= None):
2956 if self
._IsKeyword
("COMPRESS"):
2958 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
2961 if not self
._IsToken
("{"):
2962 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2964 CompressSectionObj
= CompressSection()
2965 CompressSectionObj
.Alignment
= AlignValue
2966 CompressSectionObj
.CompType
= type
2967 # Recursive sections...
2969 IsLeafSection
= self
._GetLeafSection
(CompressSectionObj
)
2970 IsEncapSection
= self
._GetEncapsulationSec
(CompressSectionObj
)
2971 if not IsLeafSection
and not IsEncapSection
:
2975 if not self
._IsToken
(T_CHAR_BRACE_R
):
2976 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2977 Obj
.SectionList
.append(CompressSectionObj
)
2980 elif self
._IsKeyword
("GUIDED"):
2982 if self
._GetNextGuid
():
2983 GuidValue
= self
._Token
2985 AttribDict
= self
._GetGuidAttrib
()
2986 if not self
._IsToken
("{"):
2987 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2988 GuidSectionObj
= GuidSection()
2989 GuidSectionObj
.Alignment
= AlignValue
2990 GuidSectionObj
.NameGuid
= GuidValue
2991 GuidSectionObj
.SectionType
= "GUIDED"
2992 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
2993 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
2994 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
2995 # Recursive sections...
2997 IsLeafSection
= self
._GetLeafSection
(GuidSectionObj
)
2998 IsEncapSection
= self
._GetEncapsulationSec
(GuidSectionObj
)
2999 if not IsLeafSection
and not IsEncapSection
:
3002 if not self
._IsToken
(T_CHAR_BRACE_R
):
3003 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3004 Obj
.SectionList
.append(GuidSectionObj
)
3010 ## _GetGuidAttri() method
3012 # Get attributes for GUID section
3014 # @param self The object pointer
3015 # @retval AttribDict Dictionary of key-value pair of section attributes
3017 def _GetGuidAttrib(self
):
3019 AttribDict
["PROCESSING_REQUIRED"] = "NONE"
3020 AttribDict
["AUTH_STATUS_VALID"] = "NONE"
3021 AttribDict
["EXTRA_HEADER_SIZE"] = -1
3022 while self
._IsKeyword
("PROCESSING_REQUIRED") or self
._IsKeyword
("AUTH_STATUS_VALID") \
3023 or self
._IsKeyword
("EXTRA_HEADER_SIZE"):
3024 AttribKey
= self
._Token
3026 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3027 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3029 if not self
._GetNextToken
():
3030 raise Warning.Expected("TRUE(1)/FALSE(0)/Number", self
.FileName
, self
.CurrentLineNumber
)
3031 elif AttribKey
== "EXTRA_HEADER_SIZE":
3033 if self
._Token
[0:2].upper() == "0X":
3036 AttribDict
[AttribKey
] = int(self
._Token
, Base
)
3039 raise Warning.Expected("Number", self
.FileName
, self
.CurrentLineNumber
)
3040 elif self
._Token
.upper() not in {"TRUE", "FALSE", "1", "0"}:
3041 raise Warning.Expected("TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
3042 AttribDict
[AttribKey
] = self
._Token
3046 ## _GetEncapsulationSec() method
3048 # Get encapsulation section for FILE
3050 # @param self The object pointer
3051 # @param FfsFile for whom section is got
3052 # @retval True Successfully find section statement
3053 # @retval False Not able to find section statement
3055 def _GetEncapsulationSec(self
, FfsFileObj
):
3056 OldPos
= self
.GetFileBufferPos()
3057 if not self
._IsKeyword
("SECTION"):
3058 if len(FfsFileObj
.SectionList
) == 0:
3059 raise Warning.Expected("SECTION", self
.FileName
, self
.CurrentLineNumber
)
3064 if self
._GetAlignment
():
3065 if self
._Token
not in ALIGNMENT_NOAUTO
:
3066 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3067 AlignValue
= self
._Token
3069 if not self
._GetCglSection
(FfsFileObj
, AlignValue
):
3070 self
.SetFileBufferPos(OldPos
)
3076 if not self
._GetNextToken
():
3078 S
= self
._Token
.upper()
3079 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FMPPAYLOAD."):
3080 self
.SectionParser(S
)
3085 self
._SkipToToken
("[FMPPAYLOAD.", True)
3086 FmpUiName
= self
._GetUiName
().upper()
3087 if FmpUiName
in self
.Profile
.FmpPayloadDict
:
3088 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName
, self
.FileName
, self
.CurrentLineNumber
)
3090 FmpData
= CapsulePayload()
3091 FmpData
.UiName
= FmpUiName
3093 if not self
._IsToken
(TAB_SECTION_END
):
3094 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3096 if not self
._GetNextToken
():
3097 raise Warning("The FMP payload section is empty!", self
.FileName
, self
.CurrentLineNumber
)
3098 FmpKeyList
= ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']
3099 while self
._Token
in FmpKeyList
:
3101 FmpKeyList
.remove(Name
)
3102 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3103 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3104 if Name
== 'IMAGE_TYPE_ID':
3105 if not self
._GetNextGuid
():
3106 raise Warning.Expected("GUID value for IMAGE_TYPE_ID.", self
.FileName
, self
.CurrentLineNumber
)
3107 FmpData
.ImageTypeId
= self
._Token
3108 elif Name
== 'CERTIFICATE_GUID':
3109 if not self
._GetNextGuid
():
3110 raise Warning.Expected("GUID value for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3111 FmpData
.Certificate_Guid
= self
._Token
3112 if UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_RSA2048_SHA256_GUID
and UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_PKCS7_GUID
:
3113 raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3115 if not self
._GetNextToken
():
3116 raise Warning.Expected("value of %s" % Name
, self
.FileName
, self
.CurrentLineNumber
)
3118 if Name
== 'IMAGE_HEADER_INIT_VERSION':
3119 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3120 FmpData
.Version
= Value
3121 elif Name
== 'IMAGE_INDEX':
3122 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3123 FmpData
.ImageIndex
= Value
3124 elif Name
== 'HARDWARE_INSTANCE':
3125 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3126 FmpData
.HardwareInstance
= Value
3127 elif Name
== 'MONOTONIC_COUNT':
3128 if FdfParser
._Verify
(Name
, Value
, 'UINT64'):
3129 FmpData
.MonotonicCount
= Value
3130 if FmpData
.MonotonicCount
.upper().startswith('0X'):
3131 FmpData
.MonotonicCount
= int(FmpData
.MonotonicCount
, 16)
3133 FmpData
.MonotonicCount
= int(FmpData
.MonotonicCount
)
3134 if not self
._GetNextToken
():
3139 if (FmpData
.MonotonicCount
and not FmpData
.Certificate_Guid
) or (not FmpData
.MonotonicCount
and FmpData
.Certificate_Guid
):
3140 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")
3142 # Only the IMAGE_TYPE_ID is required item
3143 if FmpKeyList
and 'IMAGE_TYPE_ID' in FmpKeyList
:
3144 raise Warning("'IMAGE_TYPE_ID' in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3145 # get the Image file and Vendor code file
3146 self
._GetFMPCapsuleData
(FmpData
)
3147 if not FmpData
.ImageFile
:
3148 raise Warning("Missing image file in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3149 # check whether more than one Vendor code file
3150 if len(FmpData
.VendorCodeFile
) > 1:
3151 raise Warning("Vendor code file max of 1 per FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3152 self
.Profile
.FmpPayloadDict
[FmpUiName
] = FmpData
3155 ## _GetCapsule() method
3157 # Get capsule section contents and store its data into capsule list of self.Profile
3159 # @param self The object pointer
3160 # @retval True Successfully find a capsule
3161 # @retval False Not able to find a capsule
3163 def _GetCapsule(self
):
3164 if not self
._GetNextToken
():
3167 S
= self
._Token
.upper()
3168 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[CAPSULE."):
3169 self
.SectionParser(S
)
3174 if not self
._IsToken
("[CAPSULE.", True):
3175 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3176 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3177 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3178 raise Warning.Expected("[Capsule.]", self
.FileName
, self
.CurrentLineNumber
)
3180 CapsuleObj
= Capsule()
3182 CapsuleName
= self
._GetUiName
()
3184 raise Warning.Expected("capsule name", self
.FileName
, self
.CurrentLineNumber
)
3186 CapsuleObj
.UiCapsuleName
= CapsuleName
.upper()
3188 if not self
._IsToken
(TAB_SECTION_END
):
3189 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3191 if self
._IsKeyword
("CREATE_FILE"):
3192 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3193 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3195 if not self
._GetNextToken
():
3196 raise Warning.Expected("file name", self
.FileName
, self
.CurrentLineNumber
)
3198 CapsuleObj
.CreateFile
= self
._Token
3200 self
._GetCapsuleStatements
(CapsuleObj
)
3201 self
.Profile
.CapsuleDict
[CapsuleObj
.UiCapsuleName
] = CapsuleObj
3204 ## _GetCapsuleStatements() method
3206 # Get statements for capsule
3208 # @param self The object pointer
3209 # @param Obj for whom statements are got
3211 def _GetCapsuleStatements(self
, Obj
):
3212 self
._GetCapsuleTokens
(Obj
)
3213 self
._GetDefineStatements
(Obj
)
3214 self
._GetSetStatements
(Obj
)
3215 self
._GetCapsuleData
(Obj
)
3217 ## _GetCapsuleTokens() method
3219 # Get token statements for capsule
3221 # @param self The object pointer
3222 # @param Obj for whom token statements are got
3224 def _GetCapsuleTokens(self
, Obj
):
3225 if not self
._GetNextToken
():
3227 while self
._Token
in {"CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"}:
3228 Name
= self
._Token
.strip()
3229 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3230 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3231 if not self
._GetNextToken
():
3232 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
3233 if Name
== 'CAPSULE_FLAGS':
3234 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3235 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3236 Value
= self
._Token
.strip()
3237 while self
._IsToken
(TAB_COMMA_SPLIT
):
3238 Value
+= TAB_COMMA_SPLIT
3239 if not self
._GetNextToken
():
3240 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
3241 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3242 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3243 Value
+= self
._Token
.strip()
3244 elif Name
== 'OEM_CAPSULE_FLAGS':
3245 Value
= self
._Token
.strip()
3246 if not Value
.upper().startswith('0X'):
3247 raise Warning.Expected("hex value starting with 0x", self
.FileName
, self
.CurrentLineNumber
)
3249 Value
= int(Value
, 0)
3251 raise Warning.Expected("hex string failed to convert to value", self
.FileName
, self
.CurrentLineNumber
)
3252 if not 0x0000 <= Value
<= 0xFFFF:
3253 raise Warning.Expected("hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3254 Value
= self
._Token
.strip()
3256 Value
= self
._Token
.strip()
3257 Obj
.TokensDict
[Name
] = Value
3258 if not self
._GetNextToken
():
3262 ## _GetCapsuleData() method
3264 # Get capsule data for capsule
3266 # @param self The object pointer
3267 # @param Obj for whom capsule data are got
3269 def _GetCapsuleData(self
, Obj
):
3271 IsInf
= self
._GetInfStatement
(Obj
, True)
3272 IsFile
= self
._GetFileStatement
(Obj
, True)
3273 IsFv
= self
._GetFvStatement
(Obj
)
3274 IsFd
= self
._GetFdStatement
(Obj
)
3275 IsAnyFile
= self
._GetAnyFileStatement
(Obj
)
3276 IsAfile
= self
._GetAfileStatement
(Obj
)
3277 IsFmp
= self
._GetFmpStatement
(Obj
)
3278 if not (IsInf
or IsFile
or IsFv
or IsFd
or IsAnyFile
or IsAfile
or IsFmp
):
3281 ## _GetFMPCapsuleData() method
3283 # Get capsule data for FMP capsule
3285 # @param self The object pointer
3286 # @param Obj for whom capsule data are got
3288 def _GetFMPCapsuleData(self
, Obj
):
3290 IsFv
= self
._GetFvStatement
(Obj
, True)
3291 IsFd
= self
._GetFdStatement
(Obj
, True)
3292 IsAnyFile
= self
._GetAnyFileStatement
(Obj
, True)
3293 if not (IsFv
or IsFd
or IsAnyFile
):
3296 ## _GetFvStatement() method
3298 # Get FV for capsule
3300 # @param self The object pointer
3301 # @param CapsuleObj for whom FV is got
3302 # @retval True Successfully find a FV statement
3303 # @retval False Not able to find a FV statement
3305 def _GetFvStatement(self
, CapsuleObj
, FMPCapsule
= False):
3306 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3309 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3310 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3312 if not self
._GetNextToken
():
3313 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
3315 if self
._Token
.upper() not in self
.Profile
.FvDict
:
3316 raise Warning("FV name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3318 myCapsuleFv
= CapsuleFv()
3319 myCapsuleFv
.FvName
= self
._Token
3321 if not CapsuleObj
.ImageFile
:
3322 CapsuleObj
.ImageFile
.append(myCapsuleFv
)
3324 CapsuleObj
.VendorCodeFile
.append(myCapsuleFv
)
3326 CapsuleObj
.CapsuleDataList
.append(myCapsuleFv
)
3329 ## _GetFdStatement() method
3331 # Get FD for capsule
3333 # @param self The object pointer
3334 # @param CapsuleObj for whom FD is got
3335 # @retval True Successfully find a FD statement
3336 # @retval False Not able to find a FD statement
3338 def _GetFdStatement(self
, CapsuleObj
, FMPCapsule
= False):
3339 if not self
._IsKeyword
("FD"):
3342 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3343 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3345 if not self
._GetNextToken
():
3346 raise Warning.Expected("FD name", self
.FileName
, self
.CurrentLineNumber
)
3348 if self
._Token
.upper() not in self
.Profile
.FdDict
:
3349 raise Warning("FD name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3351 myCapsuleFd
= CapsuleFd()
3352 myCapsuleFd
.FdName
= self
._Token
3354 if not CapsuleObj
.ImageFile
:
3355 CapsuleObj
.ImageFile
.append(myCapsuleFd
)
3357 CapsuleObj
.VendorCodeFile
.append(myCapsuleFd
)
3359 CapsuleObj
.CapsuleDataList
.append(myCapsuleFd
)
3362 def _GetFmpStatement(self
, CapsuleObj
):
3363 if not self
._IsKeyword
("FMP_PAYLOAD"):
3364 if not self
._IsKeyword
("FMP"):
3367 if not self
._IsKeyword
("PAYLOAD"):
3371 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3372 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3374 if not self
._GetNextToken
():
3375 raise Warning.Expected("payload name after FMP_PAYLOAD =", self
.FileName
, self
.CurrentLineNumber
)
3376 Payload
= self
._Token
.upper()
3377 if Payload
not in self
.Profile
.FmpPayloadDict
:
3378 raise Warning("This FMP Payload does not exist: %s" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3379 CapsuleObj
.FmpPayloadList
.append(self
.Profile
.FmpPayloadDict
[Payload
])
3382 def _ParseRawFileStatement(self
):
3383 if not self
._IsKeyword
("FILE"):
3386 if not self
._IsKeyword
("DATA"):
3390 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3391 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3393 if not self
._GetNextToken
():
3394 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
3396 AnyFileName
= self
._Token
3397 self
._VerifyFile
(AnyFileName
)
3399 if not os
.path
.isabs(AnyFileName
):
3400 AnyFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, AnyFileName
)
3404 ## _GetAnyFileStatement() method
3406 # Get AnyFile for capsule
3408 # @param self The object pointer
3409 # @param CapsuleObj for whom AnyFile is got
3410 # @retval True Successfully find a Anyfile statement
3411 # @retval False Not able to find a AnyFile statement
3413 def _GetAnyFileStatement(self
, CapsuleObj
, FMPCapsule
= False):
3414 AnyFileName
= self
._ParseRawFileStatement
()
3418 myCapsuleAnyFile
= CapsuleAnyFile()
3419 myCapsuleAnyFile
.FileName
= AnyFileName
3421 if not CapsuleObj
.ImageFile
:
3422 CapsuleObj
.ImageFile
.append(myCapsuleAnyFile
)
3424 CapsuleObj
.VendorCodeFile
.append(myCapsuleAnyFile
)
3426 CapsuleObj
.CapsuleDataList
.append(myCapsuleAnyFile
)
3429 ## _GetAfileStatement() method
3431 # Get Afile for capsule
3433 # @param self The object pointer
3434 # @param CapsuleObj for whom Afile is got
3435 # @retval True Successfully find a Afile statement
3436 # @retval False Not able to find a Afile statement
3438 def _GetAfileStatement(self
, CapsuleObj
):
3439 if not self
._IsKeyword
("APPEND"):
3442 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3443 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3445 if not self
._GetNextToken
():
3446 raise Warning.Expected("Afile name", self
.FileName
, self
.CurrentLineNumber
)
3448 AfileName
= self
._Token
3449 AfileBaseName
= os
.path
.basename(AfileName
)
3451 if os
.path
.splitext(AfileBaseName
)[1] not in {".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"}:
3452 raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \
3453 self
.FileName
, self
.CurrentLineNumber
)
3455 if not os
.path
.isabs(AfileName
):
3456 AfileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(AfileName
)
3457 self
._VerifyFile
(AfileName
)
3459 if not os
.path
.exists(AfileName
):
3460 raise Warning('%s does not exist' % AfileName
, self
.FileName
, self
.CurrentLineNumber
)
3464 myCapsuleAfile
= CapsuleAfile()
3465 myCapsuleAfile
.FileName
= AfileName
3466 CapsuleObj
.CapsuleDataList
.append(myCapsuleAfile
)
3469 ## _GetRule() method
3471 # Get Rule section contents and store its data into rule list of self.Profile
3473 # @param self The object pointer
3474 # @retval True Successfully find a Rule
3475 # @retval False Not able to find a Rule
3478 if not self
._GetNextToken
():
3481 S
= self
._Token
.upper()
3482 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[RULE."):
3483 self
.SectionParser(S
)
3487 if not self
._IsToken
("[Rule.", True):
3488 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3489 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3490 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3491 raise Warning.Expected("[Rule.]", self
.FileName
, self
.CurrentLineNumber
)
3493 if not self
._SkipToToken
(TAB_SPLIT
):
3494 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
3496 Arch
= self
._SkippedChars
.rstrip(TAB_SPLIT
)
3497 if Arch
.upper() not in ARCH_SET_FULL
:
3498 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
3500 ModuleType
= self
._GetModuleType
()
3503 if self
._IsToken
(TAB_SPLIT
):
3504 if not self
._GetNextWord
():
3505 raise Warning.Expected("template name", self
.FileName
, self
.CurrentLineNumber
)
3506 TemplateName
= self
._Token
3508 if not self
._IsToken
(TAB_SECTION_END
):
3509 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3511 RuleObj
= self
._GetRuleFileStatements
()
3512 RuleObj
.Arch
= Arch
.upper()
3513 RuleObj
.ModuleType
= ModuleType
3514 RuleObj
.TemplateName
= TemplateName
3515 if TemplateName
== '':
3516 self
.Profile
.RuleDict
['RULE' + \
3520 ModuleType
.upper() ] = RuleObj
3522 self
.Profile
.RuleDict
['RULE' + \
3526 ModuleType
.upper() + \
3528 TemplateName
.upper() ] = RuleObj
3531 ## _GetModuleType() method
3533 # Return the module type
3535 # @param self The object pointer
3536 # @retval string module type
3538 def _GetModuleType(self
):
3539 if not self
._GetNextWord
():
3540 raise Warning.Expected("Module type", self
.FileName
, self
.CurrentLineNumber
)
3541 if self
._Token
.upper() not in {
3542 SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3543 SUP_MODULE_DXE_CORE
, SUP_MODULE_DXE_DRIVER
,
3544 SUP_MODULE_DXE_SAL_DRIVER
, SUP_MODULE_DXE_SMM_DRIVER
,
3545 SUP_MODULE_DXE_RUNTIME_DRIVER
, SUP_MODULE_UEFI_DRIVER
,
3546 SUP_MODULE_UEFI_APPLICATION
, SUP_MODULE_USER_DEFINED
,
3547 TAB_DEFAULT
, SUP_MODULE_BASE
,
3548 EDK_COMPONENT_TYPE_SECURITY_CORE
,
3549 EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER
,
3550 EDK_COMPONENT_TYPE_PIC_PEIM
,
3551 EDK_COMPONENT_TYPE_RELOCATABLE_PEIM
, "PE32_PEIM",
3552 EDK_COMPONENT_TYPE_BS_DRIVER
, EDK_COMPONENT_TYPE_RT_DRIVER
,
3553 EDK_COMPONENT_TYPE_SAL_RT_DRIVER
,
3554 EDK_COMPONENT_TYPE_APPLICATION
, "ACPITABLE",
3555 SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3556 SUP_MODULE_MM_CORE_STANDALONE
}:
3557 raise Warning("Unknown Module type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3560 ## _GetFileExtension() method
3562 # Return the file extension
3564 # @param self The object pointer
3565 # @retval string file name extension
3567 def _GetFileExtension(self
):
3568 if not self
._IsToken
(TAB_SPLIT
):
3569 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
3572 if self
._GetNextToken
():
3573 if FileExtensionPattern
.match(self
._Token
):
3575 return TAB_SPLIT
+ Ext
3577 raise Warning("Unknown file extension '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3580 raise Warning.Expected("file extension", self
.FileName
, self
.CurrentLineNumber
)
3582 ## _GetRuleFileStatement() method
3586 # @param self The object pointer
3587 # @retval Rule Rule object
3589 def _GetRuleFileStatements(self
):
3590 if not self
._IsKeyword
("FILE"):
3591 raise Warning.Expected("FILE", self
.FileName
, self
.CurrentLineNumber
)
3593 if not self
._GetNextWord
():
3594 raise Warning.Expected("FFS type", self
.FileName
, self
.CurrentLineNumber
)
3596 Type
= self
._Token
.strip().upper()
3597 if Type
not in {"RAW", "FREEFORM", SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3598 "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE
, EDK_COMPONENT_TYPE_APPLICATION
,
3599 "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3600 SUP_MODULE_MM_CORE_STANDALONE
}:
3601 raise Warning("Unknown FV type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3603 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3604 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3606 if not self
._IsKeyword
("$(NAMED_GUID)"):
3607 if not self
._GetNextWord
():
3608 NamedGuid
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:].split()[0].strip()
3609 if GlobalData
.gGuidPatternEnd
.match(NamedGuid
):
3610 self
.CurrentOffsetWithinLine
+= len(NamedGuid
)
3611 self
._Token
= NamedGuid
3613 raise Warning.Expected("$(NAMED_GUID)", self
.FileName
, self
.CurrentLineNumber
)
3614 if self
._Token
== 'PCD':
3615 if not self
._IsToken
("("):
3616 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3617 PcdPair
= self
._GetNextPcdSettings
()
3618 if not self
._IsToken
(")"):
3619 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3620 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3622 NameGuid
= self
._Token
3625 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3626 if self
._FileCouldHaveRelocFlag
(Type
):
3627 if self
._Token
== 'RELOCS_STRIPPED':
3632 raise Warning("File type %s could not have reloc strip flag%d" % (Type
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3635 if self
._GetNextToken
():
3636 if TokenFindPattern
.match(self
._Token
):
3637 KeyStringList
.append(self
._Token
)
3638 if self
._IsToken
(TAB_COMMA_SPLIT
):
3639 while self
._GetNextToken
():
3640 if not TokenFindPattern
.match(self
._Token
):
3641 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
3642 KeyStringList
.append(self
._Token
)
3644 if not self
._IsToken
(TAB_COMMA_SPLIT
):
3652 if self
._IsKeyword
("Fixed", True):
3656 if self
._IsKeyword
("CheckSum", True):
3660 if self
._GetAlignment
():
3661 if self
._Token
not in ALIGNMENTS
:
3662 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3663 #For FFS, Auto is default option same to ""
3664 if not self
._Token
== "Auto":
3665 AlignValue
= self
._Token
3667 if self
._IsToken
("{"):
3668 # Complex file rule expected
3669 NewRule
= RuleComplexFile()
3670 NewRule
.FvFileType
= Type
3671 NewRule
.NameGuid
= NameGuid
3672 NewRule
.Alignment
= AlignValue
3673 NewRule
.CheckSum
= CheckSum
3674 NewRule
.Fixed
= Fixed
3675 NewRule
.KeyStringList
= KeyStringList
3676 if KeepReloc
is not None:
3677 NewRule
.KeepReloc
= KeepReloc
3680 IsEncapsulate
= self
._GetRuleEncapsulationSection
(NewRule
)
3681 IsLeaf
= self
._GetEfiSection
(NewRule
)
3682 if not IsEncapsulate
and not IsLeaf
:
3685 if not self
._IsToken
(T_CHAR_BRACE_R
):
3686 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3691 # Simple file rule expected
3692 if not self
._GetNextWord
():
3693 raise Warning.Expected("leaf section type", self
.FileName
, self
.CurrentLineNumber
)
3695 SectionName
= self
._Token
3697 if SectionName
not in {
3698 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3699 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3700 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3701 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3702 BINARY_FILE_TYPE_SMM_DEPEX
}:
3703 raise Warning("Unknown leaf section name '%s'" % SectionName
, self
.FileName
, self
.CurrentLineNumber
)
3706 if self
._IsKeyword
("Fixed", True):
3709 if self
._IsKeyword
("CheckSum", True):
3713 if self
._GetAlignment
():
3714 if self
._Token
not in ALIGNMENTS
:
3715 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3716 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3717 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3718 SectAlignment
= self
._Token
3721 if self
._IsToken
(TAB_VALUE_SPLIT
):
3722 Ext
= self
._GetFileExtension
()
3723 elif not self
._GetNextToken
():
3724 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
3726 NewRule
= RuleSimpleFile()
3727 NewRule
.SectionType
= SectionName
3728 NewRule
.FvFileType
= Type
3729 NewRule
.NameGuid
= NameGuid
3730 NewRule
.Alignment
= AlignValue
3731 NewRule
.SectAlignment
= SectAlignment
3732 NewRule
.CheckSum
= CheckSum
3733 NewRule
.Fixed
= Fixed
3734 NewRule
.KeyStringList
= KeyStringList
3735 if KeepReloc
is not None:
3736 NewRule
.KeepReloc
= KeepReloc
3737 NewRule
.FileExtension
= Ext
3738 NewRule
.FileName
= self
._Token
3741 ## _GetEfiSection() method
3743 # Get section list for Rule
3745 # @param self The object pointer
3746 # @param Obj for whom section is got
3747 # @retval True Successfully find section statement
3748 # @retval False Not able to find section statement
3750 def _GetEfiSection(self
, Obj
):
3751 OldPos
= self
.GetFileBufferPos()
3752 if not self
._GetNextWord
():
3754 SectionName
= self
._Token
3756 if SectionName
not in {
3757 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3758 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3759 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3760 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3761 BINARY_FILE_TYPE_SMM_DEPEX
, BINARY_FILE_TYPE_GUID
}:
3765 if SectionName
== "FV_IMAGE":
3766 FvImageSectionObj
= FvImageSection()
3767 if self
._IsKeyword
("FV_IMAGE"):
3769 if self
._IsToken
("{"):
3771 self
._GetDefineStatements
(FvObj
)
3772 self
._GetBlockStatement
(FvObj
)
3773 self
._GetSetStatements
(FvObj
)
3774 self
._GetFvAlignment
(FvObj
)
3775 self
._GetFvAttributes
(FvObj
)
3776 self
._GetAprioriSection
(FvObj
)
3777 self
._GetAprioriSection
(FvObj
)
3780 IsInf
= self
._GetInfStatement
(FvObj
)
3781 IsFile
= self
._GetFileStatement
(FvObj
)
3782 if not IsInf
and not IsFile
:
3785 if not self
._IsToken
(T_CHAR_BRACE_R
):
3786 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3787 FvImageSectionObj
.Fv
= FvObj
3788 FvImageSectionObj
.FvName
= None
3791 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3792 raise Warning.Expected("'FV'", self
.FileName
, self
.CurrentLineNumber
)
3793 FvImageSectionObj
.FvFileType
= self
._Token
3795 if self
._GetAlignment
():
3796 if self
._Token
not in ALIGNMENT_NOAUTO
:
3797 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3798 FvImageSectionObj
.Alignment
= self
._Token
3800 if self
._IsToken
(TAB_VALUE_SPLIT
):
3801 FvImageSectionObj
.FvFileExtension
= self
._GetFileExtension
()
3802 elif self
._GetNextToken
():
3803 if self
._Token
not in {
3804 T_CHAR_BRACE_R
, "COMPAT16", BINARY_FILE_TYPE_PE32
,
3805 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3806 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3807 BINARY_FILE_TYPE_UI
, "VERSION",
3808 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3809 BINARY_FILE_TYPE_SMM_DEPEX
}:
3810 FvImageSectionObj
.FvFileName
= self
._Token
3814 raise Warning.Expected("FV file name", self
.FileName
, self
.CurrentLineNumber
)
3816 Obj
.SectionList
.append(FvImageSectionObj
)
3819 EfiSectionObj
= EfiSection()
3820 EfiSectionObj
.SectionType
= SectionName
3822 if not self
._GetNextToken
():
3823 raise Warning.Expected("file type", self
.FileName
, self
.CurrentLineNumber
)
3825 if self
._Token
== "STRING":
3826 if not self
._RuleSectionCouldHaveString
(EfiSectionObj
.SectionType
):
3827 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3829 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3830 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3832 if not self
._GetNextToken
():
3833 raise Warning.Expected("Quoted String", self
.FileName
, self
.CurrentLineNumber
)
3835 if self
._GetStringData
():
3836 EfiSectionObj
.StringData
= self
._Token
3838 if self
._IsKeyword
("BUILD_NUM"):
3839 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3840 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3842 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3843 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3844 if not self
._GetNextToken
():
3845 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3846 EfiSectionObj
.BuildNum
= self
._Token
3849 EfiSectionObj
.FileType
= self
._Token
3850 self
._CheckRuleSectionFileType
(EfiSectionObj
.SectionType
, EfiSectionObj
.FileType
)
3852 if self
._IsKeyword
("Optional"):
3853 if not self
._RuleSectionCouldBeOptional
(EfiSectionObj
.SectionType
):
3854 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3855 EfiSectionObj
.Optional
= True
3857 if self
._IsKeyword
("BUILD_NUM"):
3858 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3859 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3861 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3862 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3863 if not self
._GetNextToken
():
3864 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3865 EfiSectionObj
.BuildNum
= self
._Token
3867 if self
._GetAlignment
():
3868 if self
._Token
not in ALIGNMENTS
:
3869 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3870 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3871 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3872 EfiSectionObj
.Alignment
= self
._Token
3874 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3875 if self
._SectionCouldHaveRelocFlag
(EfiSectionObj
.SectionType
):
3876 if self
._Token
== 'RELOCS_STRIPPED':
3877 EfiSectionObj
.KeepReloc
= False
3879 EfiSectionObj
.KeepReloc
= True
3880 if Obj
.KeepReloc
is not None and Obj
.KeepReloc
!= EfiSectionObj
.KeepReloc
:
3881 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3883 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3886 if self
._IsToken
(TAB_VALUE_SPLIT
):
3887 EfiSectionObj
.FileExtension
= self
._GetFileExtension
()
3888 elif self
._GetNextToken
():
3889 if self
._Token
not in {
3890 T_CHAR_BRACE_R
, "COMPAT16", BINARY_FILE_TYPE_PE32
,
3891 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3892 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3893 BINARY_FILE_TYPE_UI
, "VERSION",
3894 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3895 BINARY_FILE_TYPE_SMM_DEPEX
}:
3897 if self
._Token
.startswith('PCD'):
3901 if self
._Token
== 'PCD':
3902 if not self
._IsToken
("("):
3903 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3904 PcdPair
= self
._GetNextPcdSettings
()
3905 if not self
._IsToken
(")"):
3906 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3907 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3909 EfiSectionObj
.FileName
= self
._Token
3914 raise Warning.Expected("section file name", self
.FileName
, self
.CurrentLineNumber
)
3916 Obj
.SectionList
.append(EfiSectionObj
)
3919 ## _RuleSectionCouldBeOptional() method
3921 # Get whether a section could be optional
3923 # @param SectionType The section type to check
3924 # @retval True section could be optional
3925 # @retval False section never optional
3928 def _RuleSectionCouldBeOptional(SectionType
):
3929 if SectionType
in {BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "RAW", BINARY_FILE_TYPE_SMM_DEPEX
}:
3934 ## _RuleSectionCouldHaveBuildNum() method
3936 # Get whether a section could have build number information
3938 # @param SectionType The section type to check
3939 # @retval True section could have build number information
3940 # @retval False section never have build number information
3943 def _RuleSectionCouldHaveBuildNum(SectionType
):
3944 if SectionType
== "VERSION":
3949 ## _RuleSectionCouldHaveString() method
3951 # Get whether a section could have string
3953 # @param SectionType The section type to check
3954 # @retval True section could have string
3955 # @retval False section never have string
3958 def _RuleSectionCouldHaveString(SectionType
):
3959 if SectionType
in {BINARY_FILE_TYPE_UI
, "VERSION"}:
3964 ## _CheckRuleSectionFileType() method
3966 # Get whether a section matches a file type
3968 # @param self The object pointer
3969 # @param SectionType The section type to check
3970 # @param FileType The file type to check
3972 def _CheckRuleSectionFileType(self
, SectionType
, FileType
):
3973 WarningString
= "Incorrect section file type '%s'"
3974 if SectionType
== "COMPAT16":
3975 if FileType
not in {"COMPAT16", "SEC_COMPAT16"}:
3976 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3977 elif SectionType
== BINARY_FILE_TYPE_PE32
:
3978 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_PE32"}:
3979 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3980 elif SectionType
== BINARY_FILE_TYPE_PIC
:
3981 if FileType
not in {BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_PIC
}:
3982 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3983 elif SectionType
== BINARY_FILE_TYPE_TE
:
3984 if FileType
not in {BINARY_FILE_TYPE_TE
, "SEC_TE"}:
3985 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3986 elif SectionType
== "RAW":
3987 if FileType
not in {BINARY_FILE_TYPE_BIN
, "SEC_BIN", "RAW", "ASL", "ACPI"}:
3988 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3989 elif SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
or SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
3990 if FileType
not in {BINARY_FILE_TYPE_DXE_DEPEX
, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX
}:
3991 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3992 elif SectionType
== BINARY_FILE_TYPE_UI
:
3993 if FileType
not in {BINARY_FILE_TYPE_UI
, "SEC_UI"}:
3994 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3995 elif SectionType
== "VERSION":
3996 if FileType
not in {"VERSION", "SEC_VERSION"}:
3997 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3998 elif SectionType
== BINARY_FILE_TYPE_PEI_DEPEX
:
3999 if FileType
not in {BINARY_FILE_TYPE_PEI_DEPEX
, "SEC_PEI_DEPEX"}:
4000 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4001 elif SectionType
== BINARY_FILE_TYPE_GUID
:
4002 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_GUID"}:
4003 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4005 ## _GetRuleEncapsulationSection() method
4007 # Get encapsulation section for Rule
4009 # @param self The object pointer
4010 # @param theRule for whom section is got
4011 # @retval True Successfully find section statement
4012 # @retval False Not able to find section statement
4014 def _GetRuleEncapsulationSection(self
, theRule
):
4015 if self
._IsKeyword
("COMPRESS"):
4017 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
4020 if not self
._IsToken
("{"):
4021 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4023 CompressSectionObj
= CompressSection()
4025 CompressSectionObj
.CompType
= Type
4026 # Recursive sections...
4028 IsEncapsulate
= self
._GetRuleEncapsulationSection
(CompressSectionObj
)
4029 IsLeaf
= self
._GetEfiSection
(CompressSectionObj
)
4030 if not IsEncapsulate
and not IsLeaf
:
4033 if not self
._IsToken
(T_CHAR_BRACE_R
):
4034 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4035 theRule
.SectionList
.append(CompressSectionObj
)
4039 elif self
._IsKeyword
("GUIDED"):
4041 if self
._GetNextGuid
():
4042 GuidValue
= self
._Token
4044 if self
._IsKeyword
("$(NAMED_GUID)"):
4045 GuidValue
= self
._Token
4047 AttribDict
= self
._GetGuidAttrib
()
4049 if not self
._IsToken
("{"):
4050 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4051 GuidSectionObj
= GuidSection()
4052 GuidSectionObj
.NameGuid
= GuidValue
4053 GuidSectionObj
.SectionType
= "GUIDED"
4054 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
4055 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
4056 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
4060 IsEncapsulate
= self
._GetRuleEncapsulationSection
(GuidSectionObj
)
4061 IsLeaf
= self
._GetEfiSection
(GuidSectionObj
)
4062 if not IsEncapsulate
and not IsLeaf
:
4065 if not self
._IsToken
(T_CHAR_BRACE_R
):
4066 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4067 theRule
.SectionList
.append(GuidSectionObj
)
4073 ## _GetOptionRom() method
4075 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
4077 # @param self The object pointer
4078 # @retval True Successfully find a OptionROM
4079 # @retval False Not able to find a OptionROM
4081 def _GetOptionRom(self
):
4082 if not self
._GetNextToken
():
4085 S
= self
._Token
.upper()
4086 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[OPTIONROM."):
4087 self
.SectionParser(S
)
4092 if not self
._IsToken
("[OptionRom.", True):
4093 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4095 OptRomName
= self
._GetUiName
()
4097 if not self
._IsToken
(TAB_SECTION_END
):
4098 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
4100 OptRomObj
= OPTIONROM(OptRomName
)
4101 self
.Profile
.OptRomDict
[OptRomName
] = OptRomObj
4104 isInf
= self
._GetOptRomInfStatement
(OptRomObj
)
4105 isFile
= self
._GetOptRomFileStatement
(OptRomObj
)
4106 if not isInf
and not isFile
:
4111 ## _GetOptRomInfStatement() method
4113 # Get INF statements
4115 # @param self The object pointer
4116 # @param Obj for whom inf statement is got
4117 # @retval True Successfully find inf statement
4118 # @retval False Not able to find inf statement
4120 def _GetOptRomInfStatement(self
, Obj
):
4121 if not self
._IsKeyword
("INF"):
4124 ffsInf
= OptRomInfStatement()
4125 self
._GetInfOptions
(ffsInf
)
4127 if not self
._GetNextToken
():
4128 raise Warning.Expected("INF file path", self
.FileName
, self
.CurrentLineNumber
)
4129 ffsInf
.InfFileName
= self
._Token
4130 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4131 #check for file path
4132 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4134 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4136 NewFileName
= ffsInf
.InfFileName
4137 if ffsInf
.OverrideGuid
:
4138 NewFileName
= ProcessDuplicatedInf(PathClass(ffsInf
.InfFileName
,GenFdsGlobalVariable
.WorkSpaceDir
), ffsInf
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
).Path
4140 if not NewFileName
in self
.Profile
.InfList
:
4141 self
.Profile
.InfList
.append(NewFileName
)
4142 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4143 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
4145 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
4146 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
4148 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
4150 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
4153 self
._GetOptRomOverrides
(ffsInf
)
4155 Obj
.FfsList
.append(ffsInf
)
4158 ## _GetOptRomOverrides() method
4160 # Get overrides for OptROM INF & FILE
4162 # @param self The object pointer
4163 # @param FfsInfObj for whom overrides is got
4165 def _GetOptRomOverrides(self
, Obj
):
4166 if self
._IsToken
('{'):
4167 Overrides
= OverrideAttribs()
4169 if self
._IsKeyword
("PCI_VENDOR_ID"):
4170 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4171 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4172 if not self
._GetNextHexNumber
():
4173 raise Warning.Expected("Hex vendor id", self
.FileName
, self
.CurrentLineNumber
)
4174 Overrides
.PciVendorId
= self
._Token
4177 if self
._IsKeyword
("PCI_CLASS_CODE"):
4178 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4179 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4180 if not self
._GetNextHexNumber
():
4181 raise Warning.Expected("Hex class code", self
.FileName
, self
.CurrentLineNumber
)
4182 Overrides
.PciClassCode
= self
._Token
4185 if self
._IsKeyword
("PCI_DEVICE_ID"):
4186 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4187 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4188 # Get a list of PCI IDs
4189 Overrides
.PciDeviceId
= ""
4190 while (self
._GetNextHexNumber
()):
4191 Overrides
.PciDeviceId
= "{} {}".format(Overrides
.PciDeviceId
, self
._Token
)
4192 if not Overrides
.PciDeviceId
:
4193 raise Warning.Expected("one or more Hex device ids", self
.FileName
, self
.CurrentLineNumber
)
4196 if self
._IsKeyword
("PCI_REVISION"):
4197 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4198 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4199 if not self
._GetNextHexNumber
():
4200 raise Warning.Expected("Hex revision", self
.FileName
, self
.CurrentLineNumber
)
4201 Overrides
.PciRevision
= self
._Token
4204 if self
._IsKeyword
("PCI_COMPRESS"):
4205 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4206 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4207 if not self
._GetNextToken
():
4208 raise Warning.Expected("TRUE/FALSE for compress", self
.FileName
, self
.CurrentLineNumber
)
4209 Overrides
.NeedCompress
= self
._Token
.upper() == 'TRUE'
4212 if self
._IsToken
(T_CHAR_BRACE_R
):
4215 EdkLogger
.error("FdfParser", FORMAT_INVALID
, File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
4217 Obj
.OverrideAttribs
= Overrides
4219 ## _GetOptRomFileStatement() method
4221 # Get FILE statements
4223 # @param self The object pointer
4224 # @param Obj for whom FILE statement is got
4225 # @retval True Successfully find FILE statement
4226 # @retval False Not able to find FILE statement
4228 def _GetOptRomFileStatement(self
, Obj
):
4229 if not self
._IsKeyword
("FILE"):
4232 FfsFileObj
= OptRomFileStatement()
4234 if not self
._IsKeyword
("EFI") and not self
._IsKeyword
(BINARY_FILE_TYPE_BIN
):
4235 raise Warning.Expected("Binary type (EFI/BIN)", self
.FileName
, self
.CurrentLineNumber
)
4236 FfsFileObj
.FileType
= self
._Token
4238 if not self
._GetNextToken
():
4239 raise Warning.Expected("File path", self
.FileName
, self
.CurrentLineNumber
)
4240 FfsFileObj
.FileName
= self
._Token
4241 if FfsFileObj
.FileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4242 #check for file path
4243 ErrorCode
, ErrorInfo
= PathClass(NormPath(FfsFileObj
.FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4245 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4247 if FfsFileObj
.FileType
== 'EFI':
4248 self
._GetOptRomOverrides
(FfsFileObj
)
4250 Obj
.FfsList
.append(FfsFileObj
)
4254 ## _GetCapInFd() method
4256 # Get Cap list contained in FD
4258 # @param self The object pointer
4259 # @param FdName FD name
4260 # @retval CapList List of Capsule in FD
4262 def _GetCapInFd (self
, FdName
):
4264 if FdName
.upper() in self
.Profile
.FdDict
:
4265 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4266 for elementRegion
in FdObj
.RegionList
:
4267 if elementRegion
.RegionType
== 'CAPSULE':
4268 for elementRegionData
in elementRegion
.RegionDataList
:
4269 if elementRegionData
.endswith(".cap"):
4271 if elementRegionData
is not None and elementRegionData
.upper() not in CapList
:
4272 CapList
.append(elementRegionData
.upper())
4275 ## _GetReferencedFdCapTuple() method
4277 # Get FV and FD list referenced by a capsule image
4279 # @param self The object pointer
4280 # @param CapObj Capsule section to be searched
4281 # @param RefFdList referenced FD by section
4282 # @param RefFvList referenced FV by section
4284 def _GetReferencedFdCapTuple(self
, CapObj
, RefFdList
= [], RefFvList
= []):
4285 for CapsuleDataObj
in CapObj
.CapsuleDataList
:
4286 if hasattr(CapsuleDataObj
, 'FvName') and CapsuleDataObj
.FvName
is not None and CapsuleDataObj
.FvName
.upper() not in RefFvList
:
4287 RefFvList
.append (CapsuleDataObj
.FvName
.upper())
4288 elif hasattr(CapsuleDataObj
, 'FdName') and CapsuleDataObj
.FdName
is not None and CapsuleDataObj
.FdName
.upper() not in RefFdList
:
4289 RefFdList
.append (CapsuleDataObj
.FdName
.upper())
4290 elif CapsuleDataObj
.Ffs
is not None:
4291 if isinstance(CapsuleDataObj
.Ffs
, FileStatement
):
4292 if CapsuleDataObj
.Ffs
.FvName
is not None and CapsuleDataObj
.Ffs
.FvName
.upper() not in RefFvList
:
4293 RefFvList
.append(CapsuleDataObj
.Ffs
.FvName
.upper())
4294 elif CapsuleDataObj
.Ffs
.FdName
is not None and CapsuleDataObj
.Ffs
.FdName
.upper() not in RefFdList
:
4295 RefFdList
.append(CapsuleDataObj
.Ffs
.FdName
.upper())
4297 self
._GetReferencedFdFvTupleFromSection
(CapsuleDataObj
.Ffs
, RefFdList
, RefFvList
)
4299 ## _GetFvInFd() method
4301 # Get FV list contained in FD
4303 # @param self The object pointer
4304 # @param FdName FD name
4305 # @retval FvList list of FV in FD
4307 def _GetFvInFd (self
, FdName
):
4309 if FdName
.upper() in self
.Profile
.FdDict
:
4310 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4311 for elementRegion
in FdObj
.RegionList
:
4312 if elementRegion
.RegionType
== BINARY_FILE_TYPE_FV
:
4313 for elementRegionData
in elementRegion
.RegionDataList
:
4314 if elementRegionData
.endswith(".fv"):
4316 if elementRegionData
is not None and elementRegionData
.upper() not in FvList
:
4317 FvList
.append(elementRegionData
.upper())
4320 ## _GetReferencedFdFvTuple() method
4322 # Get FD and FV list referenced by a FFS file
4324 # @param self The object pointer
4325 # @param FfsFile contains sections to be searched
4326 # @param RefFdList referenced FD by section
4327 # @param RefFvList referenced FV by section
4329 def _GetReferencedFdFvTuple(self
, FvObj
, RefFdList
= [], RefFvList
= []):
4330 for FfsObj
in FvObj
.FfsList
:
4331 if isinstance(FfsObj
, FileStatement
):
4332 if FfsObj
.FvName
is not None and FfsObj
.FvName
.upper() not in RefFvList
:
4333 RefFvList
.append(FfsObj
.FvName
.upper())
4334 elif FfsObj
.FdName
is not None and FfsObj
.FdName
.upper() not in RefFdList
:
4335 RefFdList
.append(FfsObj
.FdName
.upper())
4337 self
._GetReferencedFdFvTupleFromSection
(FfsObj
, RefFdList
, RefFvList
)
4339 ## _GetReferencedFdFvTupleFromSection() method
4341 # Get FD and FV list referenced by a FFS section
4343 # @param self The object pointer
4344 # @param FfsFile contains sections to be searched
4345 # @param FdList referenced FD by section
4346 # @param FvList referenced FV by section
4348 def _GetReferencedFdFvTupleFromSection(self
, FfsFile
, FdList
= [], FvList
= []):
4349 SectionStack
= list(FfsFile
.SectionList
)
4350 while SectionStack
!= []:
4351 SectionObj
= SectionStack
.pop()
4352 if isinstance(SectionObj
, FvImageSection
):
4353 if SectionObj
.FvName
is not None and SectionObj
.FvName
.upper() not in FvList
:
4354 FvList
.append(SectionObj
.FvName
.upper())
4355 if SectionObj
.Fv
is not None and SectionObj
.Fv
.UiFvName
is not None and SectionObj
.Fv
.UiFvName
.upper() not in FvList
:
4356 FvList
.append(SectionObj
.Fv
.UiFvName
.upper())
4357 self
._GetReferencedFdFvTuple
(SectionObj
.Fv
, FdList
, FvList
)
4359 if isinstance(SectionObj
, CompressSection
) or isinstance(SectionObj
, GuidSection
):
4360 SectionStack
.extend(SectionObj
.SectionList
)
4362 ## CycleReferenceCheck() method
4364 # Check whether cycle reference exists in FDF
4366 # @param self The object pointer
4367 # @retval True cycle reference exists
4368 # @retval False Not exists cycle reference
4370 def CycleReferenceCheck(self
):
4372 # Check the cycle between FV and FD image
4374 MaxLength
= len (self
.Profile
.FvDict
)
4375 for FvName
in self
.Profile
.FvDict
:
4376 LogStr
= "\nCycle Reference Checking for FV: %s\n" % FvName
4377 RefFvStack
= set(FvName
)
4378 FdAnalyzedList
= set()
4381 while RefFvStack
and Index
< MaxLength
:
4383 FvNameFromStack
= RefFvStack
.pop()
4384 if FvNameFromStack
.upper() in self
.Profile
.FvDict
:
4385 FvObj
= self
.Profile
.FvDict
[FvNameFromStack
.upper()]
4391 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4393 for RefFdName
in RefFdList
:
4394 if RefFdName
in FdAnalyzedList
:
4397 LogStr
+= "FV %s contains FD %s\n" % (FvNameFromStack
, RefFdName
)
4398 FvInFdList
= self
._GetFvInFd
(RefFdName
)
4399 if FvInFdList
!= []:
4400 for FvNameInFd
in FvInFdList
:
4401 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4402 if FvNameInFd
not in RefFvStack
:
4403 RefFvStack
.add(FvNameInFd
)
4405 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4406 EdkLogger
.info(LogStr
)
4408 FdAnalyzedList
.add(RefFdName
)
4410 for RefFvName
in RefFvList
:
4411 LogStr
+= "FV %s contains FV %s\n" % (FvNameFromStack
, RefFvName
)
4412 if RefFvName
not in RefFvStack
:
4413 RefFvStack
.add(RefFvName
)
4415 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4416 EdkLogger
.info(LogStr
)
4420 # Check the cycle between Capsule and FD image
4422 MaxLength
= len (self
.Profile
.CapsuleDict
)
4423 for CapName
in self
.Profile
.CapsuleDict
:
4425 # Capsule image to be checked.
4427 LogStr
= "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4428 RefCapStack
= {CapName}
4429 FdAnalyzedList
= set()
4430 FvAnalyzedList
= set()
4433 while RefCapStack
and Index
< MaxLength
:
4435 CapNameFromStack
= RefCapStack
.pop()
4436 if CapNameFromStack
.upper() in self
.Profile
.CapsuleDict
:
4437 CapObj
= self
.Profile
.CapsuleDict
[CapNameFromStack
.upper()]
4443 self
._GetReferencedFdCapTuple
(CapObj
, RefFdList
, RefFvList
)
4447 while FvListLength
< len (RefFvList
) or FdListLength
< len (RefFdList
):
4448 for RefFdName
in RefFdList
:
4449 if RefFdName
in FdAnalyzedList
:
4452 LogStr
+= "Capsule %s contains FD %s\n" % (CapNameFromStack
, RefFdName
)
4453 for CapNameInFd
in self
._GetCapInFd
(RefFdName
):
4454 LogStr
+= "FD %s contains Capsule %s\n" % (RefFdName
, CapNameInFd
)
4455 if CapNameInFd
not in RefCapStack
:
4456 RefCapStack
.append(CapNameInFd
)
4458 if CapName
in RefCapStack
or CapNameFromStack
in RefCapStack
:
4459 EdkLogger
.info(LogStr
)
4462 for FvNameInFd
in self
._GetFvInFd
(RefFdName
):
4463 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4464 if FvNameInFd
not in RefFvList
:
4465 RefFvList
.append(FvNameInFd
)
4467 FdAnalyzedList
.add(RefFdName
)
4469 # the number of the parsed FV and FD image
4471 FvListLength
= len (RefFvList
)
4472 FdListLength
= len (RefFdList
)
4473 for RefFvName
in RefFvList
:
4474 if RefFvName
in FvAnalyzedList
:
4476 LogStr
+= "Capsule %s contains FV %s\n" % (CapNameFromStack
, RefFvName
)
4477 if RefFvName
.upper() in self
.Profile
.FvDict
:
4478 FvObj
= self
.Profile
.FvDict
[RefFvName
.upper()]
4481 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4482 FvAnalyzedList
.add(RefFvName
)
4486 def GetAllIncludedFile (self
):
4487 global AllIncludeFileList
4488 return AllIncludeFileList
4490 if __name__
== "__main__":
4493 test_file
= sys
.argv
[1]
4494 except IndexError as v
:
4495 print("Usage: %s filename" % sys
.argv
[0])
4498 parser
= FdfParser(test_file
)
4501 parser
.CycleReferenceCheck()
4502 except Warning as X
: