4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 # Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
7 # This program and the accompanying materials
8 # are licensed and made available under the terms and conditions of the BSD License
9 # which accompanies this distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 from __future__
import print_function
20 from __future__
import absolute_import
21 from re
import compile, DOTALL
22 from string
import hexdigits
25 from Common
.BuildToolError
import *
26 from Common
import EdkLogger
27 from Common
.Misc
import PathClass
, tdict
28 from Common
.StringUtils
import NormPath
, ReplaceMacro
29 from Common
import GlobalData
30 from Common
.Expression
import *
31 from Common
.DataType
import *
32 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
33 import Common
.LongFilePathOs
as os
34 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
35 from Common
.RangeExpression
import RangeExpression
36 from collections
import OrderedDict
39 from .Region
import Region
41 from .AprioriSection
import AprioriSection
42 from .FfsInfStatement
import FfsInfStatement
43 from .FfsFileStatement
import FileStatement
44 from .VerSection
import VerSection
45 from .UiSection
import UiSection
46 from .FvImageSection
import FvImageSection
47 from .DataSection
import DataSection
48 from .DepexSection
import DepexSection
49 from .CompressSection
import CompressSection
50 from .GuidSection
import GuidSection
51 from .Capsule
import EFI_CERT_TYPE_PKCS7_GUID
, EFI_CERT_TYPE_RSA2048_SHA256_GUID
, Capsule
52 from .CapsuleData
import CapsuleFfs
, CapsulePayload
, CapsuleFv
, CapsuleFd
, CapsuleAnyFile
, CapsuleAfile
53 from .RuleComplexFile
import RuleComplexFile
54 from .RuleSimpleFile
import RuleSimpleFile
55 from .EfiSection
import EfiSection
57 from .ComponentStatement
import ComponentStatement
58 from .OptionRom
import OPTIONROM
59 from .OptRomInfStatement
import OptRomInfStatement
, OverrideAttribs
60 from .OptRomFileStatement
import OptRomFileStatement
61 from .GenFdsGlobalVariable
import GenFdsGlobalVariable
65 T_CHAR_DOUBLE_QUOTE
= '\"'
66 T_CHAR_SINGLE_QUOTE
= '\''
70 SEPARATORS
= {TAB_EQUAL_SPLIT
, TAB_VALUE_SPLIT
, TAB_COMMA_SPLIT
, '{', T_CHAR_BRACE_R
}
71 ALIGNMENTS
= {"Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K", "64K", "128K",
72 "256K", "512K", "1M", "2M", "4M", "8M", "16M"}
73 ALIGNMENT_NOAUTO
= ALIGNMENTS
- {"Auto"}
74 CR_LB_SET
= {T_CHAR_CR
, TAB_LINE_BREAK
}
76 RegionSizePattern
= compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
77 RegionSizeGuidPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*")
78 RegionOffsetPcdPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$")
79 ShortcutPcdPattern
= compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
80 BaseAddrValuePattern
= compile('^0[xX][0-9a-fA-F]+')
81 FileExtensionPattern
= compile(r
'([a-zA-Z][a-zA-Z0-9]*)')
82 TokenFindPattern
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
83 AllIncludeFileList
= []
85 # Get the closest parent
86 def GetParentAtLine (Line
):
87 for Profile
in AllIncludeFileList
:
88 if Profile
.IsLineInFile(Line
):
93 def IsValidInclude (File
, Line
):
94 for Profile
in AllIncludeFileList
:
95 if Profile
.IsLineInFile(Line
) and Profile
.FileName
== File
:
100 def GetRealFileLine (File
, Line
):
102 for Profile
in AllIncludeFileList
:
103 if Profile
.IsLineInFile(Line
):
104 return Profile
.GetLineInFile(Line
)
105 elif Line
>= Profile
.InsertStartLineNumber
and Profile
.Level
== 1:
106 InsertedLines
+= Profile
.GetTotalLines()
108 return (File
, Line
- InsertedLines
)
110 ## The exception class that used to report error messages when parsing FDF
112 # Currently the "ToolName" is set to be "FdfParser".
114 class Warning (Exception):
117 # @param self The object pointer
118 # @param Str The message to record
119 # @param File The FDF name
120 # @param Line The Line number that error occurs
122 def __init__(self
, Str
, File
= None, Line
= None):
123 FileLineTuple
= GetRealFileLine(File
, Line
)
124 self
.FileName
= FileLineTuple
[0]
125 self
.LineNumber
= FileLineTuple
[1]
126 self
.OriginalLineNumber
= Line
128 self
.ToolName
= 'FdfParser'
133 # helper functions to facilitate consistency in warnings
134 # each function is for a different common warning
136 def Expected(Str
, File
, Line
):
137 return Warning("expected {}".format(Str
), File
, Line
)
139 def ExpectedEquals(File
, Line
):
140 return Warning.Expected("'='", File
, Line
)
142 def ExpectedCurlyOpen(File
, Line
):
143 return Warning.Expected("'{'", File
, Line
)
145 def ExpectedCurlyClose(File
, Line
):
146 return Warning.Expected("'}'", File
, Line
)
148 def ExpectedBracketClose(File
, Line
):
149 return Warning.Expected("']'", File
, Line
)
151 ## The Include file content class that used to record file data when parsing include file
153 # May raise Exception when opening file.
155 class IncludeFileProfile
:
158 # @param self The object pointer
159 # @param FileName The file that to be parsed
161 def __init__(self
, FileName
):
162 self
.FileName
= FileName
163 self
.FileLinesList
= []
165 with
open(FileName
, "rb", 0) as fsock
:
166 self
.FileLinesList
= fsock
.readlines()
167 for index
, line
in enumerate(self
.FileLinesList
):
168 if not line
.endswith(TAB_LINE_BREAK
):
169 self
.FileLinesList
[index
] += TAB_LINE_BREAK
171 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
173 self
.InsertStartLineNumber
= None
174 self
.InsertAdjust
= 0
175 self
.IncludeFileList
= []
176 self
.Level
= 1 # first level include file
178 def GetTotalLines(self
):
179 TotalLines
= self
.InsertAdjust
+ len(self
.FileLinesList
)
181 for Profile
in self
.IncludeFileList
:
182 TotalLines
+= Profile
.GetTotalLines()
186 def IsLineInFile(self
, Line
):
187 if Line
>= self
.InsertStartLineNumber
and Line
< self
.InsertStartLineNumber
+ self
.GetTotalLines():
192 def GetLineInFile(self
, Line
):
193 if not self
.IsLineInFile (Line
):
194 return (self
.FileName
, -1)
196 InsertedLines
= self
.InsertStartLineNumber
198 for Profile
in self
.IncludeFileList
:
199 if Profile
.IsLineInFile(Line
):
200 return Profile
.GetLineInFile(Line
)
201 elif Line
>= Profile
.InsertStartLineNumber
:
202 InsertedLines
+= Profile
.GetTotalLines()
204 return (self
.FileName
, Line
- InsertedLines
+ 1)
206 ## The FDF content class that used to record file data when parsing FDF
208 # May raise Exception when opening file.
213 # @param self The object pointer
214 # @param FileName The file that to be parsed
216 def __init__(self
, FileName
):
217 self
.FileLinesList
= []
219 with
open(FileName
, "rb", 0) as fsock
:
220 self
.FileLinesList
= fsock
.readlines()
223 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
225 self
.FileName
= FileName
226 self
.PcdDict
= OrderedDict()
227 self
.PcdLocalDict
= OrderedDict()
229 self
.InfDict
= {'ArchTBD':[]}
230 # ECC will use this Dict and List information
231 self
.PcdFileLineDict
= {}
232 self
.InfFileLineList
= []
235 self
.FdNameNotSet
= False
237 self
.CapsuleDict
= {}
241 self
.FmpPayloadDict
= {}
243 ## The syntax parser for FDF
245 # PreprocessFile method should be called prior to ParseFile
246 # CycleReferenceCheck method can detect cycles in FDF contents
248 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
249 # Get*** procedures mean these procedures will make judgement on current token only.
254 # @param self The object pointer
255 # @param FileName The file that to be parsed
257 def __init__(self
, FileName
):
258 self
.Profile
= FileProfile(FileName
)
259 self
.FileName
= FileName
260 self
.CurrentLineNumber
= 1
261 self
.CurrentOffsetWithinLine
= 0
262 self
.CurrentFdName
= None
263 self
.CurrentFvName
= None
265 self
._SkippedChars
= ""
266 GlobalData
.gFdfParser
= self
268 # Used to section info
269 self
._CurSection
= []
270 # Key: [section name, UI name, arch]
271 # Value: {MACRO_NAME: MACRO_VALUE}
272 self
._MacroDict
= tdict(True, 3)
273 self
._PcdDict
= OrderedDict()
275 self
._WipeOffArea
= []
276 if GenFdsGlobalVariable
.WorkSpaceDir
== '':
277 GenFdsGlobalVariable
.WorkSpaceDir
= os
.getenv("WORKSPACE")
279 ## _SkipWhiteSpace() method
281 # Skip white spaces from current char.
283 # @param self The object pointer
285 def _SkipWhiteSpace(self
):
286 while not self
._EndOfFile
():
287 if self
._CurrentChar
() in {TAB_PRINTCHAR_NUL
, T_CHAR_CR
, TAB_LINE_BREAK
, TAB_SPACE_SPLIT
, T_CHAR_TAB
}:
288 self
._SkippedChars
+= str(self
._CurrentChar
())
294 ## _EndOfFile() method
296 # Judge current buffer pos is at file end
298 # @param self The object pointer
299 # @retval True Current File buffer position is at file end
300 # @retval False Current File buffer position is NOT at file end
302 def _EndOfFile(self
):
303 NumberOfLines
= len(self
.Profile
.FileLinesList
)
304 SizeOfLastLine
= len(self
.Profile
.FileLinesList
[-1])
305 if self
.CurrentLineNumber
== NumberOfLines
and self
.CurrentOffsetWithinLine
>= SizeOfLastLine
- 1:
307 if self
.CurrentLineNumber
> NumberOfLines
:
311 ## _EndOfLine() method
313 # Judge current buffer pos is at line end
315 # @param self The object pointer
316 # @retval True Current File buffer position is at line end
317 # @retval False Current File buffer position is NOT at line end
319 def _EndOfLine(self
):
320 if self
.CurrentLineNumber
> len(self
.Profile
.FileLinesList
):
322 SizeOfCurrentLine
= len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
323 if self
.CurrentOffsetWithinLine
>= SizeOfCurrentLine
:
329 # Reset file data buffer to the initial state
331 # @param self The object pointer
332 # @param DestLine Optional new destination line number.
333 # @param DestOffset Optional new destination offset.
335 def Rewind(self
, DestLine
= 1, DestOffset
= 0):
336 self
.CurrentLineNumber
= DestLine
337 self
.CurrentOffsetWithinLine
= DestOffset
339 ## _UndoOneChar() method
341 # Go back one char in the file buffer
343 # @param self The object pointer
344 # @retval True Successfully go back one char
345 # @retval False Not able to go back one char as file beginning reached
347 def _UndoOneChar(self
):
348 if self
.CurrentLineNumber
== 1 and self
.CurrentOffsetWithinLine
== 0:
350 elif self
.CurrentOffsetWithinLine
== 0:
351 self
.CurrentLineNumber
-= 1
352 self
.CurrentOffsetWithinLine
= len(self
._CurrentLine
()) - 1
354 self
.CurrentOffsetWithinLine
-= 1
357 ## _GetOneChar() method
359 # Move forward one char in the file buffer
361 # @param self The object pointer
363 def _GetOneChar(self
):
364 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
365 self
.CurrentLineNumber
+= 1
366 self
.CurrentOffsetWithinLine
= 0
368 self
.CurrentOffsetWithinLine
+= 1
370 ## _CurrentChar() method
372 # Get the char pointed to by the file buffer pointer
374 # @param self The object pointer
375 # @retval Char Current char
377 def _CurrentChar(self
):
378 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
]
380 ## _NextChar() method
382 # Get the one char pass the char pointed to by the file buffer pointer
384 # @param self The object pointer
385 # @retval Char Next char
388 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
389 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
][0]
390 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
+ 1]
392 ## _SetCurrentCharValue() method
394 # Modify the value of current char
396 # @param self The object pointer
397 # @param Value The new value of current char
399 def _SetCurrentCharValue(self
, Value
):
400 self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
] = Value
402 ## _CurrentLine() method
404 # Get the list that contains current line contents
406 # @param self The object pointer
407 # @retval List current line contents
409 def _CurrentLine(self
):
410 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
412 def _StringToList(self
):
413 self
.Profile
.FileLinesList
= [list(s
) for s
in self
.Profile
.FileLinesList
]
414 if not self
.Profile
.FileLinesList
:
415 EdkLogger
.error('FdfParser', FILE_READ_FAILURE
, 'The file is empty!', File
=self
.FileName
)
416 self
.Profile
.FileLinesList
[-1].append(' ')
418 def _ReplaceFragment(self
, StartPos
, EndPos
, Value
= ' '):
419 if StartPos
[0] == EndPos
[0]:
421 while Offset
<= EndPos
[1]:
422 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
427 while self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] not in CR_LB_SET
:
428 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
432 while Line
< EndPos
[0]:
434 while self
.Profile
.FileLinesList
[Line
][Offset
] not in CR_LB_SET
:
435 self
.Profile
.FileLinesList
[Line
][Offset
] = Value
440 while Offset
<= EndPos
[1]:
441 self
.Profile
.FileLinesList
[EndPos
[0]][Offset
] = Value
444 def _SetMacroValue(self
, Macro
, Value
):
445 if not self
._CurSection
:
449 if not self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]:
450 self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]] = MacroDict
452 MacroDict
= self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]
453 MacroDict
[Macro
] = Value
455 def _GetMacroValue(self
, Macro
):
457 if Macro
in GlobalData
.gCommandLineDefines
:
458 return GlobalData
.gCommandLineDefines
[Macro
]
459 if Macro
in GlobalData
.gGlobalDefines
:
460 return GlobalData
.gGlobalDefines
[Macro
]
463 MacroDict
= self
._MacroDict
[
468 if MacroDict
and Macro
in MacroDict
:
469 return MacroDict
[Macro
]
472 if Macro
in GlobalData
.gPlatformDefines
:
473 return GlobalData
.gPlatformDefines
[Macro
]
476 def _SectionHeaderParser(self
, Section
):
478 # [FD.UiName]: use dummy instead if UI name is optional
481 # [Rule]: don't take rule section into account, macro is not allowed in this section
482 # [VTF.arch.UiName, arch]
483 # [OptionRom.DriverName]
484 self
._CurSection
= []
485 Section
= Section
.strip()[1:-1].upper().replace(' ', '').strip(TAB_SPLIT
)
486 ItemList
= Section
.split(TAB_SPLIT
)
488 if Item
== '' or Item
== 'RULE':
491 if Item
== TAB_COMMON_DEFINES
.upper():
492 self
._CurSection
= [TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
493 elif Item
== 'VTF' and len(ItemList
) == 3:
495 Pos
= UiName
.find(TAB_COMMA_SPLIT
)
497 UiName
= UiName
[:Pos
]
498 self
._CurSection
= ['VTF', UiName
, ItemList
[1]]
499 elif len(ItemList
) > 1:
500 self
._CurSection
= [ItemList
[0], ItemList
[1], TAB_COMMON
]
501 elif len(ItemList
) > 0:
502 self
._CurSection
= [ItemList
[0], 'DUMMY', TAB_COMMON
]
504 ## PreprocessFile() method
506 # Preprocess file contents, replace comments with spaces.
507 # In the end, rewind the file buffer pointer to the beginning
508 # BUGBUG: No !include statement processing contained in this procedure
509 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
511 # @param self The object pointer
513 def PreprocessFile(self
):
516 DoubleSlashComment
= False
518 # HashComment in quoted string " " is ignored.
521 while not self
._EndOfFile
():
523 if self
._CurrentChar
() == T_CHAR_DOUBLE_QUOTE
and not InComment
:
524 InString
= not InString
525 # meet new line, then no longer in a comment for // and '#'
526 if self
._CurrentChar
() == TAB_LINE_BREAK
:
527 self
.CurrentLineNumber
+= 1
528 self
.CurrentOffsetWithinLine
= 0
529 if InComment
and DoubleSlashComment
:
531 DoubleSlashComment
= False
532 if InComment
and HashComment
:
535 # check for */ comment end
536 elif InComment
and not DoubleSlashComment
and not HashComment
and self
._CurrentChar
() == T_CHAR_STAR
and self
._NextChar
() == TAB_BACK_SLASH
:
537 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
539 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
542 # set comments to spaces
544 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
546 # check for // comment
547 elif self
._CurrentChar
() == TAB_BACK_SLASH
and self
._NextChar
() == TAB_BACK_SLASH
and not self
._EndOfLine
():
549 DoubleSlashComment
= True
550 # check for '#' comment
551 elif self
._CurrentChar
() == TAB_COMMENT_SPLIT
and not self
._EndOfLine
() and not InString
:
554 # check for /* comment start
555 elif self
._CurrentChar
() == TAB_BACK_SLASH
and self
._NextChar
() == T_CHAR_STAR
:
556 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
558 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
564 # restore from ListOfList to ListOfString
565 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
568 ## PreprocessIncludeFile() method
570 # Preprocess file contents, replace !include statements with file contents.
571 # In the end, rewind the file buffer pointer to the beginning
573 # @param self The object pointer
575 def PreprocessIncludeFile(self
):
576 # nested include support
579 while self
._GetNextToken
():
581 if self
._Token
== TAB_DEFINE
:
582 if not self
._GetNextToken
():
583 raise Warning.Expected("Macro name", self
.FileName
, self
.CurrentLineNumber
)
585 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
586 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
587 Value
= self
._GetExpression
()
588 MacroDict
[Macro
] = Value
590 elif self
._Token
== TAB_INCLUDE
:
592 IncludeLine
= self
.CurrentLineNumber
593 IncludeOffset
= self
.CurrentOffsetWithinLine
- len(TAB_INCLUDE
)
594 if not self
._GetNextToken
():
595 raise Warning.Expected("include file name", self
.FileName
, self
.CurrentLineNumber
)
596 IncFileName
= self
._Token
598 StartPos
= IncFileName
.find('$(', PreIndex
)
599 EndPos
= IncFileName
.find(')', StartPos
+2)
600 while StartPos
!= -1 and EndPos
!= -1:
601 Macro
= IncFileName
[StartPos
+2: EndPos
]
602 MacroVal
= self
._GetMacroValue
(Macro
)
604 if Macro
in MacroDict
:
605 MacroVal
= MacroDict
[Macro
]
606 if MacroVal
is not None:
607 IncFileName
= IncFileName
.replace('$(' + Macro
+ ')', MacroVal
, 1)
608 if MacroVal
.find('$(') != -1:
611 PreIndex
= StartPos
+ len(MacroVal
)
613 raise Warning("The Macro %s is not defined" %Macro
, self
.FileName
, self
.CurrentLineNumber
)
614 StartPos
= IncFileName
.find('$(', PreIndex
)
615 EndPos
= IncFileName
.find(')', StartPos
+2)
617 IncludedFile
= NormPath(IncFileName
)
619 # First search the include file under the same directory as FDF file
621 IncludedFile1
= PathClass(IncludedFile
, os
.path
.dirname(self
.FileName
))
622 ErrorCode
= IncludedFile1
.Validate()[0]
625 # Then search the include file under the same directory as DSC file
628 if GenFdsGlobalVariable
.ActivePlatform
:
629 PlatformDir
= GenFdsGlobalVariable
.ActivePlatform
.Dir
630 elif GlobalData
.gActivePlatform
:
631 PlatformDir
= GlobalData
.gActivePlatform
.MetaFile
.Dir
632 IncludedFile1
= PathClass(IncludedFile
, PlatformDir
)
633 ErrorCode
= IncludedFile1
.Validate()[0]
636 # Also search file under the WORKSPACE directory
638 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
639 ErrorCode
= IncludedFile1
.Validate()[0]
641 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
),
642 self
.FileName
, self
.CurrentLineNumber
)
644 if not IsValidInclude (IncludedFile1
.Path
, self
.CurrentLineNumber
):
645 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1
.Path
), self
.FileName
, self
.CurrentLineNumber
)
647 IncFileProfile
= IncludeFileProfile(IncludedFile1
.Path
)
649 CurrentLine
= self
.CurrentLineNumber
650 CurrentOffset
= self
.CurrentOffsetWithinLine
651 # list index of the insertion, note that line number is 'CurrentLine + 1'
652 InsertAtLine
= CurrentLine
653 ParentProfile
= GetParentAtLine (CurrentLine
)
654 if ParentProfile
is not None:
655 ParentProfile
.IncludeFileList
.insert(0, IncFileProfile
)
656 IncFileProfile
.Level
= ParentProfile
.Level
+ 1
657 IncFileProfile
.InsertStartLineNumber
= InsertAtLine
+ 1
658 # deal with remaining portions after "!include filename", if exists.
659 if self
._GetNextToken
():
660 if self
.CurrentLineNumber
== CurrentLine
:
661 RemainingLine
= self
._CurrentLine
()[CurrentOffset
:]
662 self
.Profile
.FileLinesList
.insert(self
.CurrentLineNumber
, RemainingLine
)
663 IncFileProfile
.InsertAdjust
+= 1
664 self
.CurrentLineNumber
+= 1
665 self
.CurrentOffsetWithinLine
= 0
667 for Line
in IncFileProfile
.FileLinesList
:
668 self
.Profile
.FileLinesList
.insert(InsertAtLine
, Line
)
669 self
.CurrentLineNumber
+= 1
672 # reversely sorted to better determine error in file
673 AllIncludeFileList
.insert(0, IncFileProfile
)
675 # comment out the processed include file statement
676 TempList
= list(self
.Profile
.FileLinesList
[IncludeLine
- 1])
677 TempList
.insert(IncludeOffset
, TAB_COMMENT_SPLIT
)
678 self
.Profile
.FileLinesList
[IncludeLine
- 1] = ''.join(TempList
)
679 if Processed
: # Nested and back-to-back support
680 self
.Rewind(DestLine
= IncFileProfile
.InsertStartLineNumber
- 1)
686 def _GetIfListCurrentItemStat(IfList
):
696 ## PreprocessConditionalStatement() method
698 # Preprocess conditional statement.
699 # In the end, rewind the file buffer pointer to the beginning
701 # @param self The object pointer
703 def PreprocessConditionalStatement(self
):
704 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
708 while self
._GetNextToken
():
709 # Determine section name and the location dependent macro
710 if self
._GetIfListCurrentItemStat
(IfList
):
711 if self
._Token
.startswith(TAB_SECTION_START
):
713 if not self
._Token
.endswith(TAB_SECTION_END
):
714 self
._SkipToToken
(TAB_SECTION_END
)
715 Header
+= self
._SkippedChars
716 if Header
.find('$(') != -1:
717 raise Warning("macro cannot be used in section header", self
.FileName
, self
.CurrentLineNumber
)
718 self
._SectionHeaderParser
(Header
)
720 # Replace macros except in RULE section or out of section
721 elif self
._CurSection
and ReplacedLine
!= self
.CurrentLineNumber
:
722 ReplacedLine
= self
.CurrentLineNumber
724 CurLine
= self
.Profile
.FileLinesList
[ReplacedLine
- 1]
726 StartPos
= CurLine
.find('$(', PreIndex
)
727 EndPos
= CurLine
.find(')', StartPos
+2)
728 while StartPos
!= -1 and EndPos
!= -1 and self
._Token
not in {TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_IF
, TAB_ELSE_IF
}:
729 MacroName
= CurLine
[StartPos
+2: EndPos
]
730 MacorValue
= self
._GetMacroValue
(MacroName
)
731 if MacorValue
is not None:
732 CurLine
= CurLine
.replace('$(' + MacroName
+ ')', MacorValue
, 1)
733 if MacorValue
.find('$(') != -1:
736 PreIndex
= StartPos
+ len(MacorValue
)
738 PreIndex
= EndPos
+ 1
739 StartPos
= CurLine
.find('$(', PreIndex
)
740 EndPos
= CurLine
.find(')', StartPos
+2)
741 self
.Profile
.FileLinesList
[ReplacedLine
- 1] = CurLine
744 if self
._Token
== TAB_DEFINE
:
745 if self
._GetIfListCurrentItemStat
(IfList
):
746 if not self
._CurSection
:
747 raise Warning("macro cannot be defined in Rule section or out of section", self
.FileName
, self
.CurrentLineNumber
)
748 DefineLine
= self
.CurrentLineNumber
- 1
749 DefineOffset
= self
.CurrentOffsetWithinLine
- len(TAB_DEFINE
)
750 if not self
._GetNextToken
():
751 raise Warning.Expected("Macro name", self
.FileName
, self
.CurrentLineNumber
)
753 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
754 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
756 Value
= self
._GetExpression
()
757 self
._SetMacroValue
(Macro
, Value
)
758 self
._WipeOffArea
.append(((DefineLine
, DefineOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
759 elif self
._Token
== 'SET':
760 if not self
._GetIfListCurrentItemStat
(IfList
):
762 SetLine
= self
.CurrentLineNumber
- 1
763 SetOffset
= self
.CurrentOffsetWithinLine
- len('SET')
764 PcdPair
= self
._GetNextPcdSettings
()
765 PcdName
= "%s.%s" % (PcdPair
[1], PcdPair
[0])
766 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
767 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
769 Value
= self
._GetExpression
()
770 Value
= self
._EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
772 self
._PcdDict
[PcdName
] = Value
774 self
.Profile
.PcdDict
[PcdPair
] = Value
775 self
.SetPcdLocalation(PcdPair
)
776 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
777 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
779 self
._WipeOffArea
.append(((SetLine
, SetOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
780 elif self
._Token
in {TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_IF
}:
781 IfStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
._Token
))
782 IfList
.append([IfStartPos
, None, None])
784 CondLabel
= self
._Token
785 Expression
= self
._GetExpression
()
787 if CondLabel
== TAB_IF
:
788 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
790 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'in')
791 if CondLabel
== TAB_IF_N_DEF
:
792 ConditionSatisfied
= not ConditionSatisfied
794 BranchDetermined
= ConditionSatisfied
795 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, BranchDetermined
]
796 if ConditionSatisfied
:
797 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
798 elif self
._Token
in {TAB_ELSE_IF
, TAB_ELSE
}:
799 ElseStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
._Token
))
801 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
804 IfList
[-1] = [ElseStartPos
, False, True]
805 self
._WipeOffArea
.append((ElseStartPos
, (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
807 self
._WipeOffArea
.append((IfList
[-1][0], ElseStartPos
))
808 IfList
[-1] = [ElseStartPos
, True, IfList
[-1][2]]
809 if self
._Token
== TAB_ELSE_IF
:
810 Expression
= self
._GetExpression
()
811 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
812 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, IfList
[-1][2]]
816 IfList
[-1][1] = False
819 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
820 elif self
._Token
== '!endif':
822 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
824 self
._WipeOffArea
.append(((self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len('!endif')), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
826 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
829 elif not IfList
: # Don't use PCDs inside conditional directive
830 if self
.CurrentLineNumber
<= RegionLayoutLine
:
831 # Don't try the same line twice
833 SetPcd
= ShortcutPcdPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
835 self
._PcdDict
[SetPcd
.group('name')] = SetPcd
.group('value')
836 RegionLayoutLine
= self
.CurrentLineNumber
838 RegionSize
= RegionSizePattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
840 RegionLayoutLine
= self
.CurrentLineNumber
842 RegionSizeGuid
= RegionSizeGuidPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
])
843 if not RegionSizeGuid
:
844 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
846 self
._PcdDict
[RegionSizeGuid
.group('base')] = RegionSize
.group('base')
847 self
._PcdDict
[RegionSizeGuid
.group('size')] = RegionSize
.group('size')
848 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
851 raise Warning("Missing !endif", self
.FileName
, self
.CurrentLineNumber
)
854 def _CollectMacroPcd(self
):
858 MacroDict
.update(GlobalData
.gPlatformPcds
)
859 MacroDict
.update(self
._PcdDict
)
862 MacroDict
.update(GlobalData
.gPlatformDefines
)
866 ScopeMacro
= self
._MacroDict
[TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
868 MacroDict
.update(ScopeMacro
)
871 ScopeMacro
= self
._MacroDict
[
877 MacroDict
.update(ScopeMacro
)
879 MacroDict
.update(GlobalData
.gGlobalDefines
)
880 MacroDict
.update(GlobalData
.gCommandLineDefines
)
881 for Item
in GlobalData
.BuildOptionPcd
:
882 if isinstance(Item
, tuple):
884 PcdName
, TmpValue
= Item
.split(TAB_EQUAL_SPLIT
)
885 TmpValue
= BuildOptionValue(TmpValue
, {})
886 MacroDict
[PcdName
.strip()] = TmpValue
891 def _EvaluateConditional(self
, Expression
, Line
, Op
= None, Value
= None):
892 MacroPcdDict
= self
._CollectMacroPcd
()
896 return ValueExpression(Expression
, MacroPcdDict
)(True)
898 return ValueExpression(Expression
, MacroPcdDict
)()
899 except WrnExpression
as Excpt
:
901 # Catch expression evaluation warning here. We need to report
902 # the precise number of line and return the evaluation result
904 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
905 File
=self
.FileName
, ExtraData
=self
._CurrentLine
(),
908 except Exception as Excpt
:
909 if hasattr(Excpt
, 'Pcd'):
910 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
911 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
912 raise Warning("Cannot use this PCD (%s) in an expression as"
913 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
914 " of the DSC file (%s), and it is currently defined in this section:"
915 " %s, line #: %d." % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE'], Info
[0], Info
[1]),
918 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE']),
921 raise Warning(str(Excpt
), self
.FileName
, Line
)
923 if Expression
.startswith('$(') and Expression
[-1] == ')':
924 Expression
= Expression
[2:-1]
925 return Expression
in MacroPcdDict
929 # Check whether input string is found from current char position along
930 # If found, the string value is put into self._Token
932 # @param self The object pointer
933 # @param String The string to search
934 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
935 # @retval True Successfully find string, file buffer pointer moved forward
936 # @retval False Not able to find string, file buffer pointer not changed
938 def _IsToken(self
, String
, IgnoreCase
= False):
939 self
._SkipWhiteSpace
()
941 # Only consider the same line, no multi-line token allowed
942 StartPos
= self
.CurrentOffsetWithinLine
945 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
947 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
949 self
.CurrentOffsetWithinLine
+= len(String
)
950 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
954 ## _IsKeyword() method
956 # Check whether input keyword is found from current char position along, whole word only!
957 # If found, the string value is put into self._Token
959 # @param self The object pointer
960 # @param Keyword The string to search
961 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
962 # @retval True Successfully find string, file buffer pointer moved forward
963 # @retval False Not able to find string, file buffer pointer not changed
965 def _IsKeyword(self
, KeyWord
, IgnoreCase
= False):
966 self
._SkipWhiteSpace
()
968 # Only consider the same line, no multi-line token allowed
969 StartPos
= self
.CurrentOffsetWithinLine
972 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(KeyWord
.upper())
974 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(KeyWord
)
976 followingChar
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
+ len(KeyWord
)]
977 if not str(followingChar
).isspace() and followingChar
not in SEPARATORS
:
979 self
.CurrentOffsetWithinLine
+= len(KeyWord
)
980 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
984 def _GetExpression(self
):
985 Line
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
986 Index
= len(Line
) - 1
987 while Line
[Index
] in CR_LB_SET
:
989 ExpressionString
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:Index
+1]
990 self
.CurrentOffsetWithinLine
+= len(ExpressionString
)
991 ExpressionString
= ExpressionString
.strip()
992 return ExpressionString
994 ## _GetNextWord() method
996 # Get next C name from file lines
997 # If found, the string value is put into self._Token
999 # @param self The object pointer
1000 # @retval True Successfully find a C name string, file buffer pointer moved forward
1001 # @retval False Not able to find a C name string, file buffer pointer not changed
1003 def _GetNextWord(self
):
1004 self
._SkipWhiteSpace
()
1005 if self
._EndOfFile
():
1008 TempChar
= self
._CurrentChar
()
1009 StartPos
= self
.CurrentOffsetWithinLine
1010 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_':
1012 while not self
._EndOfLine
():
1013 TempChar
= self
._CurrentChar
()
1014 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1015 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-':
1021 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1026 def _GetNextPcdWord(self
):
1027 self
._SkipWhiteSpace
()
1028 if self
._EndOfFile
():
1031 TempChar
= self
._CurrentChar
()
1032 StartPos
= self
.CurrentOffsetWithinLine
1033 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_' or TempChar
== TAB_SECTION_START
or TempChar
== TAB_SECTION_END
:
1035 while not self
._EndOfLine
():
1036 TempChar
= self
._CurrentChar
()
1037 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1038 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-' or TempChar
== TAB_SECTION_START
or TempChar
== TAB_SECTION_END
:
1044 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1049 ## _GetNextToken() method
1051 # Get next token unit before a seperator
1052 # If found, the string value is put into self._Token
1054 # @param self The object pointer
1055 # @retval True Successfully find a token unit, file buffer pointer moved forward
1056 # @retval False Not able to find a token unit, file buffer pointer not changed
1058 def _GetNextToken(self
):
1059 # Skip leading spaces, if exist.
1060 self
._SkipWhiteSpace
()
1061 if self
._EndOfFile
():
1063 # Record the token start position, the position of the first non-space char.
1064 StartPos
= self
.CurrentOffsetWithinLine
1065 StartLine
= self
.CurrentLineNumber
1066 while StartLine
== self
.CurrentLineNumber
:
1067 TempChar
= self
._CurrentChar
()
1068 # Try to find the end char that is not a space and not in seperator tuple.
1069 # That is, when we got a space or any char in the tuple, we got the end of token.
1070 if not str(TempChar
).isspace() and TempChar
not in SEPARATORS
:
1072 # if we happen to meet a seperator as the first char, we must proceed to get it.
1073 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1074 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPARATORS
:
1082 EndPos
= self
.CurrentOffsetWithinLine
1083 if self
.CurrentLineNumber
!= StartLine
:
1084 EndPos
= len(self
.Profile
.FileLinesList
[StartLine
-1])
1085 self
._Token
= self
.Profile
.FileLinesList
[StartLine
-1][StartPos
: EndPos
]
1086 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
}:
1087 self
._Token
= self
._Token
.lower()
1088 if StartPos
!= self
.CurrentOffsetWithinLine
:
1093 ## _GetNextGuid() method
1095 # Get next token unit before a seperator
1096 # If found, the GUID string is put into self._Token
1098 # @param self The object pointer
1099 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
1100 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
1102 def _GetNextGuid(self
):
1103 if not self
._GetNextToken
():
1105 if gGuidPattern
.match(self
._Token
) is not None:
1112 def _Verify(Name
, Value
, Scope
):
1113 # value verification only applies to numeric values.
1114 if Scope
not in TAB_PCD_NUMERIC_TYPES
:
1119 ValueNumber
= int(Value
, 0)
1121 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value is not valid dec or hex number for %s." % Name
)
1123 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value can't be set to negative value for %s." % Name
)
1124 if ValueNumber
> MAX_VAL_TYPE
[Scope
]:
1125 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "Too large value for %s." % Name
)
1128 ## _UndoToken() method
1130 # Go back one token unit in file buffer
1132 # @param self The object pointer
1134 def _UndoToken(self
):
1136 while self
._CurrentChar
().isspace():
1137 if not self
._UndoOneChar
():
1142 StartPos
= self
.CurrentOffsetWithinLine
1143 CurrentLine
= self
.CurrentLineNumber
1144 while CurrentLine
== self
.CurrentLineNumber
:
1146 TempChar
= self
._CurrentChar
()
1147 # Try to find the end char that is not a space and not in seperator tuple.
1148 # That is, when we got a space or any char in the tuple, we got the end of token.
1149 if not str(TempChar
).isspace() and not TempChar
in SEPARATORS
:
1150 if not self
._UndoOneChar
():
1152 # if we happen to meet a seperator as the first char, we must proceed to get it.
1153 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1154 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPARATORS
:
1161 ## _GetNextHexNumber() method
1163 # Get next HEX data before a seperator
1164 # If found, the HEX data is put into self._Token
1166 # @param self The object pointer
1167 # @retval True Successfully find a HEX data, file buffer pointer moved forward
1168 # @retval False Not able to find a HEX data, file buffer pointer not changed
1170 def _GetNextHexNumber(self
):
1171 if not self
._GetNextToken
():
1173 if gHexPatternAll
.match(self
._Token
):
1179 ## _GetNextDecimalNumber() method
1181 # Get next decimal data before a seperator
1182 # If found, the decimal data is put into self._Token
1184 # @param self The object pointer
1185 # @retval True Successfully find a decimal data, file buffer pointer moved forward
1186 # @retval False Not able to find a decimal data, file buffer pointer not changed
1188 def _GetNextDecimalNumber(self
):
1189 if not self
._GetNextToken
():
1191 if self
._Token
.isdigit():
1197 def _GetNextPcdSettings(self
):
1198 if not self
._GetNextWord
():
1199 raise Warning.Expected("<PcdTokenSpaceCName>", self
.FileName
, self
.CurrentLineNumber
)
1200 pcdTokenSpaceCName
= self
._Token
1202 if not self
._IsToken
(TAB_SPLIT
):
1203 raise Warning.Expected(".", self
.FileName
, self
.CurrentLineNumber
)
1205 if not self
._GetNextWord
():
1206 raise Warning.Expected("<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1207 pcdCName
= self
._Token
1210 while self
._IsToken
(TAB_SPLIT
):
1211 if not self
._GetNextPcdWord
():
1212 raise Warning.Expected("Pcd Fields", self
.FileName
, self
.CurrentLineNumber
)
1213 Fields
.append(self
._Token
)
1215 return (pcdCName
, pcdTokenSpaceCName
,TAB_SPLIT
.join(Fields
))
1217 ## _GetStringData() method
1219 # Get string contents quoted in ""
1220 # If found, the decimal data is put into self._Token
1222 # @param self The object pointer
1223 # @retval True Successfully find a string data, file buffer pointer moved forward
1224 # @retval False Not able to find a string data, file buffer pointer not changed
1226 def _GetStringData(self
):
1228 if self
._Token
.startswith(T_CHAR_DOUBLE_QUOTE
) or self
._Token
.startswith("L\""):
1229 QuoteToUse
= T_CHAR_DOUBLE_QUOTE
1230 elif self
._Token
.startswith(T_CHAR_SINGLE_QUOTE
) or self
._Token
.startswith("L\'"):
1231 QuoteToUse
= T_CHAR_SINGLE_QUOTE
1236 self
._SkipToToken
(QuoteToUse
)
1237 currentLineNumber
= self
.CurrentLineNumber
1239 if not self
._SkipToToken
(QuoteToUse
):
1240 raise Warning(QuoteToUse
, self
.FileName
, self
.CurrentLineNumber
)
1241 if currentLineNumber
!= self
.CurrentLineNumber
:
1242 raise Warning(QuoteToUse
, self
.FileName
, self
.CurrentLineNumber
)
1243 self
._Token
= self
._SkippedChars
.rstrip(QuoteToUse
)
1246 ## _SkipToToken() method
1248 # Search forward in file buffer for the string
1249 # The skipped chars are put into self._SkippedChars
1251 # @param self The object pointer
1252 # @param String The string to search
1253 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1254 # @retval True Successfully find the string, file buffer pointer moved forward
1255 # @retval False Not able to find the string, file buffer pointer not changed
1257 def _SkipToToken(self
, String
, IgnoreCase
= False):
1258 StartPos
= self
.GetFileBufferPos()
1260 self
._SkippedChars
= ""
1261 while not self
._EndOfFile
():
1264 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
1266 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
1268 self
.CurrentOffsetWithinLine
+= len(String
)
1269 self
._SkippedChars
+= String
1271 self
._SkippedChars
+= str(self
._CurrentChar
())
1274 self
.SetFileBufferPos(StartPos
)
1275 self
._SkippedChars
= ""
1278 ## GetFileBufferPos() method
1280 # Return the tuple of current line and offset within the line
1282 # @param self The object pointer
1283 # @retval Tuple Line number and offset pair
1285 def GetFileBufferPos(self
):
1286 return (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
)
1288 ## SetFileBufferPos() method
1290 # Restore the file buffer position
1292 # @param self The object pointer
1293 # @param Pos The new file buffer position
1295 def SetFileBufferPos(self
, Pos
):
1296 (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
) = Pos
1298 ## Preprocess() method
1300 # Preprocess comment, conditional directive, include directive, replace macro.
1301 # Exception will be raised if syntax error found
1303 # @param self The object pointer
1305 def Preprocess(self
):
1306 self
._StringToList
()
1307 self
.PreprocessFile()
1308 self
.PreprocessIncludeFile()
1309 self
._StringToList
()
1310 self
.PreprocessFile()
1311 self
.PreprocessConditionalStatement()
1312 self
._StringToList
()
1313 for Pos
in self
._WipeOffArea
:
1314 self
._ReplaceFragment
(Pos
[0], Pos
[1])
1315 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
1317 while self
._GetDefines
():
1320 ## ParseFile() method
1322 # Parse the file profile buffer to extract fd, fv ... information
1323 # Exception will be raised if syntax error found
1325 # @param self The object pointer
1327 def ParseFile(self
):
1332 # Keep processing sections of the FDF until no new sections or a syntax error is found
1334 while self
._GetFd
() or self
._GetFv
() or self
._GetFmp
() or self
._GetCapsule
() or self
._GetVtf
() or self
._GetRule
() or self
._GetOptionRom
():
1337 except Warning as X
:
1339 #'\n\tGot Token: \"%s\" from File %s\n' % (self._Token, FileLineTuple[0]) + \
1340 # At this point, the closest parent would be the included file itself
1341 Profile
= GetParentAtLine(X
.OriginalLineNumber
)
1342 if Profile
is not None:
1343 X
.Message
+= ' near line %d, column %d: %s' \
1344 % (X
.LineNumber
, 0, Profile
.FileLinesList
[X
.LineNumber
-1])
1346 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1347 X
.Message
+= ' near line %d, column %d: %s' \
1348 % (FileLineTuple
[1], self
.CurrentOffsetWithinLine
+ 1, self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:].rstrip(TAB_LINE_BREAK
).rstrip(T_CHAR_CR
))
1351 ## SectionParser() method
1353 # Parse the file section info
1354 # Exception will be raised if syntax error found
1356 # @param self The object pointer
1357 # @param section The section string
1359 def SectionParser(self
, section
):
1361 if not S
.startswith("[DEFINES") and not S
.startswith("[FD.") and not S
.startswith("[FV.") and not S
.startswith("[CAPSULE.") \
1362 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM.") and not S
.startswith('[FMPPAYLOAD.'):
1363 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self
.FileName
, self
.CurrentLineNumber
)
1365 ## _GetDefines() method
1367 # Get Defines section contents and store its data into AllMacrosList
1369 # @param self The object pointer
1370 # @retval True Successfully find a Defines
1371 # @retval False Not able to find a Defines
1373 def _GetDefines(self
):
1374 if not self
._GetNextToken
():
1377 S
= self
._Token
.upper()
1378 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[DEFINES"):
1379 self
.SectionParser(S
)
1384 if not self
._IsToken
("[DEFINES", True):
1385 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1386 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1387 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1388 raise Warning.Expected("[DEFINES", self
.FileName
, self
.CurrentLineNumber
)
1390 if not self
._IsToken
(TAB_SECTION_END
):
1391 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
1393 while self
._GetNextWord
():
1394 # handle the SET statement
1395 if self
._Token
== 'SET':
1397 self
._GetSetStatement
(None)
1402 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1403 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1404 if not self
._GetNextToken
() or self
._Token
.startswith(TAB_SECTION_START
):
1405 raise Warning.Expected("MACRO value", self
.FileName
, self
.CurrentLineNumber
)
1410 ##_GetError() method
1411 def _GetError(self
):
1412 #save the Current information
1413 CurrentLine
= self
.CurrentLineNumber
1414 CurrentOffset
= self
.CurrentOffsetWithinLine
1415 while self
._GetNextToken
():
1416 if self
._Token
== TAB_ERROR
:
1417 EdkLogger
.error('FdfParser', ERROR_STATEMENT
, self
._CurrentLine
().replace(TAB_ERROR
, '', 1), File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
1418 self
.CurrentLineNumber
= CurrentLine
1419 self
.CurrentOffsetWithinLine
= CurrentOffset
1423 # Get FD section contents and store its data into FD dictionary of self.Profile
1425 # @param self The object pointer
1426 # @retval True Successfully find a FD
1427 # @retval False Not able to find a FD
1430 if not self
._GetNextToken
():
1433 S
= self
._Token
.upper()
1434 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FD."):
1435 if not S
.startswith("[FV.") and not S
.startswith('[FMPPAYLOAD.') and not S
.startswith("[CAPSULE.") \
1436 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM."):
1437 raise Warning("Unknown section", self
.FileName
, self
.CurrentLineNumber
)
1442 if not self
._IsToken
("[FD.", True):
1443 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1444 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1445 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1446 raise Warning.Expected("[FD.]", self
.FileName
, self
.CurrentLineNumber
)
1448 FdName
= self
._GetUiName
()
1450 if len (self
.Profile
.FdDict
) == 0:
1451 FdName
= GenFdsGlobalVariable
.PlatformName
1452 if FdName
== "" and GlobalData
.gActivePlatform
:
1453 FdName
= GlobalData
.gActivePlatform
.PlatformName
1454 self
.Profile
.FdNameNotSet
= True
1456 raise Warning.Expected("FdName in [FD.] section", self
.FileName
, self
.CurrentLineNumber
)
1457 self
.CurrentFdName
= FdName
.upper()
1459 if self
.CurrentFdName
in self
.Profile
.FdDict
:
1460 raise Warning("Unexpected the same FD name", self
.FileName
, self
.CurrentLineNumber
)
1462 if not self
._IsToken
(TAB_SECTION_END
):
1463 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
1466 FdObj
.FdUiName
= self
.CurrentFdName
1467 self
.Profile
.FdDict
[self
.CurrentFdName
] = FdObj
1469 if len (self
.Profile
.FdDict
) > 1 and self
.Profile
.FdNameNotSet
:
1470 raise Warning.Expected("all FDs have their name", self
.FileName
, self
.CurrentLineNumber
)
1472 Status
= self
._GetCreateFile
(FdObj
)
1474 raise Warning("FD name error", self
.FileName
, self
.CurrentLineNumber
)
1476 while self
._GetTokenStatements
(FdObj
):
1478 for Attr
in ("BaseAddress", "Size", "ErasePolarity"):
1479 if getattr(FdObj
, Attr
) is None:
1480 self
._GetNextToken
()
1481 raise Warning("Keyword %s missing" % Attr
, self
.FileName
, self
.CurrentLineNumber
)
1483 if not FdObj
.BlockSizeList
:
1484 FdObj
.BlockSizeList
.append((1, FdObj
.Size
, None))
1486 self
._GetDefineStatements
(FdObj
)
1488 self
._GetSetStatements
(FdObj
)
1490 if not self
._GetRegionLayout
(FdObj
):
1491 raise Warning.Expected("region layout", self
.FileName
, self
.CurrentLineNumber
)
1493 while self
._GetRegionLayout
(FdObj
):
1497 ## _GetUiName() method
1499 # Return the UI name of a section
1501 # @param self The object pointer
1502 # @retval FdName UI name
1504 def _GetUiName(self
):
1506 if self
._GetNextWord
():
1511 ## _GetCreateFile() method
1513 # Return the output file name of object
1515 # @param self The object pointer
1516 # @param Obj object whose data will be stored in file
1517 # @retval FdName UI name
1519 def _GetCreateFile(self
, Obj
):
1520 if self
._IsKeyword
("CREATE_FILE"):
1521 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1522 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1524 if not self
._GetNextToken
():
1525 raise Warning.Expected("file name", self
.FileName
, self
.CurrentLineNumber
)
1527 FileName
= self
._Token
1528 Obj
.CreateFileName
= FileName
1532 def SetPcdLocalation(self
,pcdpair
):
1533 self
.Profile
.PcdLocalDict
[pcdpair
] = (self
.Profile
.FileName
,self
.CurrentLineNumber
)
1535 ## _GetTokenStatements() method
1537 # Get token statements
1539 # @param self The object pointer
1540 # @param Obj for whom token statement is got
1542 def _GetTokenStatements(self
, Obj
):
1543 if self
._IsKeyword
("BaseAddress"):
1544 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1545 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1547 if not self
._GetNextHexNumber
():
1548 raise Warning.Expected("Hex base address", self
.FileName
, self
.CurrentLineNumber
)
1550 Obj
.BaseAddress
= self
._Token
1552 if self
._IsToken
(TAB_VALUE_SPLIT
):
1553 pcdPair
= self
._GetNextPcdSettings
()
1554 Obj
.BaseAddressPcd
= pcdPair
1555 self
.Profile
.PcdDict
[pcdPair
] = Obj
.BaseAddress
1556 self
.SetPcdLocalation(pcdPair
)
1557 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1558 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1561 if self
._IsKeyword
("Size"):
1562 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1563 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1565 if not self
._GetNextHexNumber
():
1566 raise Warning.Expected("Hex size", self
.FileName
, self
.CurrentLineNumber
)
1569 if self
._IsToken
(TAB_VALUE_SPLIT
):
1570 pcdPair
= self
._GetNextPcdSettings
()
1571 Obj
.SizePcd
= pcdPair
1572 self
.Profile
.PcdDict
[pcdPair
] = Size
1573 self
.SetPcdLocalation(pcdPair
)
1574 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1575 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1576 Obj
.Size
= long(Size
, 0)
1579 if self
._IsKeyword
("ErasePolarity"):
1580 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1581 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1583 if not self
._GetNextToken
():
1584 raise Warning.Expected("Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1586 if not self
._Token
in {"1", "0"}:
1587 raise Warning.Expected("1 or 0 Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1589 Obj
.ErasePolarity
= self
._Token
1592 return self
._GetBlockStatements
(Obj
)
1594 ## _GetAddressStatements() method
1596 # Get address statements
1598 # @param self The object pointer
1599 # @param Obj for whom address statement is got
1600 # @retval True Successfully find
1601 # @retval False Not able to find
1603 def _GetAddressStatements(self
, Obj
):
1604 if self
._IsKeyword
("BsBaseAddress"):
1605 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1606 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1608 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1609 raise Warning.Expected("address", self
.FileName
, self
.CurrentLineNumber
)
1611 BsAddress
= long(self
._Token
, 0)
1612 Obj
.BsBaseAddress
= BsAddress
1614 if self
._IsKeyword
("RtBaseAddress"):
1615 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1616 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1618 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1619 raise Warning.Expected("address", self
.FileName
, self
.CurrentLineNumber
)
1621 RtAddress
= long(self
._Token
, 0)
1622 Obj
.RtBaseAddress
= RtAddress
1624 ## _GetBlockStatements() method
1626 # Get block statements
1628 # @param self The object pointer
1629 # @param Obj for whom block statement is got
1631 def _GetBlockStatements(self
, Obj
):
1633 while self
._GetBlockStatement
(Obj
):
1636 Item
= Obj
.BlockSizeList
[-1]
1637 if Item
[0] is None or Item
[1] is None:
1638 raise Warning.Expected("block statement", self
.FileName
, self
.CurrentLineNumber
)
1641 ## _GetBlockStatement() method
1643 # Get block statement
1645 # @param self The object pointer
1646 # @param Obj for whom block statement is got
1647 # @retval True Successfully find
1648 # @retval False Not able to find
1650 def _GetBlockStatement(self
, Obj
):
1651 if not self
._IsKeyword
("BlockSize"):
1654 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1655 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1657 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
1658 raise Warning.Expected("Hex or Integer block size", self
.FileName
, self
.CurrentLineNumber
)
1660 BlockSize
= self
._Token
1662 if self
._IsToken
(TAB_VALUE_SPLIT
):
1663 PcdPair
= self
._GetNextPcdSettings
()
1664 BlockSizePcd
= PcdPair
1665 self
.Profile
.PcdDict
[PcdPair
] = BlockSize
1666 self
.SetPcdLocalation(PcdPair
)
1667 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1668 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1669 BlockSize
= long(BlockSize
, 0)
1672 if self
._IsKeyword
("NumBlocks"):
1673 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1674 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1676 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1677 raise Warning.Expected("block numbers", self
.FileName
, self
.CurrentLineNumber
)
1679 BlockNumber
= long(self
._Token
, 0)
1681 Obj
.BlockSizeList
.append((BlockSize
, BlockNumber
, BlockSizePcd
))
1684 ## _GetDefineStatements() method
1686 # Get define statements
1688 # @param self The object pointer
1689 # @param Obj for whom define statement is got
1690 # @retval True Successfully find
1691 # @retval False Not able to find
1693 def _GetDefineStatements(self
, Obj
):
1694 while self
._GetDefineStatement
(Obj
):
1697 ## _GetDefineStatement() method
1699 # Get define statement
1701 # @param self The object pointer
1702 # @param Obj for whom define statement is got
1703 # @retval True Successfully find
1704 # @retval False Not able to find
1706 def _GetDefineStatement(self
, Obj
):
1707 if self
._IsKeyword
(TAB_DEFINE
):
1708 self
._GetNextToken
()
1710 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1711 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1713 if not self
._GetNextToken
():
1714 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
1717 Macro
= '$(' + Macro
+ ')'
1718 Obj
.DefineVarDict
[Macro
] = Value
1723 ## _GetSetStatements() method
1725 # Get set statements
1727 # @param self The object pointer
1728 # @param Obj for whom set statement is got
1729 # @retval True Successfully find
1730 # @retval False Not able to find
1732 def _GetSetStatements(self
, Obj
):
1733 while self
._GetSetStatement
(Obj
):
1736 ## _GetSetStatement() method
1740 # @param self The object pointer
1741 # @param Obj for whom set statement is got
1742 # @retval True Successfully find
1743 # @retval False Not able to find
1745 def _GetSetStatement(self
, Obj
):
1746 if self
._IsKeyword
("SET"):
1747 PcdPair
= self
._GetNextPcdSettings
()
1749 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1750 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1752 Value
= self
._GetExpression
()
1753 Value
= self
._EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
1756 Obj
.SetVarDict
[PcdPair
] = Value
1757 self
.Profile
.PcdDict
[PcdPair
] = Value
1758 self
.SetPcdLocalation(PcdPair
)
1759 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1760 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1765 ## _CalcRegionExpr(self)
1767 # Calculate expression for offset or size of a region
1769 # @return: None if invalid expression
1770 # Calculated number if successfully
1772 def _CalcRegionExpr(self
):
1773 StartPos
= self
.GetFileBufferPos()
1776 while not self
._EndOfFile
():
1777 CurCh
= self
._CurrentChar
()
1783 if CurCh
in '|\r\n' and PairCount
== 0:
1789 ValueExpression(Expr
,
1790 self
._CollectMacroPcd
()
1793 self
.SetFileBufferPos(StartPos
)
1796 ## _GetRegionLayout() method
1798 # Get region layout for FD
1800 # @param self The object pointer
1801 # @param theFd for whom region is got
1802 # @retval True Successfully find
1803 # @retval False Not able to find
1805 def _GetRegionLayout(self
, theFd
):
1806 Offset
= self
._CalcRegionExpr
()
1810 RegionObj
= Region()
1811 RegionObj
.Offset
= Offset
1812 theFd
.RegionList
.append(RegionObj
)
1814 if not self
._IsToken
(TAB_VALUE_SPLIT
):
1815 raise Warning.Expected("'|'", self
.FileName
, self
.CurrentLineNumber
)
1817 Size
= self
._CalcRegionExpr
()
1819 raise Warning.Expected("Region Size", self
.FileName
, self
.CurrentLineNumber
)
1820 RegionObj
.Size
= Size
1822 if not self
._GetNextWord
():
1825 if not self
._Token
in {"SET", BINARY_FILE_TYPE_FV
, "FILE", "DATA", "CAPSULE", "INF"}:
1827 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1828 # Or it might be next region's offset described by an expression which starts with a PCD.
1829 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1832 IsRegionPcd
= (RegionSizeGuidPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]) or
1833 RegionOffsetPcdPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]))
1835 RegionObj
.PcdOffset
= self
._GetNextPcdSettings
()
1836 self
.Profile
.PcdDict
[RegionObj
.PcdOffset
] = "0x%08X" % (RegionObj
.Offset
+ long(theFd
.BaseAddress
, 0))
1837 self
.SetPcdLocalation(RegionObj
.PcdOffset
)
1838 self
._PcdDict
['%s.%s' % (RegionObj
.PcdOffset
[1], RegionObj
.PcdOffset
[0])] = "0x%x" % RegionObj
.Offset
1839 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1840 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdOffset
] = FileLineTuple
1841 if self
._IsToken
(TAB_VALUE_SPLIT
):
1842 RegionObj
.PcdSize
= self
._GetNextPcdSettings
()
1843 self
.Profile
.PcdDict
[RegionObj
.PcdSize
] = "0x%08X" % RegionObj
.Size
1844 self
.SetPcdLocalation(RegionObj
.PcdSize
)
1845 self
._PcdDict
['%s.%s' % (RegionObj
.PcdSize
[1], RegionObj
.PcdSize
[0])] = "0x%x" % RegionObj
.Size
1846 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1847 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdSize
] = FileLineTuple
1849 if not self
._GetNextWord
():
1852 if self
._Token
== "SET":
1854 self
._GetSetStatements
(RegionObj
)
1855 if not self
._GetNextWord
():
1858 elif self
._Token
== BINARY_FILE_TYPE_FV
:
1860 self
._GetRegionFvType
(RegionObj
)
1862 elif self
._Token
== "CAPSULE":
1864 self
._GetRegionCapType
(RegionObj
)
1866 elif self
._Token
== "FILE":
1868 self
._GetRegionFileType
(RegionObj
)
1870 elif self
._Token
== "INF":
1872 RegionObj
.RegionType
= "INF"
1873 while self
._IsKeyword
("INF"):
1875 ffsInf
= self
._ParseInfStatement
()
1878 RegionObj
.RegionDataList
.append(ffsInf
)
1880 elif self
._Token
== "DATA":
1882 self
._GetRegionDataType
(RegionObj
)
1885 if self
._GetRegionLayout
(theFd
):
1887 raise Warning("A valid region type was not found. "
1888 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
1889 self
.FileName
, self
.CurrentLineNumber
)
1893 ## _GetRegionFvType() method
1895 # Get region fv data for region
1897 # @param self The object pointer
1898 # @param RegionObj for whom region data is got
1900 def _GetRegionFvType(self
, RegionObj
):
1901 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1902 raise Warning.Expected("'FV'", self
.FileName
, self
.CurrentLineNumber
)
1904 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1905 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1907 if not self
._GetNextToken
():
1908 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
1910 RegionObj
.RegionType
= BINARY_FILE_TYPE_FV
1911 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1913 while self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1915 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1916 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1918 if not self
._GetNextToken
():
1919 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
1921 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1923 ## _GetRegionCapType() method
1925 # Get region capsule data for region
1927 # @param self The object pointer
1928 # @param RegionObj for whom region data is got
1930 def _GetRegionCapType(self
, RegionObj
):
1931 if not self
._IsKeyword
("CAPSULE"):
1932 raise Warning.Expected("'CAPSULE'", self
.FileName
, self
.CurrentLineNumber
)
1934 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1935 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1937 if not self
._GetNextToken
():
1938 raise Warning.Expected("CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1940 RegionObj
.RegionType
= "CAPSULE"
1941 RegionObj
.RegionDataList
.append(self
._Token
)
1943 while self
._IsKeyword
("CAPSULE"):
1945 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1946 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1948 if not self
._GetNextToken
():
1949 raise Warning.Expected("CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1951 RegionObj
.RegionDataList
.append(self
._Token
)
1953 ## _GetRegionFileType() method
1955 # Get region file data for region
1957 # @param self The object pointer
1958 # @param RegionObj for whom region data is got
1960 def _GetRegionFileType(self
, RegionObj
):
1961 if not self
._IsKeyword
("FILE"):
1962 raise Warning.Expected("'FILE'", self
.FileName
, self
.CurrentLineNumber
)
1964 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1965 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1967 if not self
._GetNextToken
():
1968 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
1970 RegionObj
.RegionType
= "FILE"
1971 RegionObj
.RegionDataList
.append(self
._Token
)
1973 while self
._IsKeyword
("FILE"):
1975 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1976 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1978 if not self
._GetNextToken
():
1979 raise Warning.Expected("FILE name", self
.FileName
, self
.CurrentLineNumber
)
1981 RegionObj
.RegionDataList
.append(self
._Token
)
1983 ## _GetRegionDataType() method
1985 # Get region array data for region
1987 # @param self The object pointer
1988 # @param RegionObj for whom region data is got
1990 def _GetRegionDataType(self
, RegionObj
):
1991 if not self
._IsKeyword
("DATA"):
1992 raise Warning.Expected("Region Data type", self
.FileName
, self
.CurrentLineNumber
)
1994 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1995 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1997 if not self
._IsToken
("{"):
1998 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2000 if not self
._GetNextHexNumber
():
2001 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2003 if len(self
._Token
) > 18:
2004 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2006 # convert hex string value to byte hex string array
2007 AllString
= self
._Token
2008 AllStrLen
= len (AllString
)
2010 while AllStrLen
> 4:
2011 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
2012 AllStrLen
= AllStrLen
- 2
2013 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
2016 if len (self
._Token
) <= 4:
2017 while self
._IsToken
(TAB_COMMA_SPLIT
):
2018 if not self
._GetNextHexNumber
():
2019 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2020 if len(self
._Token
) > 4:
2021 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2022 DataString
+= self
._Token
2023 DataString
+= TAB_COMMA_SPLIT
2025 if not self
._IsToken
(T_CHAR_BRACE_R
):
2026 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2028 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2029 RegionObj
.RegionType
= "DATA"
2030 RegionObj
.RegionDataList
.append(DataString
)
2032 while self
._IsKeyword
("DATA"):
2034 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2035 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2037 if not self
._IsToken
("{"):
2038 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2040 if not self
._GetNextHexNumber
():
2041 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2043 if len(self
._Token
) > 18:
2044 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2046 # convert hex string value to byte hex string array
2047 AllString
= self
._Token
2048 AllStrLen
= len (AllString
)
2050 while AllStrLen
> 4:
2051 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
2052 AllStrLen
= AllStrLen
- 2
2053 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
2056 if len (self
._Token
) <= 4:
2057 while self
._IsToken
(TAB_COMMA_SPLIT
):
2058 if not self
._GetNextHexNumber
():
2059 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2060 if len(self
._Token
) > 4:
2061 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2062 DataString
+= self
._Token
2063 DataString
+= TAB_COMMA_SPLIT
2065 if not self
._IsToken
(T_CHAR_BRACE_R
):
2066 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2068 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2069 RegionObj
.RegionDataList
.append(DataString
)
2073 # Get FV section contents and store its data into FV dictionary of self.Profile
2075 # @param self The object pointer
2076 # @retval True Successfully find a FV
2077 # @retval False Not able to find a FV
2080 if not self
._GetNextToken
():
2083 S
= self
._Token
.upper()
2084 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FV."):
2085 self
.SectionParser(S
)
2090 if not self
._IsToken
("[FV.", True):
2091 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2092 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2093 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2094 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2096 FvName
= self
._GetUiName
()
2097 self
.CurrentFvName
= FvName
.upper()
2099 if not self
._IsToken
(TAB_SECTION_END
):
2100 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
2102 FvObj
= FV(Name
=self
.CurrentFvName
)
2103 self
.Profile
.FvDict
[self
.CurrentFvName
] = FvObj
2105 Status
= self
._GetCreateFile
(FvObj
)
2107 raise Warning("FV name error", self
.FileName
, self
.CurrentLineNumber
)
2109 self
._GetDefineStatements
(FvObj
)
2111 self
._GetAddressStatements
(FvObj
)
2114 self
._GetSetStatements
(FvObj
)
2116 if not (self
._GetBlockStatement
(FvObj
) or self
._GetFvBaseAddress
(FvObj
) or
2117 self
._GetFvForceRebase
(FvObj
) or self
._GetFvAlignment
(FvObj
) or
2118 self
._GetFvAttributes
(FvObj
) or self
._GetFvNameGuid
(FvObj
) or
2119 self
._GetFvExtEntryStatement
(FvObj
) or self
._GetFvNameString
(FvObj
)):
2122 if FvObj
.FvNameString
== 'TRUE' and not FvObj
.FvNameGuid
:
2123 raise Warning("FvNameString found but FvNameGuid was not found", self
.FileName
, self
.CurrentLineNumber
)
2125 self
._GetAprioriSection
(FvObj
)
2126 self
._GetAprioriSection
(FvObj
)
2129 isInf
= self
._GetInfStatement
(FvObj
)
2130 isFile
= self
._GetFileStatement
(FvObj
)
2131 if not isInf
and not isFile
:
2136 ## _GetFvAlignment() method
2138 # Get alignment for FV
2140 # @param self The object pointer
2141 # @param Obj for whom alignment is got
2142 # @retval True Successfully find a alignment statement
2143 # @retval False Not able to find a alignment statement
2145 def _GetFvAlignment(self
, Obj
):
2146 if not self
._IsKeyword
("FvAlignment"):
2149 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2150 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2152 if not self
._GetNextToken
():
2153 raise Warning.Expected("alignment value", self
.FileName
, self
.CurrentLineNumber
)
2155 if self
._Token
.upper() not in {"1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2156 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2157 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2159 raise Warning("Unknown alignment value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2160 Obj
.FvAlignment
= self
._Token
2163 ## _GetFvBaseAddress() method
2165 # Get BaseAddress for FV
2167 # @param self The object pointer
2168 # @param Obj for whom FvBaseAddress is got
2169 # @retval True Successfully find a FvBaseAddress statement
2170 # @retval False Not able to find a FvBaseAddress statement
2172 def _GetFvBaseAddress(self
, Obj
):
2173 if not self
._IsKeyword
("FvBaseAddress"):
2176 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2177 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2179 if not self
._GetNextToken
():
2180 raise Warning.Expected("FV base address value", self
.FileName
, self
.CurrentLineNumber
)
2182 if not BaseAddrValuePattern
.match(self
._Token
.upper()):
2183 raise Warning("Unknown FV base address value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2184 Obj
.FvBaseAddress
= self
._Token
2187 ## _GetFvForceRebase() method
2189 # Get FvForceRebase for FV
2191 # @param self The object pointer
2192 # @param Obj for whom FvForceRebase is got
2193 # @retval True Successfully find a FvForceRebase statement
2194 # @retval False Not able to find a FvForceRebase statement
2196 def _GetFvForceRebase(self
, Obj
):
2197 if not self
._IsKeyword
("FvForceRebase"):
2200 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2201 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2203 if not self
._GetNextToken
():
2204 raise Warning.Expected("FvForceRebase value", self
.FileName
, self
.CurrentLineNumber
)
2206 if self
._Token
.upper() not in {"TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"}:
2207 raise Warning("Unknown FvForceRebase value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2209 if self
._Token
.upper() in {"TRUE", "1", "0X1", "0X01"}:
2210 Obj
.FvForceRebase
= True
2211 elif self
._Token
.upper() in {"FALSE", "0", "0X0", "0X00"}:
2212 Obj
.FvForceRebase
= False
2214 Obj
.FvForceRebase
= None
2219 ## _GetFvAttributes() method
2221 # Get attributes for FV
2223 # @param self The object pointer
2224 # @param Obj for whom attribute is got
2227 def _GetFvAttributes(self
, FvObj
):
2229 while self
._GetNextWord
():
2232 if name
not in {"ERASE_POLARITY", "MEMORY_MAPPED", \
2233 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2234 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2235 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2236 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2237 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"}:
2241 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2242 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2244 if not self
._GetNextToken
() or self
._Token
.upper() not in {"TRUE", "FALSE", "1", "0"}:
2245 raise Warning.Expected("TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
2247 FvObj
.FvAttributeDict
[name
] = self
._Token
2251 ## _GetFvNameGuid() method
2253 # Get FV GUID for FV
2255 # @param self The object pointer
2256 # @param Obj for whom GUID is got
2259 def _GetFvNameGuid(self
, FvObj
):
2260 if not self
._IsKeyword
("FvNameGuid"):
2263 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2264 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2266 if not self
._GetNextGuid
():
2267 raise Warning.Expected("GUID value", self
.FileName
, self
.CurrentLineNumber
)
2269 FvObj
.FvNameGuid
= self
._Token
2273 def _GetFvNameString(self
, FvObj
):
2274 if not self
._IsKeyword
("FvNameString"):
2277 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2278 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2280 if not self
._GetNextToken
() or self
._Token
.upper() not in {'TRUE', 'FALSE'}:
2281 raise Warning.Expected("TRUE or FALSE for FvNameString", self
.FileName
, self
.CurrentLineNumber
)
2283 FvObj
.FvNameString
= self
._Token
2287 def _GetFvExtEntryStatement(self
, FvObj
):
2288 if not (self
._IsKeyword
("FV_EXT_ENTRY") or self
._IsKeyword
("FV_EXT_ENTRY_TYPE")):
2291 if not self
._IsKeyword
("TYPE"):
2292 raise Warning.Expected("'TYPE'", self
.FileName
, self
.CurrentLineNumber
)
2294 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2295 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2297 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
2298 raise Warning.Expected("Hex FV extension entry type value At Line ", self
.FileName
, self
.CurrentLineNumber
)
2300 FvObj
.FvExtEntryTypeValue
.append(self
._Token
)
2302 if not self
._IsToken
("{"):
2303 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2305 if not self
._IsKeyword
("FILE") and not self
._IsKeyword
("DATA"):
2306 raise Warning.Expected("'FILE' or 'DATA'", self
.FileName
, self
.CurrentLineNumber
)
2308 FvObj
.FvExtEntryType
.append(self
._Token
)
2310 if self
._Token
== 'DATA':
2311 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2312 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2314 if not self
._IsToken
("{"):
2315 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2317 if not self
._GetNextHexNumber
():
2318 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2320 if len(self
._Token
) > 4:
2321 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2323 DataString
= self
._Token
2324 DataString
+= TAB_COMMA_SPLIT
2326 while self
._IsToken
(TAB_COMMA_SPLIT
):
2327 if not self
._GetNextHexNumber
():
2328 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2329 if len(self
._Token
) > 4:
2330 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2331 DataString
+= self
._Token
2332 DataString
+= TAB_COMMA_SPLIT
2334 if not self
._IsToken
(T_CHAR_BRACE_R
):
2335 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2337 if not self
._IsToken
(T_CHAR_BRACE_R
):
2338 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2340 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2341 FvObj
.FvExtEntryData
.append(DataString
)
2343 if self
._Token
== 'FILE':
2344 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2345 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2347 if not self
._GetNextToken
():
2348 raise Warning.Expected("FV Extension Entry file path At Line ", self
.FileName
, self
.CurrentLineNumber
)
2350 FvObj
.FvExtEntryData
.append(self
._Token
)
2352 if not self
._IsToken
(T_CHAR_BRACE_R
):
2353 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2357 ## _GetAprioriSection() method
2359 # Get token statements
2361 # @param self The object pointer
2362 # @param FvObj for whom apriori is got
2363 # @retval True Successfully find apriori statement
2364 # @retval False Not able to find apriori statement
2366 def _GetAprioriSection(self
, FvObj
):
2367 if not self
._IsKeyword
("APRIORI"):
2370 if not self
._IsKeyword
("PEI") and not self
._IsKeyword
("DXE"):
2371 raise Warning.Expected("Apriori file type", self
.FileName
, self
.CurrentLineNumber
)
2372 AprType
= self
._Token
2374 if not self
._IsToken
("{"):
2375 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2377 AprSectionObj
= AprioriSection()
2378 AprSectionObj
.AprioriType
= AprType
2380 self
._GetDefineStatements
(AprSectionObj
)
2383 IsInf
= self
._GetInfStatement
(AprSectionObj
)
2384 IsFile
= self
._GetFileStatement
(AprSectionObj
)
2385 if not IsInf
and not IsFile
:
2388 if not self
._IsToken
(T_CHAR_BRACE_R
):
2389 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2391 FvObj
.AprioriSectionList
.append(AprSectionObj
)
2394 def _ParseInfStatement(self
):
2395 if not self
._IsKeyword
("INF"):
2398 ffsInf
= FfsInfStatement()
2399 self
._GetInfOptions
(ffsInf
)
2401 if not self
._GetNextToken
():
2402 raise Warning.Expected("INF file path", self
.FileName
, self
.CurrentLineNumber
)
2403 ffsInf
.InfFileName
= self
._Token
2404 if not ffsInf
.InfFileName
.endswith('.inf'):
2405 raise Warning.Expected(".inf file path", self
.FileName
, self
.CurrentLineNumber
)
2407 ffsInf
.CurrentLineNum
= self
.CurrentLineNumber
2408 ffsInf
.CurrentLineContent
= self
._CurrentLine
()
2410 #Replace $(SAPCE) with real space
2411 ffsInf
.InfFileName
= ffsInf
.InfFileName
.replace('$(SPACE)', ' ')
2413 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
2414 #do case sensitive check for file path
2415 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2417 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2419 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
2420 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
2421 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2422 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
2424 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
2425 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
2427 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
2429 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
2431 if self
._IsToken
(TAB_VALUE_SPLIT
):
2432 if self
._IsKeyword
('RELOCS_STRIPPED'):
2433 ffsInf
.KeepReloc
= False
2434 elif self
._IsKeyword
('RELOCS_RETAINED'):
2435 ffsInf
.KeepReloc
= True
2437 raise Warning("Unknown reloc strip flag '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2440 ## _GetInfStatement() method
2442 # Get INF statements
2444 # @param self The object pointer
2445 # @param Obj for whom inf statement is got
2446 # @retval True Successfully find inf statement
2447 # @retval False Not able to find inf statement
2449 def _GetInfStatement(self
, Obj
, ForCapsule
=False):
2450 ffsInf
= self
._ParseInfStatement
()
2455 myCapsuleFfs
= CapsuleFfs()
2456 myCapsuleFfs
.Ffs
= ffsInf
2457 Obj
.CapsuleDataList
.append(myCapsuleFfs
)
2459 Obj
.FfsList
.append(ffsInf
)
2462 ## _GetInfOptions() method
2464 # Get options for INF
2466 # @param self The object pointer
2467 # @param FfsInfObj for whom option is got
2469 def _GetInfOptions(self
, FfsInfObj
):
2470 if self
._IsKeyword
("FILE_GUID"):
2471 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2472 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2473 if not self
._GetNextGuid
():
2474 raise Warning.Expected("GUID value", self
.FileName
, self
.CurrentLineNumber
)
2475 FfsInfObj
.OverrideGuid
= self
._Token
2477 if self
._IsKeyword
("RuleOverride"):
2478 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2479 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2480 if not self
._GetNextToken
():
2481 raise Warning.Expected("Rule name", self
.FileName
, self
.CurrentLineNumber
)
2482 FfsInfObj
.Rule
= self
._Token
2484 if self
._IsKeyword
("VERSION"):
2485 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2486 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2487 if not self
._GetNextToken
():
2488 raise Warning.Expected("Version", self
.FileName
, self
.CurrentLineNumber
)
2490 if self
._GetStringData
():
2491 FfsInfObj
.Version
= self
._Token
2493 if self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2494 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2495 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2496 if not self
._GetNextToken
():
2497 raise Warning.Expected("UI name", self
.FileName
, self
.CurrentLineNumber
)
2499 if self
._GetStringData
():
2500 FfsInfObj
.Ui
= self
._Token
2502 if self
._IsKeyword
("USE"):
2503 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2504 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2505 if not self
._GetNextToken
():
2506 raise Warning.Expected("ARCH name", self
.FileName
, self
.CurrentLineNumber
)
2507 FfsInfObj
.UseArch
= self
._Token
2510 if self
._GetNextToken
():
2511 p
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2512 if p
.match(self
._Token
) and p
.match(self
._Token
).span()[1] == len(self
._Token
):
2513 FfsInfObj
.KeyStringList
.append(self
._Token
)
2514 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2520 while self
._GetNextToken
():
2521 if not p
.match(self
._Token
):
2522 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2523 FfsInfObj
.KeyStringList
.append(self
._Token
)
2525 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2528 ## _GetFileStatement() method
2530 # Get FILE statements
2532 # @param self The object pointer
2533 # @param Obj for whom FILE statement is got
2534 # @retval True Successfully find FILE statement
2535 # @retval False Not able to find FILE statement
2537 def _GetFileStatement(self
, Obj
, ForCapsule
= False):
2538 if not self
._IsKeyword
("FILE"):
2541 if not self
._GetNextWord
():
2542 raise Warning.Expected("FFS type", self
.FileName
, self
.CurrentLineNumber
)
2544 if ForCapsule
and self
._Token
== 'DATA':
2549 FfsFileObj
= FileStatement()
2550 FfsFileObj
.FvFileType
= self
._Token
2552 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2553 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2555 if not self
._GetNextGuid
():
2556 if not self
._GetNextWord
():
2557 raise Warning.Expected("File GUID", self
.FileName
, self
.CurrentLineNumber
)
2558 if self
._Token
== 'PCD':
2559 if not self
._IsToken
("("):
2560 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
2561 PcdPair
= self
._GetNextPcdSettings
()
2562 if not self
._IsToken
(")"):
2563 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
2564 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
2566 FfsFileObj
.NameGuid
= self
._Token
2568 self
._GetFilePart
(FfsFileObj
)
2571 capsuleFfs
= CapsuleFfs()
2572 capsuleFfs
.Ffs
= FfsFileObj
2573 Obj
.CapsuleDataList
.append(capsuleFfs
)
2575 Obj
.FfsList
.append(FfsFileObj
)
2579 ## _FileCouldHaveRelocFlag() method
2581 # Check whether reloc strip flag can be set for a file type.
2583 # @param FileType The file type to check with
2584 # @retval True This type could have relocation strip flag
2585 # @retval False No way to have it
2588 def _FileCouldHaveRelocFlag (FileType
):
2589 if FileType
in {SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
, 'PEI_DXE_COMBO'}:
2594 ## _SectionCouldHaveRelocFlag() method
2596 # Check whether reloc strip flag can be set for a section type.
2598 # @param SectionType The section type to check with
2599 # @retval True This type could have relocation strip flag
2600 # @retval False No way to have it
2603 def _SectionCouldHaveRelocFlag (SectionType
):
2604 if SectionType
in {BINARY_FILE_TYPE_TE
, BINARY_FILE_TYPE_PE32
}:
2609 ## _GetFilePart() method
2611 # Get components for FILE statement
2613 # @param self The object pointer
2614 # @param FfsFileObj for whom component is got
2616 def _GetFilePart(self
, FfsFileObj
):
2617 self
._GetFileOpts
(FfsFileObj
)
2619 if not self
._IsToken
("{"):
2620 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2621 if self
._FileCouldHaveRelocFlag
(FfsFileObj
.FvFileType
):
2622 if self
._Token
== 'RELOCS_STRIPPED':
2623 FfsFileObj
.KeepReloc
= False
2625 FfsFileObj
.KeepReloc
= True
2627 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj
.FvFileType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
2629 if not self
._IsToken
("{"):
2630 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2632 if not self
._GetNextToken
():
2633 raise Warning.Expected("File name or section data", self
.FileName
, self
.CurrentLineNumber
)
2635 if self
._Token
== BINARY_FILE_TYPE_FV
:
2636 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2637 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2638 if not self
._GetNextToken
():
2639 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
2640 FfsFileObj
.FvName
= self
._Token
2642 elif self
._Token
== "FD":
2643 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2644 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2645 if not self
._GetNextToken
():
2646 raise Warning.Expected("FD name", self
.FileName
, self
.CurrentLineNumber
)
2647 FfsFileObj
.FdName
= self
._Token
2649 elif self
._Token
in {TAB_DEFINE
, "APRIORI", "SECTION"}:
2651 self
._GetSectionData
(FfsFileObj
)
2653 elif hasattr(FfsFileObj
, 'FvFileType') and FfsFileObj
.FvFileType
== 'RAW':
2655 self
._GetRAWData
(FfsFileObj
)
2658 FfsFileObj
.CurrentLineNum
= self
.CurrentLineNumber
2659 FfsFileObj
.CurrentLineContent
= self
._CurrentLine
()
2660 FfsFileObj
.FileName
= self
._Token
.replace('$(SPACE)', ' ')
2661 self
._VerifyFile
(FfsFileObj
.FileName
)
2663 if not self
._IsToken
(T_CHAR_BRACE_R
):
2664 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2666 ## _GetRAWData() method
2668 # Get RAW data for FILE statement
2670 # @param self The object pointer
2671 # @param FfsFileObj for whom section is got
2673 def _GetRAWData(self
, FfsFileObj
):
2674 FfsFileObj
.FileName
= []
2675 FfsFileObj
.SubAlignment
= []
2678 if self
._GetAlignment
():
2679 if self
._Token
not in ALIGNMENTS
:
2680 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2681 #For FFS, Auto is default option same to ""
2682 if not self
._Token
== "Auto":
2683 AlignValue
= self
._Token
2684 if not self
._GetNextToken
():
2685 raise Warning.Expected("Filename value", self
.FileName
, self
.CurrentLineNumber
)
2687 FileName
= self
._Token
.replace('$(SPACE)', ' ')
2688 if FileName
== T_CHAR_BRACE_R
:
2690 raise Warning.Expected("Filename value", self
.FileName
, self
.CurrentLineNumber
)
2692 self
._VerifyFile
(FileName
)
2693 File
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
)
2694 FfsFileObj
.FileName
.append(File
.Path
)
2695 FfsFileObj
.SubAlignment
.append(AlignValue
)
2697 if self
._IsToken
(T_CHAR_BRACE_R
):
2701 if len(FfsFileObj
.SubAlignment
) == 1:
2702 FfsFileObj
.SubAlignment
= FfsFileObj
.SubAlignment
[0]
2703 if len(FfsFileObj
.FileName
) == 1:
2704 FfsFileObj
.FileName
= FfsFileObj
.FileName
[0]
2706 ## _GetFileOpts() method
2708 # Get options for FILE statement
2710 # @param self The object pointer
2711 # @param FfsFileObj for whom options is got
2713 def _GetFileOpts(self
, FfsFileObj
):
2714 if self
._GetNextToken
():
2715 if TokenFindPattern
.match(self
._Token
):
2716 FfsFileObj
.KeyStringList
.append(self
._Token
)
2717 if self
._IsToken
(TAB_COMMA_SPLIT
):
2718 while self
._GetNextToken
():
2719 if not TokenFindPattern
.match(self
._Token
):
2720 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2721 FfsFileObj
.KeyStringList
.append(self
._Token
)
2723 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2729 if self
._IsKeyword
("FIXED", True):
2730 FfsFileObj
.Fixed
= True
2732 if self
._IsKeyword
("CHECKSUM", True):
2733 FfsFileObj
.CheckSum
= True
2735 if self
._GetAlignment
():
2736 if self
._Token
not in ALIGNMENTS
:
2737 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2738 #For FFS, Auto is default option same to ""
2739 if not self
._Token
== "Auto":
2740 FfsFileObj
.Alignment
= self
._Token
2742 ## _GetAlignment() method
2744 # Return the alignment value
2746 # @param self The object pointer
2747 # @retval True Successfully find alignment
2748 # @retval False Not able to find alignment
2750 def _GetAlignment(self
):
2751 if self
._IsKeyword
("Align", True):
2752 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2753 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2755 if not self
._GetNextToken
():
2756 raise Warning.Expected("alignment value", self
.FileName
, self
.CurrentLineNumber
)
2761 ## _GetSectionData() method
2763 # Get section data for FILE statement
2765 # @param self The object pointer
2766 # @param FfsFileObj for whom section is got
2768 def _GetSectionData(self
, FfsFileObj
):
2769 self
._GetDefineStatements
(FfsFileObj
)
2772 IsLeafSection
= self
._GetLeafSection
(FfsFileObj
)
2773 IsEncapSection
= self
._GetEncapsulationSec
(FfsFileObj
)
2774 if not IsLeafSection
and not IsEncapSection
:
2777 ## _GetLeafSection() method
2779 # Get leaf section for Obj
2781 # @param self The object pointer
2782 # @param Obj for whom leaf section is got
2783 # @retval True Successfully find section statement
2784 # @retval False Not able to find section statement
2786 def _GetLeafSection(self
, Obj
):
2787 OldPos
= self
.GetFileBufferPos()
2789 if not self
._IsKeyword
("SECTION"):
2790 if len(Obj
.SectionList
) == 0:
2791 raise Warning.Expected("SECTION", self
.FileName
, self
.CurrentLineNumber
)
2796 if self
._GetAlignment
():
2797 if self
._Token
not in ALIGNMENTS
:
2798 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2799 AlignValue
= self
._Token
2802 if self
._IsKeyword
("BUILD_NUM"):
2803 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2804 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2806 if not self
._GetNextToken
():
2807 raise Warning.Expected("Build number value", self
.FileName
, self
.CurrentLineNumber
)
2809 BuildNum
= self
._Token
2811 if self
._IsKeyword
("VERSION"):
2812 if AlignValue
== 'Auto':
2813 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2814 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2815 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2816 if not self
._GetNextToken
():
2817 raise Warning.Expected("version", self
.FileName
, self
.CurrentLineNumber
)
2818 VerSectionObj
= VerSection()
2819 VerSectionObj
.Alignment
= AlignValue
2820 VerSectionObj
.BuildNum
= BuildNum
2821 if self
._GetStringData
():
2822 VerSectionObj
.StringData
= self
._Token
2824 VerSectionObj
.FileName
= self
._Token
2825 Obj
.SectionList
.append(VerSectionObj
)
2827 elif self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2828 if AlignValue
== 'Auto':
2829 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2830 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2831 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2832 if not self
._GetNextToken
():
2833 raise Warning.Expected("UI", self
.FileName
, self
.CurrentLineNumber
)
2834 UiSectionObj
= UiSection()
2835 UiSectionObj
.Alignment
= AlignValue
2836 if self
._GetStringData
():
2837 UiSectionObj
.StringData
= self
._Token
2839 UiSectionObj
.FileName
= self
._Token
2840 Obj
.SectionList
.append(UiSectionObj
)
2842 elif self
._IsKeyword
("FV_IMAGE"):
2843 if AlignValue
== 'Auto':
2844 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2845 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2846 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2847 if not self
._GetNextToken
():
2848 raise Warning.Expected("FV name or FV file path", self
.FileName
, self
.CurrentLineNumber
)
2850 FvName
= self
._Token
2853 if self
._IsToken
("{"):
2855 FvObj
.UiFvName
= FvName
.upper()
2856 self
._GetDefineStatements
(FvObj
)
2858 self
._GetBlockStatement
(FvObj
)
2859 self
._GetSetStatements
(FvObj
)
2860 self
._GetFvAlignment
(FvObj
)
2861 self
._GetFvAttributes
(FvObj
)
2864 IsInf
= self
._GetInfStatement
(FvObj
)
2865 IsFile
= self
._GetFileStatement
(FvObj
)
2866 if not IsInf
and not IsFile
:
2869 if not self
._IsToken
(T_CHAR_BRACE_R
):
2870 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2872 FvImageSectionObj
= FvImageSection()
2873 FvImageSectionObj
.Alignment
= AlignValue
2874 if FvObj
is not None:
2875 FvImageSectionObj
.Fv
= FvObj
2876 FvImageSectionObj
.FvName
= None
2878 FvImageSectionObj
.FvName
= FvName
.upper()
2879 FvImageSectionObj
.FvFileName
= FvName
2881 Obj
.SectionList
.append(FvImageSectionObj
)
2883 elif self
._IsKeyword
("PEI_DEPEX_EXP") or self
._IsKeyword
("DXE_DEPEX_EXP") or self
._IsKeyword
("SMM_DEPEX_EXP"):
2884 if AlignValue
== 'Auto':
2885 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2886 DepexSectionObj
= DepexSection()
2887 DepexSectionObj
.Alignment
= AlignValue
2888 DepexSectionObj
.DepexType
= self
._Token
2890 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2891 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2892 if not self
._IsToken
("{"):
2893 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2894 if not self
._SkipToToken
(T_CHAR_BRACE_R
):
2895 raise Warning.Expected("Depex expression ending '}'", self
.FileName
, self
.CurrentLineNumber
)
2897 DepexSectionObj
.Expression
= self
._SkippedChars
.rstrip(T_CHAR_BRACE_R
)
2898 Obj
.SectionList
.append(DepexSectionObj
)
2901 if not self
._GetNextWord
():
2902 raise Warning.Expected("section type", self
.FileName
, self
.CurrentLineNumber
)
2904 # Encapsulation section appear, UndoToken and return
2905 if self
._Token
== "COMPRESS" or self
._Token
== "GUIDED":
2906 self
.SetFileBufferPos(OldPos
)
2909 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
,\
2910 BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX
}:
2911 raise Warning("Unknown section type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2912 if AlignValue
== 'Auto'and (not self
._Token
== BINARY_FILE_TYPE_PE32
) and (not self
._Token
== BINARY_FILE_TYPE_TE
):
2913 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2916 DataSectionObj
= DataSection()
2917 DataSectionObj
.Alignment
= AlignValue
2918 DataSectionObj
.SecType
= self
._Token
2920 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2921 if self
._FileCouldHaveRelocFlag
(Obj
.FvFileType
) and self
._SectionCouldHaveRelocFlag
(DataSectionObj
.SecType
):
2922 if self
._Token
== 'RELOCS_STRIPPED':
2923 DataSectionObj
.KeepReloc
= False
2925 DataSectionObj
.KeepReloc
= True
2927 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
)
2929 if self
._IsToken
(TAB_EQUAL_SPLIT
):
2930 if not self
._GetNextToken
():
2931 raise Warning.Expected("section file path", self
.FileName
, self
.CurrentLineNumber
)
2932 DataSectionObj
.SectFileName
= self
._Token
2933 self
._VerifyFile
(DataSectionObj
.SectFileName
)
2935 if not self
._GetCglSection
(DataSectionObj
):
2938 Obj
.SectionList
.append(DataSectionObj
)
2944 # Check if file exists or not:
2945 # If current phase if GenFds, the file must exist;
2946 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
2947 # @param FileName: File path to be verified.
2949 def _VerifyFile(self
, FileName
):
2950 if FileName
.replace(TAB_WORKSPACE
, '').find('$') != -1:
2952 if not GlobalData
.gAutoGenPhase
or not self
._GetMacroValue
(TAB_DSC_DEFINES_OUTPUT_DIRECTORY
) in FileName
:
2953 ErrorCode
, ErrorInfo
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2955 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2957 ## _GetCglSection() method
2959 # Get compressed or GUIDed section for Obj
2961 # @param self The object pointer
2962 # @param Obj for whom leaf section is got
2963 # @param AlignValue alignment value for complex section
2964 # @retval True Successfully find section statement
2965 # @retval False Not able to find section statement
2967 def _GetCglSection(self
, Obj
, AlignValue
= None):
2969 if self
._IsKeyword
("COMPRESS"):
2971 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
2974 if not self
._IsToken
("{"):
2975 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2977 CompressSectionObj
= CompressSection()
2978 CompressSectionObj
.Alignment
= AlignValue
2979 CompressSectionObj
.CompType
= type
2980 # Recursive sections...
2982 IsLeafSection
= self
._GetLeafSection
(CompressSectionObj
)
2983 IsEncapSection
= self
._GetEncapsulationSec
(CompressSectionObj
)
2984 if not IsLeafSection
and not IsEncapSection
:
2988 if not self
._IsToken
(T_CHAR_BRACE_R
):
2989 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2990 Obj
.SectionList
.append(CompressSectionObj
)
2993 elif self
._IsKeyword
("GUIDED"):
2995 if self
._GetNextGuid
():
2996 GuidValue
= self
._Token
2998 AttribDict
= self
._GetGuidAttrib
()
2999 if not self
._IsToken
("{"):
3000 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
3001 GuidSectionObj
= GuidSection()
3002 GuidSectionObj
.Alignment
= AlignValue
3003 GuidSectionObj
.NameGuid
= GuidValue
3004 GuidSectionObj
.SectionType
= "GUIDED"
3005 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
3006 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
3007 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
3008 # Recursive sections...
3010 IsLeafSection
= self
._GetLeafSection
(GuidSectionObj
)
3011 IsEncapSection
= self
._GetEncapsulationSec
(GuidSectionObj
)
3012 if not IsLeafSection
and not IsEncapSection
:
3015 if not self
._IsToken
(T_CHAR_BRACE_R
):
3016 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3017 Obj
.SectionList
.append(GuidSectionObj
)
3023 ## _GetGuidAttri() method
3025 # Get attributes for GUID section
3027 # @param self The object pointer
3028 # @retval AttribDict Dictionary of key-value pair of section attributes
3030 def _GetGuidAttrib(self
):
3032 AttribDict
["PROCESSING_REQUIRED"] = "NONE"
3033 AttribDict
["AUTH_STATUS_VALID"] = "NONE"
3034 AttribDict
["EXTRA_HEADER_SIZE"] = -1
3035 while self
._IsKeyword
("PROCESSING_REQUIRED") or self
._IsKeyword
("AUTH_STATUS_VALID") \
3036 or self
._IsKeyword
("EXTRA_HEADER_SIZE"):
3037 AttribKey
= self
._Token
3039 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3040 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3042 if not self
._GetNextToken
():
3043 raise Warning.Expected("TRUE(1)/FALSE(0)/Number", self
.FileName
, self
.CurrentLineNumber
)
3044 elif AttribKey
== "EXTRA_HEADER_SIZE":
3046 if self
._Token
[0:2].upper() == "0X":
3049 AttribDict
[AttribKey
] = int(self
._Token
, Base
)
3052 raise Warning.Expected("Number", self
.FileName
, self
.CurrentLineNumber
)
3053 elif self
._Token
.upper() not in {"TRUE", "FALSE", "1", "0"}:
3054 raise Warning.Expected("TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
3055 AttribDict
[AttribKey
] = self
._Token
3059 ## _GetEncapsulationSec() method
3061 # Get encapsulation section for FILE
3063 # @param self The object pointer
3064 # @param FfsFile for whom section is got
3065 # @retval True Successfully find section statement
3066 # @retval False Not able to find section statement
3068 def _GetEncapsulationSec(self
, FfsFileObj
):
3069 OldPos
= self
.GetFileBufferPos()
3070 if not self
._IsKeyword
("SECTION"):
3071 if len(FfsFileObj
.SectionList
) == 0:
3072 raise Warning.Expected("SECTION", self
.FileName
, self
.CurrentLineNumber
)
3077 if self
._GetAlignment
():
3078 if self
._Token
not in ALIGNMENT_NOAUTO
:
3079 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3080 AlignValue
= self
._Token
3082 if not self
._GetCglSection
(FfsFileObj
, AlignValue
):
3083 self
.SetFileBufferPos(OldPos
)
3089 if not self
._GetNextToken
():
3091 S
= self
._Token
.upper()
3092 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FMPPAYLOAD."):
3093 self
.SectionParser(S
)
3098 self
._SkipToToken
("[FMPPAYLOAD.", True)
3099 FmpUiName
= self
._GetUiName
().upper()
3100 if FmpUiName
in self
.Profile
.FmpPayloadDict
:
3101 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName
, self
.FileName
, self
.CurrentLineNumber
)
3103 FmpData
= CapsulePayload()
3104 FmpData
.UiName
= FmpUiName
3106 if not self
._IsToken
(TAB_SECTION_END
):
3107 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3109 if not self
._GetNextToken
():
3110 raise Warning("The FMP payload section is empty!", self
.FileName
, self
.CurrentLineNumber
)
3111 FmpKeyList
= ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']
3112 while self
._Token
in FmpKeyList
:
3114 FmpKeyList
.remove(Name
)
3115 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3116 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3117 if Name
== 'IMAGE_TYPE_ID':
3118 if not self
._GetNextGuid
():
3119 raise Warning.Expected("GUID value for IMAGE_TYPE_ID.", self
.FileName
, self
.CurrentLineNumber
)
3120 FmpData
.ImageTypeId
= self
._Token
3121 elif Name
== 'CERTIFICATE_GUID':
3122 if not self
._GetNextGuid
():
3123 raise Warning.Expected("GUID value for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3124 FmpData
.Certificate_Guid
= self
._Token
3125 if UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_RSA2048_SHA256_GUID
and UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_PKCS7_GUID
:
3126 raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3128 if not self
._GetNextToken
():
3129 raise Warning.Expected("value of %s" % Name
, self
.FileName
, self
.CurrentLineNumber
)
3131 if Name
== 'IMAGE_HEADER_INIT_VERSION':
3132 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3133 FmpData
.Version
= Value
3134 elif Name
== 'IMAGE_INDEX':
3135 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3136 FmpData
.ImageIndex
= Value
3137 elif Name
== 'HARDWARE_INSTANCE':
3138 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3139 FmpData
.HardwareInstance
= Value
3140 elif Name
== 'MONOTONIC_COUNT':
3141 if FdfParser
._Verify
(Name
, Value
, 'UINT64'):
3142 FmpData
.MonotonicCount
= Value
3143 if FmpData
.MonotonicCount
.upper().startswith('0X'):
3144 FmpData
.MonotonicCount
= (long)(FmpData
.MonotonicCount
, 16)
3146 FmpData
.MonotonicCount
= (long)(FmpData
.MonotonicCount
)
3147 if not self
._GetNextToken
():
3152 if (FmpData
.MonotonicCount
and not FmpData
.Certificate_Guid
) or (not FmpData
.MonotonicCount
and FmpData
.Certificate_Guid
):
3153 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")
3155 # Only the IMAGE_TYPE_ID is required item
3156 if FmpKeyList
and 'IMAGE_TYPE_ID' in FmpKeyList
:
3157 raise Warning("'IMAGE_TYPE_ID' in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3158 # get the Image file and Vendor code file
3159 self
._GetFMPCapsuleData
(FmpData
)
3160 if not FmpData
.ImageFile
:
3161 raise Warning("Missing image file in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3162 # check whether more than one Vendor code file
3163 if len(FmpData
.VendorCodeFile
) > 1:
3164 raise Warning("Vendor code file max of 1 per FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3165 self
.Profile
.FmpPayloadDict
[FmpUiName
] = FmpData
3168 ## _GetCapsule() method
3170 # Get capsule section contents and store its data into capsule list of self.Profile
3172 # @param self The object pointer
3173 # @retval True Successfully find a capsule
3174 # @retval False Not able to find a capsule
3176 def _GetCapsule(self
):
3177 if not self
._GetNextToken
():
3180 S
= self
._Token
.upper()
3181 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[CAPSULE."):
3182 self
.SectionParser(S
)
3187 if not self
._IsToken
("[CAPSULE.", True):
3188 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3189 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3190 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3191 raise Warning.Expected("[Capsule.]", self
.FileName
, self
.CurrentLineNumber
)
3193 CapsuleObj
= Capsule()
3195 CapsuleName
= self
._GetUiName
()
3197 raise Warning.Expected("capsule name", self
.FileName
, self
.CurrentLineNumber
)
3199 CapsuleObj
.UiCapsuleName
= CapsuleName
.upper()
3201 if not self
._IsToken
(TAB_SECTION_END
):
3202 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3204 if self
._IsKeyword
("CREATE_FILE"):
3205 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3206 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3208 if not self
._GetNextToken
():
3209 raise Warning.Expected("file name", self
.FileName
, self
.CurrentLineNumber
)
3211 CapsuleObj
.CreateFile
= self
._Token
3213 self
._GetCapsuleStatements
(CapsuleObj
)
3214 self
.Profile
.CapsuleDict
[CapsuleObj
.UiCapsuleName
] = CapsuleObj
3217 ## _GetCapsuleStatements() method
3219 # Get statements for capsule
3221 # @param self The object pointer
3222 # @param Obj for whom statements are got
3224 def _GetCapsuleStatements(self
, Obj
):
3225 self
._GetCapsuleTokens
(Obj
)
3226 self
._GetDefineStatements
(Obj
)
3227 self
._GetSetStatements
(Obj
)
3228 self
._GetCapsuleData
(Obj
)
3230 ## _GetCapsuleTokens() method
3232 # Get token statements for capsule
3234 # @param self The object pointer
3235 # @param Obj for whom token statements are got
3237 def _GetCapsuleTokens(self
, Obj
):
3238 if not self
._GetNextToken
():
3240 while self
._Token
in {"CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"}:
3241 Name
= self
._Token
.strip()
3242 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3243 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3244 if not self
._GetNextToken
():
3245 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
3246 if Name
== 'CAPSULE_FLAGS':
3247 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3248 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3249 Value
= self
._Token
.strip()
3250 while self
._IsToken
(TAB_COMMA_SPLIT
):
3251 Value
+= TAB_COMMA_SPLIT
3252 if not self
._GetNextToken
():
3253 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
3254 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3255 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3256 Value
+= self
._Token
.strip()
3257 elif Name
== 'OEM_CAPSULE_FLAGS':
3258 Value
= self
._Token
.strip()
3259 if not Value
.upper().startswith('0X'):
3260 raise Warning.Expected("hex value starting with 0x", self
.FileName
, self
.CurrentLineNumber
)
3262 Value
= int(Value
, 0)
3264 raise Warning.Expected("hex string failed to convert to value", self
.FileName
, self
.CurrentLineNumber
)
3265 if not 0x0000 <= Value
<= 0xFFFF:
3266 raise Warning.Expected("hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3267 Value
= self
._Token
.strip()
3269 Value
= self
._Token
.strip()
3270 Obj
.TokensDict
[Name
] = Value
3271 if not self
._GetNextToken
():
3275 ## _GetCapsuleData() method
3277 # Get capsule data for capsule
3279 # @param self The object pointer
3280 # @param Obj for whom capsule data are got
3282 def _GetCapsuleData(self
, Obj
):
3284 IsInf
= self
._GetInfStatement
(Obj
, True)
3285 IsFile
= self
._GetFileStatement
(Obj
, True)
3286 IsFv
= self
._GetFvStatement
(Obj
)
3287 IsFd
= self
._GetFdStatement
(Obj
)
3288 IsAnyFile
= self
._GetAnyFileStatement
(Obj
)
3289 IsAfile
= self
._GetAfileStatement
(Obj
)
3290 IsFmp
= self
._GetFmpStatement
(Obj
)
3291 if not (IsInf
or IsFile
or IsFv
or IsFd
or IsAnyFile
or IsAfile
or IsFmp
):
3294 ## _GetFMPCapsuleData() method
3296 # Get capsule data for FMP capsule
3298 # @param self The object pointer
3299 # @param Obj for whom capsule data are got
3301 def _GetFMPCapsuleData(self
, Obj
):
3303 IsFv
= self
._GetFvStatement
(Obj
, True)
3304 IsFd
= self
._GetFdStatement
(Obj
, True)
3305 IsAnyFile
= self
._GetAnyFileStatement
(Obj
, True)
3306 if not (IsFv
or IsFd
or IsAnyFile
):
3309 ## _GetFvStatement() method
3311 # Get FV for capsule
3313 # @param self The object pointer
3314 # @param CapsuleObj for whom FV is got
3315 # @retval True Successfully find a FV statement
3316 # @retval False Not able to find a FV statement
3318 def _GetFvStatement(self
, CapsuleObj
, FMPCapsule
= False):
3319 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3322 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3323 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3325 if not self
._GetNextToken
():
3326 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
3328 if self
._Token
.upper() not in self
.Profile
.FvDict
:
3329 raise Warning("FV name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3331 myCapsuleFv
= CapsuleFv()
3332 myCapsuleFv
.FvName
= self
._Token
3334 if not CapsuleObj
.ImageFile
:
3335 CapsuleObj
.ImageFile
.append(myCapsuleFv
)
3337 CapsuleObj
.VendorCodeFile
.append(myCapsuleFv
)
3339 CapsuleObj
.CapsuleDataList
.append(myCapsuleFv
)
3342 ## _GetFdStatement() method
3344 # Get FD for capsule
3346 # @param self The object pointer
3347 # @param CapsuleObj for whom FD is got
3348 # @retval True Successfully find a FD statement
3349 # @retval False Not able to find a FD statement
3351 def _GetFdStatement(self
, CapsuleObj
, FMPCapsule
= False):
3352 if not self
._IsKeyword
("FD"):
3355 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3356 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3358 if not self
._GetNextToken
():
3359 raise Warning.Expected("FD name", self
.FileName
, self
.CurrentLineNumber
)
3361 if self
._Token
.upper() not in self
.Profile
.FdDict
:
3362 raise Warning("FD name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3364 myCapsuleFd
= CapsuleFd()
3365 myCapsuleFd
.FdName
= self
._Token
3367 if not CapsuleObj
.ImageFile
:
3368 CapsuleObj
.ImageFile
.append(myCapsuleFd
)
3370 CapsuleObj
.VendorCodeFile
.append(myCapsuleFd
)
3372 CapsuleObj
.CapsuleDataList
.append(myCapsuleFd
)
3375 def _GetFmpStatement(self
, CapsuleObj
):
3376 if not self
._IsKeyword
("FMP_PAYLOAD"):
3377 if not self
._IsKeyword
("FMP"):
3380 if not self
._IsKeyword
("PAYLOAD"):
3384 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3385 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3387 if not self
._GetNextToken
():
3388 raise Warning.Expected("payload name after FMP_PAYLOAD =", self
.FileName
, self
.CurrentLineNumber
)
3389 Payload
= self
._Token
.upper()
3390 if Payload
not in self
.Profile
.FmpPayloadDict
:
3391 raise Warning("This FMP Payload does not exist: %s" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3392 CapsuleObj
.FmpPayloadList
.append(self
.Profile
.FmpPayloadDict
[Payload
])
3395 def _ParseRawFileStatement(self
):
3396 if not self
._IsKeyword
("FILE"):
3399 if not self
._IsKeyword
("DATA"):
3403 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3404 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3406 if not self
._GetNextToken
():
3407 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
3409 AnyFileName
= self
._Token
3410 self
._VerifyFile
(AnyFileName
)
3412 if not os
.path
.isabs(AnyFileName
):
3413 AnyFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, AnyFileName
)
3417 ## _GetAnyFileStatement() method
3419 # Get AnyFile for capsule
3421 # @param self The object pointer
3422 # @param CapsuleObj for whom AnyFile is got
3423 # @retval True Successfully find a Anyfile statement
3424 # @retval False Not able to find a AnyFile statement
3426 def _GetAnyFileStatement(self
, CapsuleObj
, FMPCapsule
= False):
3427 AnyFileName
= self
._ParseRawFileStatement
()
3431 myCapsuleAnyFile
= CapsuleAnyFile()
3432 myCapsuleAnyFile
.FileName
= AnyFileName
3434 if not CapsuleObj
.ImageFile
:
3435 CapsuleObj
.ImageFile
.append(myCapsuleAnyFile
)
3437 CapsuleObj
.VendorCodeFile
.append(myCapsuleAnyFile
)
3439 CapsuleObj
.CapsuleDataList
.append(myCapsuleAnyFile
)
3442 ## _GetAfileStatement() method
3444 # Get Afile for capsule
3446 # @param self The object pointer
3447 # @param CapsuleObj for whom Afile is got
3448 # @retval True Successfully find a Afile statement
3449 # @retval False Not able to find a Afile statement
3451 def _GetAfileStatement(self
, CapsuleObj
):
3452 if not self
._IsKeyword
("APPEND"):
3455 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3456 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3458 if not self
._GetNextToken
():
3459 raise Warning.Expected("Afile name", self
.FileName
, self
.CurrentLineNumber
)
3461 AfileName
= self
._Token
3462 AfileBaseName
= os
.path
.basename(AfileName
)
3464 if os
.path
.splitext(AfileBaseName
)[1] not in {".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"}:
3465 raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \
3466 self
.FileName
, self
.CurrentLineNumber
)
3468 if not os
.path
.isabs(AfileName
):
3469 AfileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(AfileName
)
3470 self
._VerifyFile
(AfileName
)
3472 if not os
.path
.exists(AfileName
):
3473 raise Warning('%s does not exist' % AfileName
, self
.FileName
, self
.CurrentLineNumber
)
3477 myCapsuleAfile
= CapsuleAfile()
3478 myCapsuleAfile
.FileName
= AfileName
3479 CapsuleObj
.CapsuleDataList
.append(myCapsuleAfile
)
3482 ## _GetRule() method
3484 # Get Rule section contents and store its data into rule list of self.Profile
3486 # @param self The object pointer
3487 # @retval True Successfully find a Rule
3488 # @retval False Not able to find a Rule
3491 if not self
._GetNextToken
():
3494 S
= self
._Token
.upper()
3495 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[RULE."):
3496 self
.SectionParser(S
)
3500 if not self
._IsToken
("[Rule.", True):
3501 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3502 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3503 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3504 raise Warning.Expected("[Rule.]", self
.FileName
, self
.CurrentLineNumber
)
3506 if not self
._SkipToToken
(TAB_SPLIT
):
3507 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
3509 Arch
= self
._SkippedChars
.rstrip(TAB_SPLIT
)
3510 if Arch
.upper() not in ARCH_SET_FULL
:
3511 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
3513 ModuleType
= self
._GetModuleType
()
3516 if self
._IsToken
(TAB_SPLIT
):
3517 if not self
._GetNextWord
():
3518 raise Warning.Expected("template name", self
.FileName
, self
.CurrentLineNumber
)
3519 TemplateName
= self
._Token
3521 if not self
._IsToken
(TAB_SECTION_END
):
3522 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3524 RuleObj
= self
._GetRuleFileStatements
()
3525 RuleObj
.Arch
= Arch
.upper()
3526 RuleObj
.ModuleType
= ModuleType
3527 RuleObj
.TemplateName
= TemplateName
3528 if TemplateName
== '':
3529 self
.Profile
.RuleDict
['RULE' + \
3533 ModuleType
.upper() ] = RuleObj
3535 self
.Profile
.RuleDict
['RULE' + \
3539 ModuleType
.upper() + \
3541 TemplateName
.upper() ] = RuleObj
3544 ## _GetModuleType() method
3546 # Return the module type
3548 # @param self The object pointer
3549 # @retval string module type
3551 def _GetModuleType(self
):
3552 if not self
._GetNextWord
():
3553 raise Warning.Expected("Module type", self
.FileName
, self
.CurrentLineNumber
)
3554 if self
._Token
.upper() not in {
3555 SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3556 SUP_MODULE_DXE_CORE
, SUP_MODULE_DXE_DRIVER
,
3557 SUP_MODULE_DXE_SAL_DRIVER
, SUP_MODULE_DXE_SMM_DRIVER
,
3558 SUP_MODULE_DXE_RUNTIME_DRIVER
, SUP_MODULE_UEFI_DRIVER
,
3559 SUP_MODULE_UEFI_APPLICATION
, SUP_MODULE_USER_DEFINED
,
3560 TAB_DEFAULT
, SUP_MODULE_BASE
,
3561 EDK_COMPONENT_TYPE_SECURITY_CORE
,
3562 EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER
,
3563 EDK_COMPONENT_TYPE_PIC_PEIM
,
3564 EDK_COMPONENT_TYPE_RELOCATABLE_PEIM
, "PE32_PEIM",
3565 EDK_COMPONENT_TYPE_BS_DRIVER
, EDK_COMPONENT_TYPE_RT_DRIVER
,
3566 EDK_COMPONENT_TYPE_SAL_RT_DRIVER
,
3567 EDK_COMPONENT_TYPE_APPLICATION
, "ACPITABLE",
3568 SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3569 SUP_MODULE_MM_CORE_STANDALONE
}:
3570 raise Warning("Unknown Module type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3573 ## _GetFileExtension() method
3575 # Return the file extension
3577 # @param self The object pointer
3578 # @retval string file name extension
3580 def _GetFileExtension(self
):
3581 if not self
._IsToken
(TAB_SPLIT
):
3582 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
3585 if self
._GetNextToken
():
3586 if FileExtensionPattern
.match(self
._Token
):
3588 return TAB_SPLIT
+ Ext
3590 raise Warning("Unknown file extension '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3593 raise Warning.Expected("file extension", self
.FileName
, self
.CurrentLineNumber
)
3595 ## _GetRuleFileStatement() method
3599 # @param self The object pointer
3600 # @retval Rule Rule object
3602 def _GetRuleFileStatements(self
):
3603 if not self
._IsKeyword
("FILE"):
3604 raise Warning.Expected("FILE", self
.FileName
, self
.CurrentLineNumber
)
3606 if not self
._GetNextWord
():
3607 raise Warning.Expected("FFS type", self
.FileName
, self
.CurrentLineNumber
)
3609 Type
= self
._Token
.strip().upper()
3610 if Type
not in {"RAW", "FREEFORM", SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3611 "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE
, EDK_COMPONENT_TYPE_APPLICATION
,
3612 "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3613 SUP_MODULE_MM_CORE_STANDALONE
}:
3614 raise Warning("Unknown FV type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3616 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3617 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3619 if not self
._IsKeyword
("$(NAMED_GUID)"):
3620 if not self
._GetNextWord
():
3621 raise Warning.Expected("$(NAMED_GUID)", self
.FileName
, self
.CurrentLineNumber
)
3622 if self
._Token
== 'PCD':
3623 if not self
._IsToken
("("):
3624 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3625 PcdPair
= self
._GetNextPcdSettings
()
3626 if not self
._IsToken
(")"):
3627 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3628 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3630 NameGuid
= self
._Token
3633 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3634 if self
._FileCouldHaveRelocFlag
(Type
):
3635 if self
._Token
== 'RELOCS_STRIPPED':
3640 raise Warning("File type %s could not have reloc strip flag%d" % (Type
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3643 if self
._GetNextToken
():
3644 if TokenFindPattern
.match(self
._Token
):
3645 KeyStringList
.append(self
._Token
)
3646 if self
._IsToken
(TAB_COMMA_SPLIT
):
3647 while self
._GetNextToken
():
3648 if not TokenFindPattern
.match(self
._Token
):
3649 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
3650 KeyStringList
.append(self
._Token
)
3652 if not self
._IsToken
(TAB_COMMA_SPLIT
):
3660 if self
._IsKeyword
("Fixed", True):
3664 if self
._IsKeyword
("CheckSum", True):
3668 if self
._GetAlignment
():
3669 if self
._Token
not in ALIGNMENTS
:
3670 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3671 #For FFS, Auto is default option same to ""
3672 if not self
._Token
== "Auto":
3673 AlignValue
= self
._Token
3675 if self
._IsToken
("{"):
3676 # Complex file rule expected
3677 NewRule
= RuleComplexFile()
3678 NewRule
.FvFileType
= Type
3679 NewRule
.NameGuid
= NameGuid
3680 NewRule
.Alignment
= AlignValue
3681 NewRule
.CheckSum
= CheckSum
3682 NewRule
.Fixed
= Fixed
3683 NewRule
.KeyStringList
= KeyStringList
3684 if KeepReloc
is not None:
3685 NewRule
.KeepReloc
= KeepReloc
3688 IsEncapsulate
= self
._GetRuleEncapsulationSection
(NewRule
)
3689 IsLeaf
= self
._GetEfiSection
(NewRule
)
3690 if not IsEncapsulate
and not IsLeaf
:
3693 if not self
._IsToken
(T_CHAR_BRACE_R
):
3694 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3699 # Simple file rule expected
3700 if not self
._GetNextWord
():
3701 raise Warning.Expected("leaf section type", self
.FileName
, self
.CurrentLineNumber
)
3703 SectionName
= self
._Token
3705 if SectionName
not in {
3706 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3707 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3708 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3709 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3710 BINARY_FILE_TYPE_SMM_DEPEX
}:
3711 raise Warning("Unknown leaf section name '%s'" % SectionName
, self
.FileName
, self
.CurrentLineNumber
)
3714 if self
._IsKeyword
("Fixed", True):
3717 if self
._IsKeyword
("CheckSum", True):
3721 if self
._GetAlignment
():
3722 if self
._Token
not in ALIGNMENTS
:
3723 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3724 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3725 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3726 SectAlignment
= self
._Token
3729 if self
._IsToken
(TAB_VALUE_SPLIT
):
3730 Ext
= self
._GetFileExtension
()
3731 elif not self
._GetNextToken
():
3732 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
3734 NewRule
= RuleSimpleFile()
3735 NewRule
.SectionType
= SectionName
3736 NewRule
.FvFileType
= Type
3737 NewRule
.NameGuid
= NameGuid
3738 NewRule
.Alignment
= AlignValue
3739 NewRule
.SectAlignment
= SectAlignment
3740 NewRule
.CheckSum
= CheckSum
3741 NewRule
.Fixed
= Fixed
3742 NewRule
.KeyStringList
= KeyStringList
3743 if KeepReloc
is not None:
3744 NewRule
.KeepReloc
= KeepReloc
3745 NewRule
.FileExtension
= Ext
3746 NewRule
.FileName
= self
._Token
3749 ## _GetEfiSection() method
3751 # Get section list for Rule
3753 # @param self The object pointer
3754 # @param Obj for whom section is got
3755 # @retval True Successfully find section statement
3756 # @retval False Not able to find section statement
3758 def _GetEfiSection(self
, Obj
):
3759 OldPos
= self
.GetFileBufferPos()
3760 if not self
._GetNextWord
():
3762 SectionName
= self
._Token
3764 if SectionName
not in {
3765 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3766 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3767 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3768 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3769 BINARY_FILE_TYPE_SMM_DEPEX
, BINARY_FILE_TYPE_GUID
}:
3773 if SectionName
== "FV_IMAGE":
3774 FvImageSectionObj
= FvImageSection()
3775 if self
._IsKeyword
("FV_IMAGE"):
3777 if self
._IsToken
("{"):
3779 self
._GetDefineStatements
(FvObj
)
3780 self
._GetBlockStatement
(FvObj
)
3781 self
._GetSetStatements
(FvObj
)
3782 self
._GetFvAlignment
(FvObj
)
3783 self
._GetFvAttributes
(FvObj
)
3784 self
._GetAprioriSection
(FvObj
)
3785 self
._GetAprioriSection
(FvObj
)
3788 IsInf
= self
._GetInfStatement
(FvObj
)
3789 IsFile
= self
._GetFileStatement
(FvObj
)
3790 if not IsInf
and not IsFile
:
3793 if not self
._IsToken
(T_CHAR_BRACE_R
):
3794 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3795 FvImageSectionObj
.Fv
= FvObj
3796 FvImageSectionObj
.FvName
= None
3799 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3800 raise Warning.Expected("'FV'", self
.FileName
, self
.CurrentLineNumber
)
3801 FvImageSectionObj
.FvFileType
= self
._Token
3803 if self
._GetAlignment
():
3804 if self
._Token
not in ALIGNMENT_NOAUTO
:
3805 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3806 FvImageSectionObj
.Alignment
= self
._Token
3808 if self
._IsToken
(TAB_VALUE_SPLIT
):
3809 FvImageSectionObj
.FvFileExtension
= self
._GetFileExtension
()
3810 elif self
._GetNextToken
():
3811 if self
._Token
not in {
3812 T_CHAR_BRACE_R
, "COMPAT16", BINARY_FILE_TYPE_PE32
,
3813 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3814 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3815 BINARY_FILE_TYPE_UI
, "VERSION",
3816 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3817 BINARY_FILE_TYPE_SMM_DEPEX
}:
3818 FvImageSectionObj
.FvFileName
= self
._Token
3822 raise Warning.Expected("FV file name", self
.FileName
, self
.CurrentLineNumber
)
3824 Obj
.SectionList
.append(FvImageSectionObj
)
3827 EfiSectionObj
= EfiSection()
3828 EfiSectionObj
.SectionType
= SectionName
3830 if not self
._GetNextToken
():
3831 raise Warning.Expected("file type", self
.FileName
, self
.CurrentLineNumber
)
3833 if self
._Token
== "STRING":
3834 if not self
._RuleSectionCouldHaveString
(EfiSectionObj
.SectionType
):
3835 raise Warning("%s section could NOT have string data%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
)
3840 if not self
._GetNextToken
():
3841 raise Warning.Expected("Quoted String", self
.FileName
, self
.CurrentLineNumber
)
3843 if self
._GetStringData
():
3844 EfiSectionObj
.StringData
= self
._Token
3846 if self
._IsKeyword
("BUILD_NUM"):
3847 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3848 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3850 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3851 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3852 if not self
._GetNextToken
():
3853 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3854 EfiSectionObj
.BuildNum
= self
._Token
3857 EfiSectionObj
.FileType
= self
._Token
3858 self
._CheckRuleSectionFileType
(EfiSectionObj
.SectionType
, EfiSectionObj
.FileType
)
3860 if self
._IsKeyword
("Optional"):
3861 if not self
._RuleSectionCouldBeOptional
(EfiSectionObj
.SectionType
):
3862 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3863 EfiSectionObj
.Optional
= True
3865 if self
._IsKeyword
("BUILD_NUM"):
3866 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3867 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3869 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3870 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3871 if not self
._GetNextToken
():
3872 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3873 EfiSectionObj
.BuildNum
= self
._Token
3875 if self
._GetAlignment
():
3876 if self
._Token
not in ALIGNMENTS
:
3877 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3878 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3879 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3880 EfiSectionObj
.Alignment
= self
._Token
3882 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3883 if self
._SectionCouldHaveRelocFlag
(EfiSectionObj
.SectionType
):
3884 if self
._Token
== 'RELOCS_STRIPPED':
3885 EfiSectionObj
.KeepReloc
= False
3887 EfiSectionObj
.KeepReloc
= True
3888 if Obj
.KeepReloc
is not None and Obj
.KeepReloc
!= EfiSectionObj
.KeepReloc
:
3889 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3891 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3894 if self
._IsToken
(TAB_VALUE_SPLIT
):
3895 EfiSectionObj
.FileExtension
= self
._GetFileExtension
()
3896 elif self
._GetNextToken
():
3897 if self
._Token
not in {
3898 T_CHAR_BRACE_R
, "COMPAT16", BINARY_FILE_TYPE_PE32
,
3899 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3900 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3901 BINARY_FILE_TYPE_UI
, "VERSION",
3902 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3903 BINARY_FILE_TYPE_SMM_DEPEX
}:
3905 if self
._Token
.startswith('PCD'):
3909 if self
._Token
== 'PCD':
3910 if not self
._IsToken
("("):
3911 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3912 PcdPair
= self
._GetNextPcdSettings
()
3913 if not self
._IsToken
(")"):
3914 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3915 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3917 EfiSectionObj
.FileName
= self
._Token
3922 raise Warning.Expected("section file name", self
.FileName
, self
.CurrentLineNumber
)
3924 Obj
.SectionList
.append(EfiSectionObj
)
3927 ## _RuleSectionCouldBeOptional() method
3929 # Get whether a section could be optional
3931 # @param SectionType The section type to check
3932 # @retval True section could be optional
3933 # @retval False section never optional
3936 def _RuleSectionCouldBeOptional(SectionType
):
3937 if SectionType
in {BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "RAW", BINARY_FILE_TYPE_SMM_DEPEX
}:
3942 ## _RuleSectionCouldHaveBuildNum() method
3944 # Get whether a section could have build number information
3946 # @param SectionType The section type to check
3947 # @retval True section could have build number information
3948 # @retval False section never have build number information
3951 def _RuleSectionCouldHaveBuildNum(SectionType
):
3952 if SectionType
== "VERSION":
3957 ## _RuleSectionCouldHaveString() method
3959 # Get whether a section could have string
3961 # @param SectionType The section type to check
3962 # @retval True section could have string
3963 # @retval False section never have string
3966 def _RuleSectionCouldHaveString(SectionType
):
3967 if SectionType
in {BINARY_FILE_TYPE_UI
, "VERSION"}:
3972 ## _CheckRuleSectionFileType() method
3974 # Get whether a section matches a file type
3976 # @param self The object pointer
3977 # @param SectionType The section type to check
3978 # @param FileType The file type to check
3980 def _CheckRuleSectionFileType(self
, SectionType
, FileType
):
3981 WarningString
= "Incorrect section file type '%s'"
3982 if SectionType
== "COMPAT16":
3983 if FileType
not in {"COMPAT16", "SEC_COMPAT16"}:
3984 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3985 elif SectionType
== BINARY_FILE_TYPE_PE32
:
3986 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_PE32"}:
3987 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3988 elif SectionType
== BINARY_FILE_TYPE_PIC
:
3989 if FileType
not in {BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_PIC
}:
3990 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3991 elif SectionType
== BINARY_FILE_TYPE_TE
:
3992 if FileType
not in {BINARY_FILE_TYPE_TE
, "SEC_TE"}:
3993 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3994 elif SectionType
== "RAW":
3995 if FileType
not in {BINARY_FILE_TYPE_BIN
, "SEC_BIN", "RAW", "ASL", "ACPI"}:
3996 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3997 elif SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
or SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
3998 if FileType
not in {BINARY_FILE_TYPE_DXE_DEPEX
, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX
}:
3999 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4000 elif SectionType
== BINARY_FILE_TYPE_UI
:
4001 if FileType
not in {BINARY_FILE_TYPE_UI
, "SEC_UI"}:
4002 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4003 elif SectionType
== "VERSION":
4004 if FileType
not in {"VERSION", "SEC_VERSION"}:
4005 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4006 elif SectionType
== BINARY_FILE_TYPE_PEI_DEPEX
:
4007 if FileType
not in {BINARY_FILE_TYPE_PEI_DEPEX
, "SEC_PEI_DEPEX"}:
4008 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4009 elif SectionType
== BINARY_FILE_TYPE_GUID
:
4010 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_GUID"}:
4011 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4013 ## _GetRuleEncapsulationSection() method
4015 # Get encapsulation section for Rule
4017 # @param self The object pointer
4018 # @param theRule for whom section is got
4019 # @retval True Successfully find section statement
4020 # @retval False Not able to find section statement
4022 def _GetRuleEncapsulationSection(self
, theRule
):
4023 if self
._IsKeyword
("COMPRESS"):
4025 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
4028 if not self
._IsToken
("{"):
4029 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4031 CompressSectionObj
= CompressSection()
4033 CompressSectionObj
.CompType
= Type
4034 # Recursive sections...
4036 IsEncapsulate
= self
._GetRuleEncapsulationSection
(CompressSectionObj
)
4037 IsLeaf
= self
._GetEfiSection
(CompressSectionObj
)
4038 if not IsEncapsulate
and not IsLeaf
:
4041 if not self
._IsToken
(T_CHAR_BRACE_R
):
4042 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4043 theRule
.SectionList
.append(CompressSectionObj
)
4047 elif self
._IsKeyword
("GUIDED"):
4049 if self
._GetNextGuid
():
4050 GuidValue
= self
._Token
4052 if self
._IsKeyword
("$(NAMED_GUID)"):
4053 GuidValue
= self
._Token
4055 AttribDict
= self
._GetGuidAttrib
()
4057 if not self
._IsToken
("{"):
4058 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4059 GuidSectionObj
= GuidSection()
4060 GuidSectionObj
.NameGuid
= GuidValue
4061 GuidSectionObj
.SectionType
= "GUIDED"
4062 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
4063 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
4064 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
4068 IsEncapsulate
= self
._GetRuleEncapsulationSection
(GuidSectionObj
)
4069 IsLeaf
= self
._GetEfiSection
(GuidSectionObj
)
4070 if not IsEncapsulate
and not IsLeaf
:
4073 if not self
._IsToken
(T_CHAR_BRACE_R
):
4074 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4075 theRule
.SectionList
.append(GuidSectionObj
)
4083 # Get VTF section contents and store its data into VTF list of self.Profile
4085 # @param self The object pointer
4086 # @retval True Successfully find a VTF
4087 # @retval False Not able to find a VTF
4090 HW_ARCH_SET
= {TAB_ARCH_IA32
, TAB_ARCH_X64
, TAB_ARCH_IPF
, TAB_ARCH_ARM
, TAB_ARCH_AARCH64
}
4091 if not self
._GetNextToken
():
4094 S
= self
._Token
.upper()
4095 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[VTF."):
4096 self
.SectionParser(S
)
4101 if not self
._IsToken
("[VTF.", True):
4102 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4103 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
4104 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
4105 raise Warning.Expected("[VTF.]", self
.FileName
, self
.CurrentLineNumber
)
4107 if not self
._SkipToToken
(TAB_SPLIT
):
4108 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
4110 Arch
= self
._SkippedChars
.rstrip(TAB_SPLIT
).upper()
4111 if Arch
not in HW_ARCH_SET
:
4112 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
4114 if not self
._GetNextWord
():
4115 raise Warning.Expected("VTF name", self
.FileName
, self
.CurrentLineNumber
)
4116 Name
= self
._Token
.upper()
4119 VtfObj
.UiName
= Name
4120 VtfObj
.KeyArch
= Arch
4122 if self
._IsToken
(TAB_COMMA_SPLIT
):
4123 if not self
._GetNextWord
():
4124 raise Warning.Expected("Arch list", self
.FileName
, self
.CurrentLineNumber
)
4125 if self
._Token
.upper() not in HW_ARCH_SET
:
4126 raise Warning("Unknown Arch '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4127 VtfObj
.ArchList
= self
._Token
.upper()
4129 if not self
._IsToken
(TAB_SECTION_END
):
4130 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
4132 if self
._IsKeyword
("IA32_RST_BIN"):
4133 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4134 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4136 if not self
._GetNextToken
():
4137 raise Warning.Expected("Reset file", self
.FileName
, self
.CurrentLineNumber
)
4139 VtfObj
.ResetBin
= self
._Token
4140 if VtfObj
.ResetBin
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4141 #check for file path
4142 ErrorCode
, ErrorInfo
= PathClass(NormPath(VtfObj
.ResetBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4144 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4146 while self
._GetComponentStatement
(VtfObj
):
4149 self
.Profile
.VtfList
.append(VtfObj
)
4152 ## _GetComponentStatement() method
4154 # Get components in VTF
4156 # @param self The object pointer
4157 # @param VtfObj for whom component is got
4158 # @retval True Successfully find a component
4159 # @retval False Not able to find a component
4161 def _GetComponentStatement(self
, VtfObj
):
4162 if not self
._IsKeyword
("COMP_NAME"):
4165 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4166 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4168 if not self
._GetNextWord
():
4169 raise Warning.Expected("Component Name", self
.FileName
, self
.CurrentLineNumber
)
4171 CompStatementObj
= ComponentStatement()
4172 CompStatementObj
.CompName
= self
._Token
4174 if not self
._IsKeyword
("COMP_LOC"):
4175 raise Warning.Expected("COMP_LOC", self
.FileName
, self
.CurrentLineNumber
)
4177 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4178 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4180 CompStatementObj
.CompLoc
= ""
4181 if self
._GetNextWord
():
4182 CompStatementObj
.CompLoc
= self
._Token
4183 if self
._IsToken
(TAB_VALUE_SPLIT
):
4184 if not self
._GetNextWord
():
4185 raise Warning.Expected("Region Name", self
.FileName
, self
.CurrentLineNumber
)
4187 if self
._Token
not in {"F", "N", "S"}: #, "H", "L", "PH", "PL"): not support
4188 raise Warning("Unknown location type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4190 CompStatementObj
.FilePos
= self
._Token
4192 self
.CurrentLineNumber
+= 1
4193 self
.CurrentOffsetWithinLine
= 0
4195 if not self
._IsKeyword
("COMP_TYPE"):
4196 raise Warning.Expected("COMP_TYPE", self
.FileName
, self
.CurrentLineNumber
)
4198 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4199 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4201 if not self
._GetNextToken
():
4202 raise Warning.Expected("Component type", self
.FileName
, self
.CurrentLineNumber
)
4203 if self
._Token
not in {"FIT", "PAL_B", "PAL_A", "OEM"}:
4204 if not self
._Token
.startswith("0x") or len(self
._Token
) < 3 or len(self
._Token
) > 4 or \
4205 not self
._Token
[2] in hexdigits
or not self
._Token
[-1] in hexdigits
:
4206 raise Warning("Unknown location type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4207 CompStatementObj
.CompType
= self
._Token
4209 if not self
._IsKeyword
("COMP_VER"):
4210 raise Warning.Expected("COMP_VER", self
.FileName
, self
.CurrentLineNumber
)
4212 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4213 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4215 if not self
._GetNextToken
():
4216 raise Warning.Expected("Component version", self
.FileName
, self
.CurrentLineNumber
)
4218 Pattern
= compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', DOTALL
)
4219 if Pattern
.match(self
._Token
) is None:
4220 raise Warning("Unknown version format '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4221 CompStatementObj
.CompVer
= self
._Token
4223 if not self
._IsKeyword
("COMP_CS"):
4224 raise Warning.Expected("COMP_CS", self
.FileName
, self
.CurrentLineNumber
)
4226 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4227 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4229 if not self
._GetNextToken
():
4230 raise Warning.Expected("Component CS", self
.FileName
, self
.CurrentLineNumber
)
4231 if self
._Token
not in {"1", "0"}:
4232 raise Warning("Unknown Component CS '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4233 CompStatementObj
.CompCs
= self
._Token
4236 if not self
._IsKeyword
("COMP_BIN"):
4237 raise Warning.Expected("COMP_BIN", self
.FileName
, self
.CurrentLineNumber
)
4239 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4240 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4242 if not self
._GetNextToken
():
4243 raise Warning.Expected("Component file", self
.FileName
, self
.CurrentLineNumber
)
4245 CompStatementObj
.CompBin
= self
._Token
4246 if CompStatementObj
.CompBin
!= '-' and CompStatementObj
.CompBin
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4247 #check for file path
4248 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4250 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4252 if not self
._IsKeyword
("COMP_SYM"):
4253 raise Warning.Expected("COMP_SYM", self
.FileName
, self
.CurrentLineNumber
)
4255 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4256 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4258 if not self
._GetNextToken
():
4259 raise Warning.Expected("Component symbol file", self
.FileName
, self
.CurrentLineNumber
)
4261 CompStatementObj
.CompSym
= self
._Token
4262 if CompStatementObj
.CompSym
!= '-' and CompStatementObj
.CompSym
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4263 #check for file path
4264 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompSym
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4266 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4268 if not self
._IsKeyword
("COMP_SIZE"):
4269 raise Warning.Expected("COMP_SIZE", self
.FileName
, self
.CurrentLineNumber
)
4271 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4272 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4274 if self
._IsToken
("-"):
4275 CompStatementObj
.CompSize
= self
._Token
4276 elif self
._GetNextDecimalNumber
():
4277 CompStatementObj
.CompSize
= self
._Token
4278 elif self
._GetNextHexNumber
():
4279 CompStatementObj
.CompSize
= self
._Token
4281 raise Warning("Unknown size '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4283 VtfObj
.ComponentStatementList
.append(CompStatementObj
)
4286 ## _GetOptionRom() method
4288 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
4290 # @param self The object pointer
4291 # @retval True Successfully find a OptionROM
4292 # @retval False Not able to find a OptionROM
4294 def _GetOptionRom(self
):
4295 if not self
._GetNextToken
():
4298 S
= self
._Token
.upper()
4299 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[OPTIONROM."):
4300 self
.SectionParser(S
)
4305 if not self
._IsToken
("[OptionRom.", True):
4306 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4308 OptRomName
= self
._GetUiName
()
4310 if not self
._IsToken
(TAB_SECTION_END
):
4311 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
4313 OptRomObj
= OPTIONROM(OptRomName
)
4314 self
.Profile
.OptRomDict
[OptRomName
] = OptRomObj
4317 isInf
= self
._GetOptRomInfStatement
(OptRomObj
)
4318 isFile
= self
._GetOptRomFileStatement
(OptRomObj
)
4319 if not isInf
and not isFile
:
4324 ## _GetOptRomInfStatement() method
4326 # Get INF statements
4328 # @param self The object pointer
4329 # @param Obj for whom inf statement is got
4330 # @retval True Successfully find inf statement
4331 # @retval False Not able to find inf statement
4333 def _GetOptRomInfStatement(self
, Obj
):
4334 if not self
._IsKeyword
("INF"):
4337 ffsInf
= OptRomInfStatement()
4338 self
._GetInfOptions
(ffsInf
)
4340 if not self
._GetNextToken
():
4341 raise Warning.Expected("INF file path", self
.FileName
, self
.CurrentLineNumber
)
4342 ffsInf
.InfFileName
= self
._Token
4343 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4344 #check for file path
4345 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4347 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4349 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
4350 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
4351 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4352 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
4354 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
4355 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
4357 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
4359 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
4362 self
._GetOptRomOverrides
(ffsInf
)
4364 Obj
.FfsList
.append(ffsInf
)
4367 ## _GetOptRomOverrides() method
4369 # Get overrides for OptROM INF & FILE
4371 # @param self The object pointer
4372 # @param FfsInfObj for whom overrides is got
4374 def _GetOptRomOverrides(self
, Obj
):
4375 if self
._IsToken
('{'):
4376 Overrides
= OverrideAttribs()
4378 if self
._IsKeyword
("PCI_VENDOR_ID"):
4379 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4380 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4381 if not self
._GetNextHexNumber
():
4382 raise Warning.Expected("Hex vendor id", self
.FileName
, self
.CurrentLineNumber
)
4383 Overrides
.PciVendorId
= self
._Token
4386 if self
._IsKeyword
("PCI_CLASS_CODE"):
4387 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4388 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4389 if not self
._GetNextHexNumber
():
4390 raise Warning.Expected("Hex class code", self
.FileName
, self
.CurrentLineNumber
)
4391 Overrides
.PciClassCode
= self
._Token
4394 if self
._IsKeyword
("PCI_DEVICE_ID"):
4395 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4396 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4397 # Get a list of PCI IDs
4398 Overrides
.PciDeviceId
= ""
4399 while (self
.__GetNextHexNumber
()):
4400 Overrides
.PciDeviceId
= "{} {}".format(Overrides
.PciDeviceId
, self
.__Token
)
4401 if not Overrides
.PciDeviceId
:
4402 raise Warning.Expected("one or more Hex device ids", self
.FileName
, self
.CurrentLineNumber
)
4405 if self
._IsKeyword
("PCI_REVISION"):
4406 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4407 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4408 if not self
._GetNextHexNumber
():
4409 raise Warning.Expected("Hex revision", self
.FileName
, self
.CurrentLineNumber
)
4410 Overrides
.PciRevision
= self
._Token
4413 if self
._IsKeyword
("PCI_COMPRESS"):
4414 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4415 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4416 if not self
._GetNextToken
():
4417 raise Warning.Expected("TRUE/FALSE for compress", self
.FileName
, self
.CurrentLineNumber
)
4418 Overrides
.NeedCompress
= self
._Token
.upper() == 'TRUE'
4421 if self
._IsToken
(T_CHAR_BRACE_R
):
4424 EdkLogger
.error("FdfParser", FORMAT_INVALID
, File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
4426 Obj
.OverrideAttribs
= Overrides
4428 ## _GetOptRomFileStatement() method
4430 # Get FILE statements
4432 # @param self The object pointer
4433 # @param Obj for whom FILE statement is got
4434 # @retval True Successfully find FILE statement
4435 # @retval False Not able to find FILE statement
4437 def _GetOptRomFileStatement(self
, Obj
):
4438 if not self
._IsKeyword
("FILE"):
4441 FfsFileObj
= OptRomFileStatement()
4443 if not self
._IsKeyword
("EFI") and not self
._IsKeyword
(BINARY_FILE_TYPE_BIN
):
4444 raise Warning.Expected("Binary type (EFI/BIN)", self
.FileName
, self
.CurrentLineNumber
)
4445 FfsFileObj
.FileType
= self
._Token
4447 if not self
._GetNextToken
():
4448 raise Warning.Expected("File path", self
.FileName
, self
.CurrentLineNumber
)
4449 FfsFileObj
.FileName
= self
._Token
4450 if FfsFileObj
.FileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4451 #check for file path
4452 ErrorCode
, ErrorInfo
= PathClass(NormPath(FfsFileObj
.FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4454 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4456 if FfsFileObj
.FileType
== 'EFI':
4457 self
._GetOptRomOverrides
(FfsFileObj
)
4459 Obj
.FfsList
.append(FfsFileObj
)
4463 ## _GetCapInFd() method
4465 # Get Cap list contained in FD
4467 # @param self The object pointer
4468 # @param FdName FD name
4469 # @retval CapList List of Capsule in FD
4471 def _GetCapInFd (self
, FdName
):
4473 if FdName
.upper() in self
.Profile
.FdDict
:
4474 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4475 for elementRegion
in FdObj
.RegionList
:
4476 if elementRegion
.RegionType
== 'CAPSULE':
4477 for elementRegionData
in elementRegion
.RegionDataList
:
4478 if elementRegionData
.endswith(".cap"):
4480 if elementRegionData
is not None and elementRegionData
.upper() not in CapList
:
4481 CapList
.append(elementRegionData
.upper())
4484 ## _GetReferencedFdCapTuple() method
4486 # Get FV and FD list referenced by a capsule image
4488 # @param self The object pointer
4489 # @param CapObj Capsule section to be searched
4490 # @param RefFdList referenced FD by section
4491 # @param RefFvList referenced FV by section
4493 def _GetReferencedFdCapTuple(self
, CapObj
, RefFdList
= [], RefFvList
= []):
4494 for CapsuleDataObj
in CapObj
.CapsuleDataList
:
4495 if hasattr(CapsuleDataObj
, 'FvName') and CapsuleDataObj
.FvName
is not None and CapsuleDataObj
.FvName
.upper() not in RefFvList
:
4496 RefFvList
.append (CapsuleDataObj
.FvName
.upper())
4497 elif hasattr(CapsuleDataObj
, 'FdName') and CapsuleDataObj
.FdName
is not None and CapsuleDataObj
.FdName
.upper() not in RefFdList
:
4498 RefFdList
.append (CapsuleDataObj
.FdName
.upper())
4499 elif CapsuleDataObj
.Ffs
is not None:
4500 if isinstance(CapsuleDataObj
.Ffs
, FileStatement
):
4501 if CapsuleDataObj
.Ffs
.FvName
is not None and CapsuleDataObj
.Ffs
.FvName
.upper() not in RefFvList
:
4502 RefFvList
.append(CapsuleDataObj
.Ffs
.FvName
.upper())
4503 elif CapsuleDataObj
.Ffs
.FdName
is not None and CapsuleDataObj
.Ffs
.FdName
.upper() not in RefFdList
:
4504 RefFdList
.append(CapsuleDataObj
.Ffs
.FdName
.upper())
4506 self
._GetReferencedFdFvTupleFromSection
(CapsuleDataObj
.Ffs
, RefFdList
, RefFvList
)
4508 ## _GetFvInFd() method
4510 # Get FV list contained in FD
4512 # @param self The object pointer
4513 # @param FdName FD name
4514 # @retval FvList list of FV in FD
4516 def _GetFvInFd (self
, FdName
):
4518 if FdName
.upper() in self
.Profile
.FdDict
:
4519 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4520 for elementRegion
in FdObj
.RegionList
:
4521 if elementRegion
.RegionType
== BINARY_FILE_TYPE_FV
:
4522 for elementRegionData
in elementRegion
.RegionDataList
:
4523 if elementRegionData
.endswith(".fv"):
4525 if elementRegionData
is not None and elementRegionData
.upper() not in FvList
:
4526 FvList
.append(elementRegionData
.upper())
4529 ## _GetReferencedFdFvTuple() method
4531 # Get FD and FV list referenced by a FFS file
4533 # @param self The object pointer
4534 # @param FfsFile contains sections to be searched
4535 # @param RefFdList referenced FD by section
4536 # @param RefFvList referenced FV by section
4538 def _GetReferencedFdFvTuple(self
, FvObj
, RefFdList
= [], RefFvList
= []):
4539 for FfsObj
in FvObj
.FfsList
:
4540 if isinstance(FfsObj
, FileStatement
):
4541 if FfsObj
.FvName
is not None and FfsObj
.FvName
.upper() not in RefFvList
:
4542 RefFvList
.append(FfsObj
.FvName
.upper())
4543 elif FfsObj
.FdName
is not None and FfsObj
.FdName
.upper() not in RefFdList
:
4544 RefFdList
.append(FfsObj
.FdName
.upper())
4546 self
._GetReferencedFdFvTupleFromSection
(FfsObj
, RefFdList
, RefFvList
)
4548 ## _GetReferencedFdFvTupleFromSection() method
4550 # Get FD and FV list referenced by a FFS section
4552 # @param self The object pointer
4553 # @param FfsFile contains sections to be searched
4554 # @param FdList referenced FD by section
4555 # @param FvList referenced FV by section
4557 def _GetReferencedFdFvTupleFromSection(self
, FfsFile
, FdList
= [], FvList
= []):
4558 SectionStack
= list(FfsFile
.SectionList
)
4559 while SectionStack
!= []:
4560 SectionObj
= SectionStack
.pop()
4561 if isinstance(SectionObj
, FvImageSection
):
4562 if SectionObj
.FvName
is not None and SectionObj
.FvName
.upper() not in FvList
:
4563 FvList
.append(SectionObj
.FvName
.upper())
4564 if SectionObj
.Fv
is not None and SectionObj
.Fv
.UiFvName
is not None and SectionObj
.Fv
.UiFvName
.upper() not in FvList
:
4565 FvList
.append(SectionObj
.Fv
.UiFvName
.upper())
4566 self
._GetReferencedFdFvTuple
(SectionObj
.Fv
, FdList
, FvList
)
4568 if isinstance(SectionObj
, CompressSection
) or isinstance(SectionObj
, GuidSection
):
4569 SectionStack
.extend(SectionObj
.SectionList
)
4571 ## CycleReferenceCheck() method
4573 # Check whether cycle reference exists in FDF
4575 # @param self The object pointer
4576 # @retval True cycle reference exists
4577 # @retval False Not exists cycle reference
4579 def CycleReferenceCheck(self
):
4581 # Check the cycle between FV and FD image
4583 MaxLength
= len (self
.Profile
.FvDict
)
4584 for FvName
in self
.Profile
.FvDict
:
4585 LogStr
= "\nCycle Reference Checking for FV: %s\n" % FvName
4586 RefFvStack
= set(FvName
)
4587 FdAnalyzedList
= set()
4590 while RefFvStack
and Index
< MaxLength
:
4592 FvNameFromStack
= RefFvStack
.pop()
4593 if FvNameFromStack
.upper() in self
.Profile
.FvDict
:
4594 FvObj
= self
.Profile
.FvDict
[FvNameFromStack
.upper()]
4600 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4602 for RefFdName
in RefFdList
:
4603 if RefFdName
in FdAnalyzedList
:
4606 LogStr
+= "FV %s contains FD %s\n" % (FvNameFromStack
, RefFdName
)
4607 FvInFdList
= self
._GetFvInFd
(RefFdName
)
4608 if FvInFdList
!= []:
4609 for FvNameInFd
in FvInFdList
:
4610 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4611 if FvNameInFd
not in RefFvStack
:
4612 RefFvStack
.add(FvNameInFd
)
4614 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4615 EdkLogger
.info(LogStr
)
4617 FdAnalyzedList
.add(RefFdName
)
4619 for RefFvName
in RefFvList
:
4620 LogStr
+= "FV %s contains FV %s\n" % (FvNameFromStack
, RefFvName
)
4621 if RefFvName
not in RefFvStack
:
4622 RefFvStack
.add(RefFvName
)
4624 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4625 EdkLogger
.info(LogStr
)
4629 # Check the cycle between Capsule and FD image
4631 MaxLength
= len (self
.Profile
.CapsuleDict
)
4632 for CapName
in self
.Profile
.CapsuleDict
:
4634 # Capsule image to be checked.
4636 LogStr
= "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4637 RefCapStack
= {CapName}
4638 FdAnalyzedList
= set()
4639 FvAnalyzedList
= set()
4642 while RefCapStack
and Index
< MaxLength
:
4644 CapNameFromStack
= RefCapStack
.pop()
4645 if CapNameFromStack
.upper() in self
.Profile
.CapsuleDict
:
4646 CapObj
= self
.Profile
.CapsuleDict
[CapNameFromStack
.upper()]
4652 self
._GetReferencedFdCapTuple
(CapObj
, RefFdList
, RefFvList
)
4656 while FvListLength
< len (RefFvList
) or FdListLength
< len (RefFdList
):
4657 for RefFdName
in RefFdList
:
4658 if RefFdName
in FdAnalyzedList
:
4661 LogStr
+= "Capsule %s contains FD %s\n" % (CapNameFromStack
, RefFdName
)
4662 for CapNameInFd
in self
._GetCapInFd
(RefFdName
):
4663 LogStr
+= "FD %s contains Capsule %s\n" % (RefFdName
, CapNameInFd
)
4664 if CapNameInFd
not in RefCapStack
:
4665 RefCapStack
.append(CapNameInFd
)
4667 if CapName
in RefCapStack
or CapNameFromStack
in RefCapStack
:
4668 EdkLogger
.info(LogStr
)
4671 for FvNameInFd
in self
._GetFvInFd
(RefFdName
):
4672 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4673 if FvNameInFd
not in RefFvList
:
4674 RefFvList
.append(FvNameInFd
)
4676 FdAnalyzedList
.add(RefFdName
)
4678 # the number of the parsed FV and FD image
4680 FvListLength
= len (RefFvList
)
4681 FdListLength
= len (RefFdList
)
4682 for RefFvName
in RefFvList
:
4683 if RefFvName
in FvAnalyzedList
:
4685 LogStr
+= "Capsule %s contains FV %s\n" % (CapNameFromStack
, RefFvName
)
4686 if RefFvName
.upper() in self
.Profile
.FvDict
:
4687 FvObj
= self
.Profile
.FvDict
[RefFvName
.upper()]
4690 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4691 FvAnalyzedList
.add(RefFvName
)
4695 def GetAllIncludedFile (self
):
4696 global AllIncludeFileList
4697 return AllIncludeFileList
4699 if __name__
== "__main__":
4702 test_file
= sys
.argv
[1]
4703 except IndexError as v
:
4704 print("Usage: %s filename" % sys
.argv
[0])
4707 parser
= FdfParser(test_file
)
4710 parser
.CycleReferenceCheck()
4711 except Warning as X
: