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 raise Warning.Expected("$(NAMED_GUID)", self
.FileName
, self
.CurrentLineNumber
)
3609 if self
._Token
== 'PCD':
3610 if not self
._IsToken
("("):
3611 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3612 PcdPair
= self
._GetNextPcdSettings
()
3613 if not self
._IsToken
(")"):
3614 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3615 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3617 NameGuid
= self
._Token
3620 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3621 if self
._FileCouldHaveRelocFlag
(Type
):
3622 if self
._Token
== 'RELOCS_STRIPPED':
3627 raise Warning("File type %s could not have reloc strip flag%d" % (Type
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3630 if self
._GetNextToken
():
3631 if TokenFindPattern
.match(self
._Token
):
3632 KeyStringList
.append(self
._Token
)
3633 if self
._IsToken
(TAB_COMMA_SPLIT
):
3634 while self
._GetNextToken
():
3635 if not TokenFindPattern
.match(self
._Token
):
3636 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
3637 KeyStringList
.append(self
._Token
)
3639 if not self
._IsToken
(TAB_COMMA_SPLIT
):
3647 if self
._IsKeyword
("Fixed", True):
3651 if self
._IsKeyword
("CheckSum", True):
3655 if self
._GetAlignment
():
3656 if self
._Token
not in ALIGNMENTS
:
3657 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3658 #For FFS, Auto is default option same to ""
3659 if not self
._Token
== "Auto":
3660 AlignValue
= self
._Token
3662 if self
._IsToken
("{"):
3663 # Complex file rule expected
3664 NewRule
= RuleComplexFile()
3665 NewRule
.FvFileType
= Type
3666 NewRule
.NameGuid
= NameGuid
3667 NewRule
.Alignment
= AlignValue
3668 NewRule
.CheckSum
= CheckSum
3669 NewRule
.Fixed
= Fixed
3670 NewRule
.KeyStringList
= KeyStringList
3671 if KeepReloc
is not None:
3672 NewRule
.KeepReloc
= KeepReloc
3675 IsEncapsulate
= self
._GetRuleEncapsulationSection
(NewRule
)
3676 IsLeaf
= self
._GetEfiSection
(NewRule
)
3677 if not IsEncapsulate
and not IsLeaf
:
3680 if not self
._IsToken
(T_CHAR_BRACE_R
):
3681 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3686 # Simple file rule expected
3687 if not self
._GetNextWord
():
3688 raise Warning.Expected("leaf section type", self
.FileName
, self
.CurrentLineNumber
)
3690 SectionName
= self
._Token
3692 if SectionName
not in {
3693 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3694 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3695 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3696 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3697 BINARY_FILE_TYPE_SMM_DEPEX
}:
3698 raise Warning("Unknown leaf section name '%s'" % SectionName
, self
.FileName
, self
.CurrentLineNumber
)
3701 if self
._IsKeyword
("Fixed", True):
3704 if self
._IsKeyword
("CheckSum", True):
3708 if self
._GetAlignment
():
3709 if self
._Token
not in ALIGNMENTS
:
3710 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3711 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3712 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3713 SectAlignment
= self
._Token
3716 if self
._IsToken
(TAB_VALUE_SPLIT
):
3717 Ext
= self
._GetFileExtension
()
3718 elif not self
._GetNextToken
():
3719 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
3721 NewRule
= RuleSimpleFile()
3722 NewRule
.SectionType
= SectionName
3723 NewRule
.FvFileType
= Type
3724 NewRule
.NameGuid
= NameGuid
3725 NewRule
.Alignment
= AlignValue
3726 NewRule
.SectAlignment
= SectAlignment
3727 NewRule
.CheckSum
= CheckSum
3728 NewRule
.Fixed
= Fixed
3729 NewRule
.KeyStringList
= KeyStringList
3730 if KeepReloc
is not None:
3731 NewRule
.KeepReloc
= KeepReloc
3732 NewRule
.FileExtension
= Ext
3733 NewRule
.FileName
= self
._Token
3736 ## _GetEfiSection() method
3738 # Get section list for Rule
3740 # @param self The object pointer
3741 # @param Obj for whom section is got
3742 # @retval True Successfully find section statement
3743 # @retval False Not able to find section statement
3745 def _GetEfiSection(self
, Obj
):
3746 OldPos
= self
.GetFileBufferPos()
3747 if not self
._GetNextWord
():
3749 SectionName
= self
._Token
3751 if SectionName
not in {
3752 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3753 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3754 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3755 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3756 BINARY_FILE_TYPE_SMM_DEPEX
, BINARY_FILE_TYPE_GUID
}:
3760 if SectionName
== "FV_IMAGE":
3761 FvImageSectionObj
= FvImageSection()
3762 if self
._IsKeyword
("FV_IMAGE"):
3764 if self
._IsToken
("{"):
3766 self
._GetDefineStatements
(FvObj
)
3767 self
._GetBlockStatement
(FvObj
)
3768 self
._GetSetStatements
(FvObj
)
3769 self
._GetFvAlignment
(FvObj
)
3770 self
._GetFvAttributes
(FvObj
)
3771 self
._GetAprioriSection
(FvObj
)
3772 self
._GetAprioriSection
(FvObj
)
3775 IsInf
= self
._GetInfStatement
(FvObj
)
3776 IsFile
= self
._GetFileStatement
(FvObj
)
3777 if not IsInf
and not IsFile
:
3780 if not self
._IsToken
(T_CHAR_BRACE_R
):
3781 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3782 FvImageSectionObj
.Fv
= FvObj
3783 FvImageSectionObj
.FvName
= None
3786 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3787 raise Warning.Expected("'FV'", self
.FileName
, self
.CurrentLineNumber
)
3788 FvImageSectionObj
.FvFileType
= self
._Token
3790 if self
._GetAlignment
():
3791 if self
._Token
not in ALIGNMENT_NOAUTO
:
3792 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3793 FvImageSectionObj
.Alignment
= self
._Token
3795 if self
._IsToken
(TAB_VALUE_SPLIT
):
3796 FvImageSectionObj
.FvFileExtension
= self
._GetFileExtension
()
3797 elif self
._GetNextToken
():
3798 if self
._Token
not in {
3799 T_CHAR_BRACE_R
, "COMPAT16", BINARY_FILE_TYPE_PE32
,
3800 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3801 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3802 BINARY_FILE_TYPE_UI
, "VERSION",
3803 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3804 BINARY_FILE_TYPE_SMM_DEPEX
}:
3805 FvImageSectionObj
.FvFileName
= self
._Token
3809 raise Warning.Expected("FV file name", self
.FileName
, self
.CurrentLineNumber
)
3811 Obj
.SectionList
.append(FvImageSectionObj
)
3814 EfiSectionObj
= EfiSection()
3815 EfiSectionObj
.SectionType
= SectionName
3817 if not self
._GetNextToken
():
3818 raise Warning.Expected("file type", self
.FileName
, self
.CurrentLineNumber
)
3820 if self
._Token
== "STRING":
3821 if not self
._RuleSectionCouldHaveString
(EfiSectionObj
.SectionType
):
3822 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3824 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3825 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3827 if not self
._GetNextToken
():
3828 raise Warning.Expected("Quoted String", self
.FileName
, self
.CurrentLineNumber
)
3830 if self
._GetStringData
():
3831 EfiSectionObj
.StringData
= self
._Token
3833 if self
._IsKeyword
("BUILD_NUM"):
3834 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3835 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3837 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3838 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3839 if not self
._GetNextToken
():
3840 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3841 EfiSectionObj
.BuildNum
= self
._Token
3844 EfiSectionObj
.FileType
= self
._Token
3845 self
._CheckRuleSectionFileType
(EfiSectionObj
.SectionType
, EfiSectionObj
.FileType
)
3847 if self
._IsKeyword
("Optional"):
3848 if not self
._RuleSectionCouldBeOptional
(EfiSectionObj
.SectionType
):
3849 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3850 EfiSectionObj
.Optional
= True
3852 if self
._IsKeyword
("BUILD_NUM"):
3853 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3854 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3856 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3857 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3858 if not self
._GetNextToken
():
3859 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3860 EfiSectionObj
.BuildNum
= self
._Token
3862 if self
._GetAlignment
():
3863 if self
._Token
not in ALIGNMENTS
:
3864 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3865 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3866 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3867 EfiSectionObj
.Alignment
= self
._Token
3869 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3870 if self
._SectionCouldHaveRelocFlag
(EfiSectionObj
.SectionType
):
3871 if self
._Token
== 'RELOCS_STRIPPED':
3872 EfiSectionObj
.KeepReloc
= False
3874 EfiSectionObj
.KeepReloc
= True
3875 if Obj
.KeepReloc
is not None and Obj
.KeepReloc
!= EfiSectionObj
.KeepReloc
:
3876 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3878 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3881 if self
._IsToken
(TAB_VALUE_SPLIT
):
3882 EfiSectionObj
.FileExtension
= self
._GetFileExtension
()
3883 elif self
._GetNextToken
():
3884 if self
._Token
not in {
3885 T_CHAR_BRACE_R
, "COMPAT16", BINARY_FILE_TYPE_PE32
,
3886 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3887 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3888 BINARY_FILE_TYPE_UI
, "VERSION",
3889 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3890 BINARY_FILE_TYPE_SMM_DEPEX
}:
3892 if self
._Token
.startswith('PCD'):
3896 if self
._Token
== 'PCD':
3897 if not self
._IsToken
("("):
3898 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3899 PcdPair
= self
._GetNextPcdSettings
()
3900 if not self
._IsToken
(")"):
3901 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3902 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3904 EfiSectionObj
.FileName
= self
._Token
3909 raise Warning.Expected("section file name", self
.FileName
, self
.CurrentLineNumber
)
3911 Obj
.SectionList
.append(EfiSectionObj
)
3914 ## _RuleSectionCouldBeOptional() method
3916 # Get whether a section could be optional
3918 # @param SectionType The section type to check
3919 # @retval True section could be optional
3920 # @retval False section never optional
3923 def _RuleSectionCouldBeOptional(SectionType
):
3924 if SectionType
in {BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "RAW", BINARY_FILE_TYPE_SMM_DEPEX
}:
3929 ## _RuleSectionCouldHaveBuildNum() method
3931 # Get whether a section could have build number information
3933 # @param SectionType The section type to check
3934 # @retval True section could have build number information
3935 # @retval False section never have build number information
3938 def _RuleSectionCouldHaveBuildNum(SectionType
):
3939 if SectionType
== "VERSION":
3944 ## _RuleSectionCouldHaveString() method
3946 # Get whether a section could have string
3948 # @param SectionType The section type to check
3949 # @retval True section could have string
3950 # @retval False section never have string
3953 def _RuleSectionCouldHaveString(SectionType
):
3954 if SectionType
in {BINARY_FILE_TYPE_UI
, "VERSION"}:
3959 ## _CheckRuleSectionFileType() method
3961 # Get whether a section matches a file type
3963 # @param self The object pointer
3964 # @param SectionType The section type to check
3965 # @param FileType The file type to check
3967 def _CheckRuleSectionFileType(self
, SectionType
, FileType
):
3968 WarningString
= "Incorrect section file type '%s'"
3969 if SectionType
== "COMPAT16":
3970 if FileType
not in {"COMPAT16", "SEC_COMPAT16"}:
3971 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3972 elif SectionType
== BINARY_FILE_TYPE_PE32
:
3973 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_PE32"}:
3974 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3975 elif SectionType
== BINARY_FILE_TYPE_PIC
:
3976 if FileType
not in {BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_PIC
}:
3977 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3978 elif SectionType
== BINARY_FILE_TYPE_TE
:
3979 if FileType
not in {BINARY_FILE_TYPE_TE
, "SEC_TE"}:
3980 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3981 elif SectionType
== "RAW":
3982 if FileType
not in {BINARY_FILE_TYPE_BIN
, "SEC_BIN", "RAW", "ASL", "ACPI"}:
3983 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3984 elif SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
or SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
3985 if FileType
not in {BINARY_FILE_TYPE_DXE_DEPEX
, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX
}:
3986 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3987 elif SectionType
== BINARY_FILE_TYPE_UI
:
3988 if FileType
not in {BINARY_FILE_TYPE_UI
, "SEC_UI"}:
3989 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3990 elif SectionType
== "VERSION":
3991 if FileType
not in {"VERSION", "SEC_VERSION"}:
3992 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3993 elif SectionType
== BINARY_FILE_TYPE_PEI_DEPEX
:
3994 if FileType
not in {BINARY_FILE_TYPE_PEI_DEPEX
, "SEC_PEI_DEPEX"}:
3995 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3996 elif SectionType
== BINARY_FILE_TYPE_GUID
:
3997 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_GUID"}:
3998 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4000 ## _GetRuleEncapsulationSection() method
4002 # Get encapsulation section for Rule
4004 # @param self The object pointer
4005 # @param theRule for whom section is got
4006 # @retval True Successfully find section statement
4007 # @retval False Not able to find section statement
4009 def _GetRuleEncapsulationSection(self
, theRule
):
4010 if self
._IsKeyword
("COMPRESS"):
4012 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
4015 if not self
._IsToken
("{"):
4016 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4018 CompressSectionObj
= CompressSection()
4020 CompressSectionObj
.CompType
= Type
4021 # Recursive sections...
4023 IsEncapsulate
= self
._GetRuleEncapsulationSection
(CompressSectionObj
)
4024 IsLeaf
= self
._GetEfiSection
(CompressSectionObj
)
4025 if not IsEncapsulate
and not IsLeaf
:
4028 if not self
._IsToken
(T_CHAR_BRACE_R
):
4029 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4030 theRule
.SectionList
.append(CompressSectionObj
)
4034 elif self
._IsKeyword
("GUIDED"):
4036 if self
._GetNextGuid
():
4037 GuidValue
= self
._Token
4039 if self
._IsKeyword
("$(NAMED_GUID)"):
4040 GuidValue
= self
._Token
4042 AttribDict
= self
._GetGuidAttrib
()
4044 if not self
._IsToken
("{"):
4045 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4046 GuidSectionObj
= GuidSection()
4047 GuidSectionObj
.NameGuid
= GuidValue
4048 GuidSectionObj
.SectionType
= "GUIDED"
4049 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
4050 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
4051 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
4055 IsEncapsulate
= self
._GetRuleEncapsulationSection
(GuidSectionObj
)
4056 IsLeaf
= self
._GetEfiSection
(GuidSectionObj
)
4057 if not IsEncapsulate
and not IsLeaf
:
4060 if not self
._IsToken
(T_CHAR_BRACE_R
):
4061 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4062 theRule
.SectionList
.append(GuidSectionObj
)
4068 ## _GetOptionRom() method
4070 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
4072 # @param self The object pointer
4073 # @retval True Successfully find a OptionROM
4074 # @retval False Not able to find a OptionROM
4076 def _GetOptionRom(self
):
4077 if not self
._GetNextToken
():
4080 S
= self
._Token
.upper()
4081 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[OPTIONROM."):
4082 self
.SectionParser(S
)
4087 if not self
._IsToken
("[OptionRom.", True):
4088 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4090 OptRomName
= self
._GetUiName
()
4092 if not self
._IsToken
(TAB_SECTION_END
):
4093 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
4095 OptRomObj
= OPTIONROM(OptRomName
)
4096 self
.Profile
.OptRomDict
[OptRomName
] = OptRomObj
4099 isInf
= self
._GetOptRomInfStatement
(OptRomObj
)
4100 isFile
= self
._GetOptRomFileStatement
(OptRomObj
)
4101 if not isInf
and not isFile
:
4106 ## _GetOptRomInfStatement() method
4108 # Get INF statements
4110 # @param self The object pointer
4111 # @param Obj for whom inf statement is got
4112 # @retval True Successfully find inf statement
4113 # @retval False Not able to find inf statement
4115 def _GetOptRomInfStatement(self
, Obj
):
4116 if not self
._IsKeyword
("INF"):
4119 ffsInf
= OptRomInfStatement()
4120 self
._GetInfOptions
(ffsInf
)
4122 if not self
._GetNextToken
():
4123 raise Warning.Expected("INF file path", self
.FileName
, self
.CurrentLineNumber
)
4124 ffsInf
.InfFileName
= self
._Token
4125 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4126 #check for file path
4127 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4129 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4131 NewFileName
= ffsInf
.InfFileName
4132 if ffsInf
.OverrideGuid
:
4133 NewFileName
= ProcessDuplicatedInf(PathClass(ffsInf
.InfFileName
,GenFdsGlobalVariable
.WorkSpaceDir
), ffsInf
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
).Path
4135 if not NewFileName
in self
.Profile
.InfList
:
4136 self
.Profile
.InfList
.append(NewFileName
)
4137 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4138 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
4140 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
4141 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
4143 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
4145 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
4148 self
._GetOptRomOverrides
(ffsInf
)
4150 Obj
.FfsList
.append(ffsInf
)
4153 ## _GetOptRomOverrides() method
4155 # Get overrides for OptROM INF & FILE
4157 # @param self The object pointer
4158 # @param FfsInfObj for whom overrides is got
4160 def _GetOptRomOverrides(self
, Obj
):
4161 if self
._IsToken
('{'):
4162 Overrides
= OverrideAttribs()
4164 if self
._IsKeyword
("PCI_VENDOR_ID"):
4165 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4166 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4167 if not self
._GetNextHexNumber
():
4168 raise Warning.Expected("Hex vendor id", self
.FileName
, self
.CurrentLineNumber
)
4169 Overrides
.PciVendorId
= self
._Token
4172 if self
._IsKeyword
("PCI_CLASS_CODE"):
4173 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4174 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4175 if not self
._GetNextHexNumber
():
4176 raise Warning.Expected("Hex class code", self
.FileName
, self
.CurrentLineNumber
)
4177 Overrides
.PciClassCode
= self
._Token
4180 if self
._IsKeyword
("PCI_DEVICE_ID"):
4181 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4182 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4183 # Get a list of PCI IDs
4184 Overrides
.PciDeviceId
= ""
4185 while (self
._GetNextHexNumber
()):
4186 Overrides
.PciDeviceId
= "{} {}".format(Overrides
.PciDeviceId
, self
._Token
)
4187 if not Overrides
.PciDeviceId
:
4188 raise Warning.Expected("one or more Hex device ids", self
.FileName
, self
.CurrentLineNumber
)
4191 if self
._IsKeyword
("PCI_REVISION"):
4192 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4193 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4194 if not self
._GetNextHexNumber
():
4195 raise Warning.Expected("Hex revision", self
.FileName
, self
.CurrentLineNumber
)
4196 Overrides
.PciRevision
= self
._Token
4199 if self
._IsKeyword
("PCI_COMPRESS"):
4200 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4201 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4202 if not self
._GetNextToken
():
4203 raise Warning.Expected("TRUE/FALSE for compress", self
.FileName
, self
.CurrentLineNumber
)
4204 Overrides
.NeedCompress
= self
._Token
.upper() == 'TRUE'
4207 if self
._IsToken
(T_CHAR_BRACE_R
):
4210 EdkLogger
.error("FdfParser", FORMAT_INVALID
, File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
4212 Obj
.OverrideAttribs
= Overrides
4214 ## _GetOptRomFileStatement() method
4216 # Get FILE statements
4218 # @param self The object pointer
4219 # @param Obj for whom FILE statement is got
4220 # @retval True Successfully find FILE statement
4221 # @retval False Not able to find FILE statement
4223 def _GetOptRomFileStatement(self
, Obj
):
4224 if not self
._IsKeyword
("FILE"):
4227 FfsFileObj
= OptRomFileStatement()
4229 if not self
._IsKeyword
("EFI") and not self
._IsKeyword
(BINARY_FILE_TYPE_BIN
):
4230 raise Warning.Expected("Binary type (EFI/BIN)", self
.FileName
, self
.CurrentLineNumber
)
4231 FfsFileObj
.FileType
= self
._Token
4233 if not self
._GetNextToken
():
4234 raise Warning.Expected("File path", self
.FileName
, self
.CurrentLineNumber
)
4235 FfsFileObj
.FileName
= self
._Token
4236 if FfsFileObj
.FileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4237 #check for file path
4238 ErrorCode
, ErrorInfo
= PathClass(NormPath(FfsFileObj
.FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4240 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4242 if FfsFileObj
.FileType
== 'EFI':
4243 self
._GetOptRomOverrides
(FfsFileObj
)
4245 Obj
.FfsList
.append(FfsFileObj
)
4249 ## _GetCapInFd() method
4251 # Get Cap list contained in FD
4253 # @param self The object pointer
4254 # @param FdName FD name
4255 # @retval CapList List of Capsule in FD
4257 def _GetCapInFd (self
, FdName
):
4259 if FdName
.upper() in self
.Profile
.FdDict
:
4260 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4261 for elementRegion
in FdObj
.RegionList
:
4262 if elementRegion
.RegionType
== 'CAPSULE':
4263 for elementRegionData
in elementRegion
.RegionDataList
:
4264 if elementRegionData
.endswith(".cap"):
4266 if elementRegionData
is not None and elementRegionData
.upper() not in CapList
:
4267 CapList
.append(elementRegionData
.upper())
4270 ## _GetReferencedFdCapTuple() method
4272 # Get FV and FD list referenced by a capsule image
4274 # @param self The object pointer
4275 # @param CapObj Capsule section to be searched
4276 # @param RefFdList referenced FD by section
4277 # @param RefFvList referenced FV by section
4279 def _GetReferencedFdCapTuple(self
, CapObj
, RefFdList
= [], RefFvList
= []):
4280 for CapsuleDataObj
in CapObj
.CapsuleDataList
:
4281 if hasattr(CapsuleDataObj
, 'FvName') and CapsuleDataObj
.FvName
is not None and CapsuleDataObj
.FvName
.upper() not in RefFvList
:
4282 RefFvList
.append (CapsuleDataObj
.FvName
.upper())
4283 elif hasattr(CapsuleDataObj
, 'FdName') and CapsuleDataObj
.FdName
is not None and CapsuleDataObj
.FdName
.upper() not in RefFdList
:
4284 RefFdList
.append (CapsuleDataObj
.FdName
.upper())
4285 elif CapsuleDataObj
.Ffs
is not None:
4286 if isinstance(CapsuleDataObj
.Ffs
, FileStatement
):
4287 if CapsuleDataObj
.Ffs
.FvName
is not None and CapsuleDataObj
.Ffs
.FvName
.upper() not in RefFvList
:
4288 RefFvList
.append(CapsuleDataObj
.Ffs
.FvName
.upper())
4289 elif CapsuleDataObj
.Ffs
.FdName
is not None and CapsuleDataObj
.Ffs
.FdName
.upper() not in RefFdList
:
4290 RefFdList
.append(CapsuleDataObj
.Ffs
.FdName
.upper())
4292 self
._GetReferencedFdFvTupleFromSection
(CapsuleDataObj
.Ffs
, RefFdList
, RefFvList
)
4294 ## _GetFvInFd() method
4296 # Get FV list contained in FD
4298 # @param self The object pointer
4299 # @param FdName FD name
4300 # @retval FvList list of FV in FD
4302 def _GetFvInFd (self
, FdName
):
4304 if FdName
.upper() in self
.Profile
.FdDict
:
4305 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4306 for elementRegion
in FdObj
.RegionList
:
4307 if elementRegion
.RegionType
== BINARY_FILE_TYPE_FV
:
4308 for elementRegionData
in elementRegion
.RegionDataList
:
4309 if elementRegionData
.endswith(".fv"):
4311 if elementRegionData
is not None and elementRegionData
.upper() not in FvList
:
4312 FvList
.append(elementRegionData
.upper())
4315 ## _GetReferencedFdFvTuple() method
4317 # Get FD and FV list referenced by a FFS file
4319 # @param self The object pointer
4320 # @param FfsFile contains sections to be searched
4321 # @param RefFdList referenced FD by section
4322 # @param RefFvList referenced FV by section
4324 def _GetReferencedFdFvTuple(self
, FvObj
, RefFdList
= [], RefFvList
= []):
4325 for FfsObj
in FvObj
.FfsList
:
4326 if isinstance(FfsObj
, FileStatement
):
4327 if FfsObj
.FvName
is not None and FfsObj
.FvName
.upper() not in RefFvList
:
4328 RefFvList
.append(FfsObj
.FvName
.upper())
4329 elif FfsObj
.FdName
is not None and FfsObj
.FdName
.upper() not in RefFdList
:
4330 RefFdList
.append(FfsObj
.FdName
.upper())
4332 self
._GetReferencedFdFvTupleFromSection
(FfsObj
, RefFdList
, RefFvList
)
4334 ## _GetReferencedFdFvTupleFromSection() method
4336 # Get FD and FV list referenced by a FFS section
4338 # @param self The object pointer
4339 # @param FfsFile contains sections to be searched
4340 # @param FdList referenced FD by section
4341 # @param FvList referenced FV by section
4343 def _GetReferencedFdFvTupleFromSection(self
, FfsFile
, FdList
= [], FvList
= []):
4344 SectionStack
= list(FfsFile
.SectionList
)
4345 while SectionStack
!= []:
4346 SectionObj
= SectionStack
.pop()
4347 if isinstance(SectionObj
, FvImageSection
):
4348 if SectionObj
.FvName
is not None and SectionObj
.FvName
.upper() not in FvList
:
4349 FvList
.append(SectionObj
.FvName
.upper())
4350 if SectionObj
.Fv
is not None and SectionObj
.Fv
.UiFvName
is not None and SectionObj
.Fv
.UiFvName
.upper() not in FvList
:
4351 FvList
.append(SectionObj
.Fv
.UiFvName
.upper())
4352 self
._GetReferencedFdFvTuple
(SectionObj
.Fv
, FdList
, FvList
)
4354 if isinstance(SectionObj
, CompressSection
) or isinstance(SectionObj
, GuidSection
):
4355 SectionStack
.extend(SectionObj
.SectionList
)
4357 ## CycleReferenceCheck() method
4359 # Check whether cycle reference exists in FDF
4361 # @param self The object pointer
4362 # @retval True cycle reference exists
4363 # @retval False Not exists cycle reference
4365 def CycleReferenceCheck(self
):
4367 # Check the cycle between FV and FD image
4369 MaxLength
= len (self
.Profile
.FvDict
)
4370 for FvName
in self
.Profile
.FvDict
:
4371 LogStr
= "\nCycle Reference Checking for FV: %s\n" % FvName
4372 RefFvStack
= set(FvName
)
4373 FdAnalyzedList
= set()
4376 while RefFvStack
and Index
< MaxLength
:
4378 FvNameFromStack
= RefFvStack
.pop()
4379 if FvNameFromStack
.upper() in self
.Profile
.FvDict
:
4380 FvObj
= self
.Profile
.FvDict
[FvNameFromStack
.upper()]
4386 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4388 for RefFdName
in RefFdList
:
4389 if RefFdName
in FdAnalyzedList
:
4392 LogStr
+= "FV %s contains FD %s\n" % (FvNameFromStack
, RefFdName
)
4393 FvInFdList
= self
._GetFvInFd
(RefFdName
)
4394 if FvInFdList
!= []:
4395 for FvNameInFd
in FvInFdList
:
4396 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4397 if FvNameInFd
not in RefFvStack
:
4398 RefFvStack
.add(FvNameInFd
)
4400 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4401 EdkLogger
.info(LogStr
)
4403 FdAnalyzedList
.add(RefFdName
)
4405 for RefFvName
in RefFvList
:
4406 LogStr
+= "FV %s contains FV %s\n" % (FvNameFromStack
, RefFvName
)
4407 if RefFvName
not in RefFvStack
:
4408 RefFvStack
.add(RefFvName
)
4410 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4411 EdkLogger
.info(LogStr
)
4415 # Check the cycle between Capsule and FD image
4417 MaxLength
= len (self
.Profile
.CapsuleDict
)
4418 for CapName
in self
.Profile
.CapsuleDict
:
4420 # Capsule image to be checked.
4422 LogStr
= "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4423 RefCapStack
= {CapName}
4424 FdAnalyzedList
= set()
4425 FvAnalyzedList
= set()
4428 while RefCapStack
and Index
< MaxLength
:
4430 CapNameFromStack
= RefCapStack
.pop()
4431 if CapNameFromStack
.upper() in self
.Profile
.CapsuleDict
:
4432 CapObj
= self
.Profile
.CapsuleDict
[CapNameFromStack
.upper()]
4438 self
._GetReferencedFdCapTuple
(CapObj
, RefFdList
, RefFvList
)
4442 while FvListLength
< len (RefFvList
) or FdListLength
< len (RefFdList
):
4443 for RefFdName
in RefFdList
:
4444 if RefFdName
in FdAnalyzedList
:
4447 LogStr
+= "Capsule %s contains FD %s\n" % (CapNameFromStack
, RefFdName
)
4448 for CapNameInFd
in self
._GetCapInFd
(RefFdName
):
4449 LogStr
+= "FD %s contains Capsule %s\n" % (RefFdName
, CapNameInFd
)
4450 if CapNameInFd
not in RefCapStack
:
4451 RefCapStack
.append(CapNameInFd
)
4453 if CapName
in RefCapStack
or CapNameFromStack
in RefCapStack
:
4454 EdkLogger
.info(LogStr
)
4457 for FvNameInFd
in self
._GetFvInFd
(RefFdName
):
4458 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4459 if FvNameInFd
not in RefFvList
:
4460 RefFvList
.append(FvNameInFd
)
4462 FdAnalyzedList
.add(RefFdName
)
4464 # the number of the parsed FV and FD image
4466 FvListLength
= len (RefFvList
)
4467 FdListLength
= len (RefFdList
)
4468 for RefFvName
in RefFvList
:
4469 if RefFvName
in FvAnalyzedList
:
4471 LogStr
+= "Capsule %s contains FV %s\n" % (CapNameFromStack
, RefFvName
)
4472 if RefFvName
.upper() in self
.Profile
.FvDict
:
4473 FvObj
= self
.Profile
.FvDict
[RefFvName
.upper()]
4476 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4477 FvAnalyzedList
.add(RefFvName
)
4481 def GetAllIncludedFile (self
):
4482 global AllIncludeFileList
4483 return AllIncludeFileList
4485 if __name__
== "__main__":
4488 test_file
= sys
.argv
[1]
4489 except IndexError as v
:
4490 print("Usage: %s filename" % sys
.argv
[0])
4493 parser
= FdfParser(test_file
)
4496 parser
.CycleReferenceCheck()
4497 except Warning as X
: