4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 # Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
7 # This program and the accompanying materials
8 # are licensed and made available under the terms and conditions of the BSD License
9 # which accompanies this distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 from __future__
import print_function
20 from __future__
import absolute_import
21 from re
import compile, DOTALL
22 from string
import hexdigits
25 from Common
.BuildToolError
import *
26 from Common
import EdkLogger
27 from Common
.Misc
import PathClass
, tdict
28 from Common
.StringUtils
import NormPath
, ReplaceMacro
29 from Common
import GlobalData
30 from Common
.Expression
import *
31 from Common
.DataType
import *
32 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
33 import Common
.LongFilePathOs
as os
34 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
35 from Common
.RangeExpression
import RangeExpression
36 from collections
import OrderedDict
39 from .Region
import Region
41 from .AprioriSection
import AprioriSection
42 from .FfsInfStatement
import FfsInfStatement
43 from .FfsFileStatement
import FileStatement
44 from .VerSection
import VerSection
45 from .UiSection
import UiSection
46 from .FvImageSection
import FvImageSection
47 from .DataSection
import DataSection
48 from .DepexSection
import DepexSection
49 from .CompressSection
import CompressSection
50 from .GuidSection
import GuidSection
51 from .Capsule
import EFI_CERT_TYPE_PKCS7_GUID
, EFI_CERT_TYPE_RSA2048_SHA256_GUID
, Capsule
52 from .CapsuleData
import CapsuleFfs
, CapsulePayload
, CapsuleFv
, CapsuleFd
, CapsuleAnyFile
, CapsuleAfile
53 from .RuleComplexFile
import RuleComplexFile
54 from .RuleSimpleFile
import RuleSimpleFile
55 from .EfiSection
import EfiSection
57 from .ComponentStatement
import ComponentStatement
58 from .OptionRom
import OPTIONROM
59 from .OptRomInfStatement
import OptRomInfStatement
, OverrideAttribs
60 from .OptRomFileStatement
import OptRomFileStatement
61 from .GenFdsGlobalVariable
import GenFdsGlobalVariable
65 T_CHAR_DOUBLE_QUOTE
= '\"'
66 T_CHAR_SINGLE_QUOTE
= '\''
69 SEPARATORS
= {TAB_EQUAL_SPLIT
, TAB_VALUE_SPLIT
, TAB_COMMA_SPLIT
, '{', '}'}
70 ALIGNMENTS
= {"Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K", "64K", "128K",
71 "256K", "512K", "1M", "2M", "4M", "8M", "16M"}
72 ALIGNMENT_NOAUTO
= ALIGNMENTS
- {"Auto"}
73 CR_LB_SET
= {T_CHAR_CR
, TAB_LINE_BREAK
}
75 RegionSizePattern
= compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
76 RegionSizeGuidPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*")
77 RegionOffsetPcdPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$")
78 ShortcutPcdPattern
= compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
79 BaseAddrValuePattern
= compile('^0[xX][0-9a-fA-F]+')
80 FileExtensionPattern
= compile(r
'([a-zA-Z][a-zA-Z0-9]*)')
81 TokenFindPattern
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
82 AllIncludeFileList
= []
84 # Get the closest parent
85 def GetParentAtLine (Line
):
86 for Profile
in AllIncludeFileList
:
87 if Profile
.IsLineInFile(Line
):
92 def IsValidInclude (File
, Line
):
93 for Profile
in AllIncludeFileList
:
94 if Profile
.IsLineInFile(Line
) and Profile
.FileName
== File
:
99 def GetRealFileLine (File
, Line
):
101 for Profile
in AllIncludeFileList
:
102 if Profile
.IsLineInFile(Line
):
103 return Profile
.GetLineInFile(Line
)
104 elif Line
>= Profile
.InsertStartLineNumber
and Profile
.Level
== 1:
105 InsertedLines
+= Profile
.GetTotalLines()
107 return (File
, Line
- InsertedLines
)
109 ## The exception class that used to report error messages when parsing FDF
111 # Currently the "ToolName" is set to be "FdfParser".
113 class Warning (Exception):
116 # @param self The object pointer
117 # @param Str The message to record
118 # @param File The FDF name
119 # @param Line The Line number that error occurs
121 def __init__(self
, Str
, File
= None, Line
= None):
122 FileLineTuple
= GetRealFileLine(File
, Line
)
123 self
.FileName
= FileLineTuple
[0]
124 self
.LineNumber
= FileLineTuple
[1]
125 self
.OriginalLineNumber
= Line
127 self
.ToolName
= 'FdfParser'
132 # helper functions to facilitate consistency in warnings
133 # each function is for a different common warning
135 def Expected(Str
, File
, Line
):
136 return Warning("expected {}".format(Str
), File
, Line
)
138 def ExpectedEquals(File
, Line
):
139 return Warning.Expected("'='", File
, Line
)
141 def ExpectedCurlyOpen(File
, Line
):
142 return Warning.Expected("'{'", File
, Line
)
144 def ExpectedCurlyClose(File
, Line
):
145 return Warning.Expected("'}'", File
, Line
)
147 def ExpectedBracketClose(File
, Line
):
148 return Warning.Expected("']'", File
, Line
)
150 ## The Include file content class that used to record file data when parsing include file
152 # May raise Exception when opening file.
154 class IncludeFileProfile
:
157 # @param self The object pointer
158 # @param FileName The file that to be parsed
160 def __init__(self
, FileName
):
161 self
.FileName
= FileName
162 self
.FileLinesList
= []
164 with
open(FileName
, "rb", 0) as fsock
:
165 self
.FileLinesList
= fsock
.readlines()
166 for index
, line
in enumerate(self
.FileLinesList
):
167 if not line
.endswith(TAB_LINE_BREAK
):
168 self
.FileLinesList
[index
] += TAB_LINE_BREAK
170 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
172 self
.InsertStartLineNumber
= None
173 self
.InsertAdjust
= 0
174 self
.IncludeFileList
= []
175 self
.Level
= 1 # first level include file
177 def GetTotalLines(self
):
178 TotalLines
= self
.InsertAdjust
+ len(self
.FileLinesList
)
180 for Profile
in self
.IncludeFileList
:
181 TotalLines
+= Profile
.GetTotalLines()
185 def IsLineInFile(self
, Line
):
186 if Line
>= self
.InsertStartLineNumber
and Line
< self
.InsertStartLineNumber
+ self
.GetTotalLines():
191 def GetLineInFile(self
, Line
):
192 if not self
.IsLineInFile (Line
):
193 return (self
.FileName
, -1)
195 InsertedLines
= self
.InsertStartLineNumber
197 for Profile
in self
.IncludeFileList
:
198 if Profile
.IsLineInFile(Line
):
199 return Profile
.GetLineInFile(Line
)
200 elif Line
>= Profile
.InsertStartLineNumber
:
201 InsertedLines
+= Profile
.GetTotalLines()
203 return (self
.FileName
, Line
- InsertedLines
+ 1)
205 ## The FDF content class that used to record file data when parsing FDF
207 # May raise Exception when opening file.
212 # @param self The object pointer
213 # @param FileName The file that to be parsed
215 def __init__(self
, FileName
):
216 self
.FileLinesList
= []
218 with
open(FileName
, "rb", 0) as fsock
:
219 self
.FileLinesList
= fsock
.readlines()
222 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
224 self
.FileName
= FileName
225 self
.PcdDict
= OrderedDict()
226 self
.PcdLocalDict
= OrderedDict()
228 self
.InfDict
= {'ArchTBD':[]}
229 # ECC will use this Dict and List information
230 self
.PcdFileLineDict
= {}
231 self
.InfFileLineList
= []
234 self
.FdNameNotSet
= False
236 self
.CapsuleDict
= {}
240 self
.FmpPayloadDict
= {}
242 ## The syntax parser for FDF
244 # PreprocessFile method should be called prior to ParseFile
245 # CycleReferenceCheck method can detect cycles in FDF contents
247 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
248 # Get*** procedures mean these procedures will make judgement on current token only.
253 # @param self The object pointer
254 # @param FileName The file that to be parsed
256 def __init__(self
, FileName
):
257 self
.Profile
= FileProfile(FileName
)
258 self
.FileName
= FileName
259 self
.CurrentLineNumber
= 1
260 self
.CurrentOffsetWithinLine
= 0
261 self
.CurrentFdName
= None
262 self
.CurrentFvName
= None
264 self
._SkippedChars
= ""
265 GlobalData
.gFdfParser
= self
267 # Used to section info
268 self
._CurSection
= []
269 # Key: [section name, UI name, arch]
270 # Value: {MACRO_NAME: MACRO_VALUE}
271 self
._MacroDict
= tdict(True, 3)
272 self
._PcdDict
= OrderedDict()
274 self
._WipeOffArea
= []
275 if GenFdsGlobalVariable
.WorkSpaceDir
== '':
276 GenFdsGlobalVariable
.WorkSpaceDir
= os
.getenv("WORKSPACE")
278 ## _SkipWhiteSpace() method
280 # Skip white spaces from current char.
282 # @param self The object pointer
284 def _SkipWhiteSpace(self
):
285 while not self
._EndOfFile
():
286 if self
._CurrentChar
() in {TAB_PRINTCHAR_NUL
, T_CHAR_CR
, TAB_LINE_BREAK
, TAB_SPACE_SPLIT
, T_CHAR_TAB
}:
287 self
._SkippedChars
+= str(self
._CurrentChar
())
293 ## _EndOfFile() method
295 # Judge current buffer pos is at file end
297 # @param self The object pointer
298 # @retval True Current File buffer position is at file end
299 # @retval False Current File buffer position is NOT at file end
301 def _EndOfFile(self
):
302 NumberOfLines
= len(self
.Profile
.FileLinesList
)
303 SizeOfLastLine
= len(self
.Profile
.FileLinesList
[-1])
304 if self
.CurrentLineNumber
== NumberOfLines
and self
.CurrentOffsetWithinLine
>= SizeOfLastLine
- 1:
306 if self
.CurrentLineNumber
> NumberOfLines
:
310 ## _EndOfLine() method
312 # Judge current buffer pos is at line end
314 # @param self The object pointer
315 # @retval True Current File buffer position is at line end
316 # @retval False Current File buffer position is NOT at line end
318 def _EndOfLine(self
):
319 if self
.CurrentLineNumber
> len(self
.Profile
.FileLinesList
):
321 SizeOfCurrentLine
= len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
322 if self
.CurrentOffsetWithinLine
>= SizeOfCurrentLine
:
328 # Reset file data buffer to the initial state
330 # @param self The object pointer
331 # @param DestLine Optional new destination line number.
332 # @param DestOffset Optional new destination offset.
334 def Rewind(self
, DestLine
= 1, DestOffset
= 0):
335 self
.CurrentLineNumber
= DestLine
336 self
.CurrentOffsetWithinLine
= DestOffset
338 ## _UndoOneChar() method
340 # Go back one char in the file buffer
342 # @param self The object pointer
343 # @retval True Successfully go back one char
344 # @retval False Not able to go back one char as file beginning reached
346 def _UndoOneChar(self
):
347 if self
.CurrentLineNumber
== 1 and self
.CurrentOffsetWithinLine
== 0:
349 elif self
.CurrentOffsetWithinLine
== 0:
350 self
.CurrentLineNumber
-= 1
351 self
.CurrentOffsetWithinLine
= len(self
._CurrentLine
()) - 1
353 self
.CurrentOffsetWithinLine
-= 1
356 ## _GetOneChar() method
358 # Move forward one char in the file buffer
360 # @param self The object pointer
362 def _GetOneChar(self
):
363 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
364 self
.CurrentLineNumber
+= 1
365 self
.CurrentOffsetWithinLine
= 0
367 self
.CurrentOffsetWithinLine
+= 1
369 ## _CurrentChar() method
371 # Get the char pointed to by the file buffer pointer
373 # @param self The object pointer
374 # @retval Char Current char
376 def _CurrentChar(self
):
377 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
]
379 ## _NextChar() method
381 # Get the one char pass the char pointed to by the file buffer pointer
383 # @param self The object pointer
384 # @retval Char Next char
387 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
388 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
][0]
389 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
+ 1]
391 ## _SetCurrentCharValue() method
393 # Modify the value of current char
395 # @param self The object pointer
396 # @param Value The new value of current char
398 def _SetCurrentCharValue(self
, Value
):
399 self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
] = Value
401 ## _CurrentLine() method
403 # Get the list that contains current line contents
405 # @param self The object pointer
406 # @retval List current line contents
408 def _CurrentLine(self
):
409 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
411 def _StringToList(self
):
412 self
.Profile
.FileLinesList
= [list(s
) for s
in self
.Profile
.FileLinesList
]
413 if not self
.Profile
.FileLinesList
:
414 EdkLogger
.error('FdfParser', FILE_READ_FAILURE
, 'The file is empty!', File
=self
.FileName
)
415 self
.Profile
.FileLinesList
[-1].append(' ')
417 def _ReplaceFragment(self
, StartPos
, EndPos
, Value
= ' '):
418 if StartPos
[0] == EndPos
[0]:
420 while Offset
<= EndPos
[1]:
421 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
426 while self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] not in CR_LB_SET
:
427 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
431 while Line
< EndPos
[0]:
433 while self
.Profile
.FileLinesList
[Line
][Offset
] not in CR_LB_SET
:
434 self
.Profile
.FileLinesList
[Line
][Offset
] = Value
439 while Offset
<= EndPos
[1]:
440 self
.Profile
.FileLinesList
[EndPos
[0]][Offset
] = Value
443 def _SetMacroValue(self
, Macro
, Value
):
444 if not self
._CurSection
:
448 if not self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]:
449 self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]] = MacroDict
451 MacroDict
= self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]
452 MacroDict
[Macro
] = Value
454 def _GetMacroValue(self
, Macro
):
456 if Macro
in GlobalData
.gCommandLineDefines
:
457 return GlobalData
.gCommandLineDefines
[Macro
]
458 if Macro
in GlobalData
.gGlobalDefines
:
459 return GlobalData
.gGlobalDefines
[Macro
]
462 MacroDict
= self
._MacroDict
[
467 if MacroDict
and Macro
in MacroDict
:
468 return MacroDict
[Macro
]
471 if Macro
in GlobalData
.gPlatformDefines
:
472 return GlobalData
.gPlatformDefines
[Macro
]
475 def _SectionHeaderParser(self
, Section
):
477 # [FD.UiName]: use dummy instead if UI name is optional
480 # [Rule]: don't take rule section into account, macro is not allowed in this section
481 # [VTF.arch.UiName, arch]
482 # [OptionRom.DriverName]
483 self
._CurSection
= []
484 Section
= Section
.strip()[1:-1].upper().replace(' ', '').strip(TAB_SPLIT
)
485 ItemList
= Section
.split(TAB_SPLIT
)
487 if Item
== '' or Item
== 'RULE':
490 if Item
== TAB_COMMON_DEFINES
.upper():
491 self
._CurSection
= [TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
492 elif Item
== 'VTF' and len(ItemList
) == 3:
494 Pos
= UiName
.find(TAB_COMMA_SPLIT
)
496 UiName
= UiName
[:Pos
]
497 self
._CurSection
= ['VTF', UiName
, ItemList
[1]]
498 elif len(ItemList
) > 1:
499 self
._CurSection
= [ItemList
[0], ItemList
[1], TAB_COMMON
]
500 elif len(ItemList
) > 0:
501 self
._CurSection
= [ItemList
[0], 'DUMMY', TAB_COMMON
]
503 ## PreprocessFile() method
505 # Preprocess file contents, replace comments with spaces.
506 # In the end, rewind the file buffer pointer to the beginning
507 # BUGBUG: No !include statement processing contained in this procedure
508 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
510 # @param self The object pointer
512 def PreprocessFile(self
):
515 DoubleSlashComment
= False
517 # HashComment in quoted string " " is ignored.
520 while not self
._EndOfFile
():
522 if self
._CurrentChar
() == T_CHAR_DOUBLE_QUOTE
and not InComment
:
523 InString
= not InString
524 # meet new line, then no longer in a comment for // and '#'
525 if self
._CurrentChar
() == TAB_LINE_BREAK
:
526 self
.CurrentLineNumber
+= 1
527 self
.CurrentOffsetWithinLine
= 0
528 if InComment
and DoubleSlashComment
:
530 DoubleSlashComment
= False
531 if InComment
and HashComment
:
534 # check for */ comment end
535 elif InComment
and not DoubleSlashComment
and not HashComment
and self
._CurrentChar
() == T_CHAR_STAR
and self
._NextChar
() == TAB_BACK_SLASH
:
536 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
538 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
541 # set comments to spaces
543 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
545 # check for // comment
546 elif self
._CurrentChar
() == TAB_BACK_SLASH
and self
._NextChar
() == TAB_BACK_SLASH
and not self
._EndOfLine
():
548 DoubleSlashComment
= True
549 # check for '#' comment
550 elif self
._CurrentChar
() == TAB_COMMENT_SPLIT
and not self
._EndOfLine
() and not InString
:
553 # check for /* comment start
554 elif self
._CurrentChar
() == TAB_BACK_SLASH
and self
._NextChar
() == T_CHAR_STAR
:
555 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
557 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
563 # restore from ListOfList to ListOfString
564 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
567 ## PreprocessIncludeFile() method
569 # Preprocess file contents, replace !include statements with file contents.
570 # In the end, rewind the file buffer pointer to the beginning
572 # @param self The object pointer
574 def PreprocessIncludeFile(self
):
575 # nested include support
578 while self
._GetNextToken
():
580 if self
._Token
== TAB_DEFINE
:
581 if not self
._GetNextToken
():
582 raise Warning.Expected("Macro name", self
.FileName
, self
.CurrentLineNumber
)
584 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
585 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
586 Value
= self
._GetExpression
()
587 MacroDict
[Macro
] = Value
589 elif self
._Token
== TAB_INCLUDE
:
591 IncludeLine
= self
.CurrentLineNumber
592 IncludeOffset
= self
.CurrentOffsetWithinLine
- len(TAB_INCLUDE
)
593 if not self
._GetNextToken
():
594 raise Warning.Expected("include file name", self
.FileName
, self
.CurrentLineNumber
)
595 IncFileName
= self
._Token
597 StartPos
= IncFileName
.find('$(', PreIndex
)
598 EndPos
= IncFileName
.find(')', StartPos
+2)
599 while StartPos
!= -1 and EndPos
!= -1:
600 Macro
= IncFileName
[StartPos
+2: EndPos
]
601 MacroVal
= self
._GetMacroValue
(Macro
)
603 if Macro
in MacroDict
:
604 MacroVal
= MacroDict
[Macro
]
605 if MacroVal
is not None:
606 IncFileName
= IncFileName
.replace('$(' + Macro
+ ')', MacroVal
, 1)
607 if MacroVal
.find('$(') != -1:
610 PreIndex
= StartPos
+ len(MacroVal
)
612 raise Warning("The Macro %s is not defined" %Macro
, self
.FileName
, self
.CurrentLineNumber
)
613 StartPos
= IncFileName
.find('$(', PreIndex
)
614 EndPos
= IncFileName
.find(')', StartPos
+2)
616 IncludedFile
= NormPath(IncFileName
)
618 # First search the include file under the same directory as FDF file
620 IncludedFile1
= PathClass(IncludedFile
, os
.path
.dirname(self
.FileName
))
621 ErrorCode
= IncludedFile1
.Validate()[0]
624 # Then search the include file under the same directory as DSC file
627 if GenFdsGlobalVariable
.ActivePlatform
:
628 PlatformDir
= GenFdsGlobalVariable
.ActivePlatform
.Dir
629 elif GlobalData
.gActivePlatform
:
630 PlatformDir
= GlobalData
.gActivePlatform
.MetaFile
.Dir
631 IncludedFile1
= PathClass(IncludedFile
, PlatformDir
)
632 ErrorCode
= IncludedFile1
.Validate()[0]
635 # Also search file under the WORKSPACE directory
637 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
638 ErrorCode
= IncludedFile1
.Validate()[0]
640 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
),
641 self
.FileName
, self
.CurrentLineNumber
)
643 if not IsValidInclude (IncludedFile1
.Path
, self
.CurrentLineNumber
):
644 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1
.Path
), self
.FileName
, self
.CurrentLineNumber
)
646 IncFileProfile
= IncludeFileProfile(IncludedFile1
.Path
)
648 CurrentLine
= self
.CurrentLineNumber
649 CurrentOffset
= self
.CurrentOffsetWithinLine
650 # list index of the insertion, note that line number is 'CurrentLine + 1'
651 InsertAtLine
= CurrentLine
652 ParentProfile
= GetParentAtLine (CurrentLine
)
653 if ParentProfile
is not None:
654 ParentProfile
.IncludeFileList
.insert(0, IncFileProfile
)
655 IncFileProfile
.Level
= ParentProfile
.Level
+ 1
656 IncFileProfile
.InsertStartLineNumber
= InsertAtLine
+ 1
657 # deal with remaining portions after "!include filename", if exists.
658 if self
._GetNextToken
():
659 if self
.CurrentLineNumber
== CurrentLine
:
660 RemainingLine
= self
._CurrentLine
()[CurrentOffset
:]
661 self
.Profile
.FileLinesList
.insert(self
.CurrentLineNumber
, RemainingLine
)
662 IncFileProfile
.InsertAdjust
+= 1
663 self
.CurrentLineNumber
+= 1
664 self
.CurrentOffsetWithinLine
= 0
666 for Line
in IncFileProfile
.FileLinesList
:
667 self
.Profile
.FileLinesList
.insert(InsertAtLine
, Line
)
668 self
.CurrentLineNumber
+= 1
671 # reversely sorted to better determine error in file
672 AllIncludeFileList
.insert(0, IncFileProfile
)
674 # comment out the processed include file statement
675 TempList
= list(self
.Profile
.FileLinesList
[IncludeLine
- 1])
676 TempList
.insert(IncludeOffset
, TAB_COMMENT_SPLIT
)
677 self
.Profile
.FileLinesList
[IncludeLine
- 1] = ''.join(TempList
)
678 if Processed
: # Nested and back-to-back support
679 self
.Rewind(DestLine
= IncFileProfile
.InsertStartLineNumber
- 1)
685 def _GetIfListCurrentItemStat(IfList
):
695 ## PreprocessConditionalStatement() method
697 # Preprocess conditional statement.
698 # In the end, rewind the file buffer pointer to the beginning
700 # @param self The object pointer
702 def PreprocessConditionalStatement(self
):
703 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
707 while self
._GetNextToken
():
708 # Determine section name and the location dependent macro
709 if self
._GetIfListCurrentItemStat
(IfList
):
710 if self
._Token
.startswith(TAB_SECTION_START
):
712 if not self
._Token
.endswith(TAB_SECTION_END
):
713 self
._SkipToToken
(TAB_SECTION_END
)
714 Header
+= self
._SkippedChars
715 if Header
.find('$(') != -1:
716 raise Warning("macro cannot be used in section header", self
.FileName
, self
.CurrentLineNumber
)
717 self
._SectionHeaderParser
(Header
)
719 # Replace macros except in RULE section or out of section
720 elif self
._CurSection
and ReplacedLine
!= self
.CurrentLineNumber
:
721 ReplacedLine
= self
.CurrentLineNumber
723 CurLine
= self
.Profile
.FileLinesList
[ReplacedLine
- 1]
725 StartPos
= CurLine
.find('$(', PreIndex
)
726 EndPos
= CurLine
.find(')', StartPos
+2)
727 while StartPos
!= -1 and EndPos
!= -1 and self
._Token
not in {TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_IF
, TAB_ELSE_IF
}:
728 MacroName
= CurLine
[StartPos
+2: EndPos
]
729 MacorValue
= self
._GetMacroValue
(MacroName
)
730 if MacorValue
is not None:
731 CurLine
= CurLine
.replace('$(' + MacroName
+ ')', MacorValue
, 1)
732 if MacorValue
.find('$(') != -1:
735 PreIndex
= StartPos
+ len(MacorValue
)
737 PreIndex
= EndPos
+ 1
738 StartPos
= CurLine
.find('$(', PreIndex
)
739 EndPos
= CurLine
.find(')', StartPos
+2)
740 self
.Profile
.FileLinesList
[ReplacedLine
- 1] = CurLine
743 if self
._Token
== TAB_DEFINE
:
744 if self
._GetIfListCurrentItemStat
(IfList
):
745 if not self
._CurSection
:
746 raise Warning("macro cannot be defined in Rule section or out of section", self
.FileName
, self
.CurrentLineNumber
)
747 DefineLine
= self
.CurrentLineNumber
- 1
748 DefineOffset
= self
.CurrentOffsetWithinLine
- len(TAB_DEFINE
)
749 if not self
._GetNextToken
():
750 raise Warning.Expected("Macro name", self
.FileName
, self
.CurrentLineNumber
)
752 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
753 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
755 Value
= self
._GetExpression
()
756 self
._SetMacroValue
(Macro
, Value
)
757 self
._WipeOffArea
.append(((DefineLine
, DefineOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
758 elif self
._Token
== 'SET':
759 if not self
._GetIfListCurrentItemStat
(IfList
):
761 SetLine
= self
.CurrentLineNumber
- 1
762 SetOffset
= self
.CurrentOffsetWithinLine
- len('SET')
763 PcdPair
= self
._GetNextPcdSettings
()
764 PcdName
= "%s.%s" % (PcdPair
[1], PcdPair
[0])
765 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
766 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
768 Value
= self
._GetExpression
()
769 Value
= self
._EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
771 self
._PcdDict
[PcdName
] = Value
773 self
.Profile
.PcdDict
[PcdPair
] = Value
774 self
.SetPcdLocalation(PcdPair
)
775 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
776 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
778 self
._WipeOffArea
.append(((SetLine
, SetOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
779 elif self
._Token
in {TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_IF
}:
780 IfStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
._Token
))
781 IfList
.append([IfStartPos
, None, None])
783 CondLabel
= self
._Token
784 Expression
= self
._GetExpression
()
786 if CondLabel
== TAB_IF
:
787 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
789 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'in')
790 if CondLabel
== TAB_IF_N_DEF
:
791 ConditionSatisfied
= not ConditionSatisfied
793 BranchDetermined
= ConditionSatisfied
794 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, BranchDetermined
]
795 if ConditionSatisfied
:
796 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
797 elif self
._Token
in {TAB_ELSE_IF
, TAB_ELSE
}:
798 ElseStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
._Token
))
800 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
803 IfList
[-1] = [ElseStartPos
, False, True]
804 self
._WipeOffArea
.append((ElseStartPos
, (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
806 self
._WipeOffArea
.append((IfList
[-1][0], ElseStartPos
))
807 IfList
[-1] = [ElseStartPos
, True, IfList
[-1][2]]
808 if self
._Token
== TAB_ELSE_IF
:
809 Expression
= self
._GetExpression
()
810 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
811 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, IfList
[-1][2]]
815 IfList
[-1][1] = False
818 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
819 elif self
._Token
== '!endif':
821 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
823 self
._WipeOffArea
.append(((self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len('!endif')), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
825 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
828 elif not IfList
: # Don't use PCDs inside conditional directive
829 if self
.CurrentLineNumber
<= RegionLayoutLine
:
830 # Don't try the same line twice
832 SetPcd
= ShortcutPcdPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
834 self
._PcdDict
[SetPcd
.group('name')] = SetPcd
.group('value')
835 RegionLayoutLine
= self
.CurrentLineNumber
837 RegionSize
= RegionSizePattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
839 RegionLayoutLine
= self
.CurrentLineNumber
841 RegionSizeGuid
= RegionSizeGuidPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
])
842 if not RegionSizeGuid
:
843 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
845 self
._PcdDict
[RegionSizeGuid
.group('base')] = RegionSize
.group('base')
846 self
._PcdDict
[RegionSizeGuid
.group('size')] = RegionSize
.group('size')
847 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
850 raise Warning("Missing !endif", self
.FileName
, self
.CurrentLineNumber
)
853 def _CollectMacroPcd(self
):
857 MacroDict
.update(GlobalData
.gPlatformPcds
)
858 MacroDict
.update(self
._PcdDict
)
861 MacroDict
.update(GlobalData
.gPlatformDefines
)
865 ScopeMacro
= self
._MacroDict
[TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
867 MacroDict
.update(ScopeMacro
)
870 ScopeMacro
= self
._MacroDict
[
876 MacroDict
.update(ScopeMacro
)
878 MacroDict
.update(GlobalData
.gGlobalDefines
)
879 MacroDict
.update(GlobalData
.gCommandLineDefines
)
880 for Item
in GlobalData
.BuildOptionPcd
:
881 if isinstance(Item
, tuple):
883 PcdName
, TmpValue
= Item
.split(TAB_EQUAL_SPLIT
)
884 TmpValue
= BuildOptionValue(TmpValue
, {})
885 MacroDict
[PcdName
.strip()] = TmpValue
890 def _EvaluateConditional(self
, Expression
, Line
, Op
= None, Value
= None):
891 MacroPcdDict
= self
._CollectMacroPcd
()
895 return ValueExpression(Expression
, MacroPcdDict
)(True)
897 return ValueExpression(Expression
, MacroPcdDict
)()
898 except WrnExpression
as Excpt
:
900 # Catch expression evaluation warning here. We need to report
901 # the precise number of line and return the evaluation result
903 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
904 File
=self
.FileName
, ExtraData
=self
._CurrentLine
(),
907 except Exception as Excpt
:
908 if hasattr(Excpt
, 'Pcd'):
909 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
910 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
911 raise Warning("Cannot use this PCD (%s) in an expression as"
912 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
913 " of the DSC file (%s), and it is currently defined in this section:"
914 " %s, line #: %d." % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE'], Info
[0], Info
[1]),
917 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE']),
920 raise Warning(str(Excpt
), self
.FileName
, Line
)
922 if Expression
.startswith('$(') and Expression
[-1] == ')':
923 Expression
= Expression
[2:-1]
924 return Expression
in MacroPcdDict
928 # Check whether input string is found from current char position along
929 # If found, the string value is put into self._Token
931 # @param self The object pointer
932 # @param String The string to search
933 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
934 # @retval True Successfully find string, file buffer pointer moved forward
935 # @retval False Not able to find string, file buffer pointer not changed
937 def _IsToken(self
, String
, IgnoreCase
= False):
938 self
._SkipWhiteSpace
()
940 # Only consider the same line, no multi-line token allowed
941 StartPos
= self
.CurrentOffsetWithinLine
944 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
946 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
948 self
.CurrentOffsetWithinLine
+= len(String
)
949 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
953 ## _IsKeyword() method
955 # Check whether input keyword is found from current char position along, whole word only!
956 # If found, the string value is put into self._Token
958 # @param self The object pointer
959 # @param Keyword The string to search
960 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
961 # @retval True Successfully find string, file buffer pointer moved forward
962 # @retval False Not able to find string, file buffer pointer not changed
964 def _IsKeyword(self
, KeyWord
, IgnoreCase
= False):
965 self
._SkipWhiteSpace
()
967 # Only consider the same line, no multi-line token allowed
968 StartPos
= self
.CurrentOffsetWithinLine
971 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(KeyWord
.upper())
973 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(KeyWord
)
975 followingChar
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
+ len(KeyWord
)]
976 if not str(followingChar
).isspace() and followingChar
not in SEPARATORS
:
978 self
.CurrentOffsetWithinLine
+= len(KeyWord
)
979 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
983 def _GetExpression(self
):
984 Line
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
985 Index
= len(Line
) - 1
986 while Line
[Index
] in CR_LB_SET
:
988 ExpressionString
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:Index
+1]
989 self
.CurrentOffsetWithinLine
+= len(ExpressionString
)
990 ExpressionString
= ExpressionString
.strip()
991 return ExpressionString
993 ## _GetNextWord() method
995 # Get next C name from file lines
996 # If found, the string value is put into self._Token
998 # @param self The object pointer
999 # @retval True Successfully find a C name string, file buffer pointer moved forward
1000 # @retval False Not able to find a C name string, file buffer pointer not changed
1002 def _GetNextWord(self
):
1003 self
._SkipWhiteSpace
()
1004 if self
._EndOfFile
():
1007 TempChar
= self
._CurrentChar
()
1008 StartPos
= self
.CurrentOffsetWithinLine
1009 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_':
1011 while not self
._EndOfLine
():
1012 TempChar
= self
._CurrentChar
()
1013 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1014 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-':
1020 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1025 def _GetNextPcdWord(self
):
1026 self
._SkipWhiteSpace
()
1027 if self
._EndOfFile
():
1030 TempChar
= self
._CurrentChar
()
1031 StartPos
= self
.CurrentOffsetWithinLine
1032 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_' or TempChar
== TAB_SECTION_START
or TempChar
== TAB_SECTION_END
:
1034 while not self
._EndOfLine
():
1035 TempChar
= self
._CurrentChar
()
1036 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1037 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-' or TempChar
== TAB_SECTION_START
or TempChar
== TAB_SECTION_END
:
1043 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1048 ## _GetNextToken() method
1050 # Get next token unit before a seperator
1051 # If found, the string value is put into self._Token
1053 # @param self The object pointer
1054 # @retval True Successfully find a token unit, file buffer pointer moved forward
1055 # @retval False Not able to find a token unit, file buffer pointer not changed
1057 def _GetNextToken(self
):
1058 # Skip leading spaces, if exist.
1059 self
._SkipWhiteSpace
()
1060 if self
._EndOfFile
():
1062 # Record the token start position, the position of the first non-space char.
1063 StartPos
= self
.CurrentOffsetWithinLine
1064 StartLine
= self
.CurrentLineNumber
1065 while StartLine
== self
.CurrentLineNumber
:
1066 TempChar
= self
._CurrentChar
()
1067 # Try to find the end char that is not a space and not in seperator tuple.
1068 # That is, when we got a space or any char in the tuple, we got the end of token.
1069 if not str(TempChar
).isspace() and TempChar
not in SEPARATORS
:
1071 # if we happen to meet a seperator as the first char, we must proceed to get it.
1072 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1073 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPARATORS
:
1081 EndPos
= self
.CurrentOffsetWithinLine
1082 if self
.CurrentLineNumber
!= StartLine
:
1083 EndPos
= len(self
.Profile
.FileLinesList
[StartLine
-1])
1084 self
._Token
= self
.Profile
.FileLinesList
[StartLine
-1][StartPos
: EndPos
]
1085 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
}:
1086 self
._Token
= self
._Token
.lower()
1087 if StartPos
!= self
.CurrentOffsetWithinLine
:
1092 ## _GetNextGuid() method
1094 # Get next token unit before a seperator
1095 # If found, the GUID string is put into self._Token
1097 # @param self The object pointer
1098 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
1099 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
1101 def _GetNextGuid(self
):
1102 if not self
._GetNextToken
():
1104 if gGuidPattern
.match(self
._Token
) is not None:
1111 def _Verify(Name
, Value
, Scope
):
1112 # value verification only applies to numeric values.
1113 if Scope
not in TAB_PCD_NUMERIC_TYPES
:
1118 ValueNumber
= int(Value
, 0)
1120 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value is not valid dec or hex number for %s." % Name
)
1122 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value can't be set to negative value for %s." % Name
)
1123 if ValueNumber
> MAX_VAL_TYPE
[Scope
]:
1124 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "Too large value for %s." % Name
)
1127 ## _UndoToken() method
1129 # Go back one token unit in file buffer
1131 # @param self The object pointer
1133 def _UndoToken(self
):
1135 while self
._CurrentChar
().isspace():
1136 if not self
._UndoOneChar
():
1141 StartPos
= self
.CurrentOffsetWithinLine
1142 CurrentLine
= self
.CurrentLineNumber
1143 while CurrentLine
== self
.CurrentLineNumber
:
1145 TempChar
= self
._CurrentChar
()
1146 # Try to find the end char that is not a space and not in seperator tuple.
1147 # That is, when we got a space or any char in the tuple, we got the end of token.
1148 if not str(TempChar
).isspace() and not TempChar
in SEPARATORS
:
1149 if not self
._UndoOneChar
():
1151 # if we happen to meet a seperator as the first char, we must proceed to get it.
1152 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1153 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPARATORS
:
1160 ## _GetNextHexNumber() method
1162 # Get next HEX data before a seperator
1163 # If found, the HEX data is put into self._Token
1165 # @param self The object pointer
1166 # @retval True Successfully find a HEX data, file buffer pointer moved forward
1167 # @retval False Not able to find a HEX data, file buffer pointer not changed
1169 def _GetNextHexNumber(self
):
1170 if not self
._GetNextToken
():
1172 if gHexPatternAll
.match(self
._Token
):
1178 ## _GetNextDecimalNumber() method
1180 # Get next decimal data before a seperator
1181 # If found, the decimal data is put into self._Token
1183 # @param self The object pointer
1184 # @retval True Successfully find a decimal data, file buffer pointer moved forward
1185 # @retval False Not able to find a decimal data, file buffer pointer not changed
1187 def _GetNextDecimalNumber(self
):
1188 if not self
._GetNextToken
():
1190 if self
._Token
.isdigit():
1196 def _GetNextPcdSettings(self
):
1197 if not self
._GetNextWord
():
1198 raise Warning.Expected("<PcdTokenSpaceCName>", self
.FileName
, self
.CurrentLineNumber
)
1199 pcdTokenSpaceCName
= self
._Token
1201 if not self
._IsToken
(TAB_SPLIT
):
1202 raise Warning.Expected(".", self
.FileName
, self
.CurrentLineNumber
)
1204 if not self
._GetNextWord
():
1205 raise Warning.Expected("<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1206 pcdCName
= self
._Token
1209 while self
._IsToken
(TAB_SPLIT
):
1210 if not self
._GetNextPcdWord
():
1211 raise Warning.Expected("Pcd Fields", self
.FileName
, self
.CurrentLineNumber
)
1212 Fields
.append(self
._Token
)
1214 return (pcdCName
, pcdTokenSpaceCName
,TAB_SPLIT
.join(Fields
))
1216 ## _GetStringData() method
1218 # Get string contents quoted in ""
1219 # If found, the decimal data is put into self._Token
1221 # @param self The object pointer
1222 # @retval True Successfully find a string data, file buffer pointer moved forward
1223 # @retval False Not able to find a string data, file buffer pointer not changed
1225 def _GetStringData(self
):
1227 if self
._Token
.startswith(T_CHAR_DOUBLE_QUOTE
) or self
._Token
.startswith("L\""):
1228 QuoteToUse
= T_CHAR_DOUBLE_QUOTE
1229 elif self
._Token
.startswith(T_CHAR_SINGLE_QUOTE
) or self
._Token
.startswith("L\'"):
1230 QuoteToUse
= T_CHAR_SINGLE_QUOTE
1235 self
._SkipToToken
(QuoteToUse
)
1236 currentLineNumber
= self
.CurrentLineNumber
1238 if not self
._SkipToToken
(QuoteToUse
):
1239 raise Warning(QuoteToUse
, self
.FileName
, self
.CurrentLineNumber
)
1240 if currentLineNumber
!= self
.CurrentLineNumber
:
1241 raise Warning(QuoteToUse
, self
.FileName
, self
.CurrentLineNumber
)
1242 self
._Token
= self
._SkippedChars
.rstrip(QuoteToUse
)
1245 ## _SkipToToken() method
1247 # Search forward in file buffer for the string
1248 # The skipped chars are put into self._SkippedChars
1250 # @param self The object pointer
1251 # @param String The string to search
1252 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1253 # @retval True Successfully find the string, file buffer pointer moved forward
1254 # @retval False Not able to find the string, file buffer pointer not changed
1256 def _SkipToToken(self
, String
, IgnoreCase
= False):
1257 StartPos
= self
.GetFileBufferPos()
1259 self
._SkippedChars
= ""
1260 while not self
._EndOfFile
():
1263 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
1265 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
1267 self
.CurrentOffsetWithinLine
+= len(String
)
1268 self
._SkippedChars
+= String
1270 self
._SkippedChars
+= str(self
._CurrentChar
())
1273 self
.SetFileBufferPos(StartPos
)
1274 self
._SkippedChars
= ""
1277 ## GetFileBufferPos() method
1279 # Return the tuple of current line and offset within the line
1281 # @param self The object pointer
1282 # @retval Tuple Line number and offset pair
1284 def GetFileBufferPos(self
):
1285 return (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
)
1287 ## SetFileBufferPos() method
1289 # Restore the file buffer position
1291 # @param self The object pointer
1292 # @param Pos The new file buffer position
1294 def SetFileBufferPos(self
, Pos
):
1295 (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
) = Pos
1297 ## Preprocess() method
1299 # Preprocess comment, conditional directive, include directive, replace macro.
1300 # Exception will be raised if syntax error found
1302 # @param self The object pointer
1304 def Preprocess(self
):
1305 self
._StringToList
()
1306 self
.PreprocessFile()
1307 self
.PreprocessIncludeFile()
1308 self
._StringToList
()
1309 self
.PreprocessFile()
1310 self
.PreprocessConditionalStatement()
1311 self
._StringToList
()
1312 for Pos
in self
._WipeOffArea
:
1313 self
._ReplaceFragment
(Pos
[0], Pos
[1])
1314 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
1316 while self
._GetDefines
():
1319 ## ParseFile() method
1321 # Parse the file profile buffer to extract fd, fv ... information
1322 # Exception will be raised if syntax error found
1324 # @param self The object pointer
1326 def ParseFile(self
):
1331 # Keep processing sections of the FDF until no new sections or a syntax error is found
1333 while self
._GetFd
() or self
._GetFv
() or self
._GetFmp
() or self
._GetCapsule
() or self
._GetVtf
() or self
._GetRule
() or self
._GetOptionRom
():
1336 except Warning as X
:
1338 #'\n\tGot Token: \"%s\" from File %s\n' % (self._Token, FileLineTuple[0]) + \
1339 # At this point, the closest parent would be the included file itself
1340 Profile
= GetParentAtLine(X
.OriginalLineNumber
)
1341 if Profile
is not None:
1342 X
.Message
+= ' near line %d, column %d: %s' \
1343 % (X
.LineNumber
, 0, Profile
.FileLinesList
[X
.LineNumber
-1])
1345 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1346 X
.Message
+= ' near line %d, column %d: %s' \
1347 % (FileLineTuple
[1], self
.CurrentOffsetWithinLine
+ 1, self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:].rstrip(TAB_LINE_BREAK
).rstrip(T_CHAR_CR
))
1350 ## SectionParser() method
1352 # Parse the file section info
1353 # Exception will be raised if syntax error found
1355 # @param self The object pointer
1356 # @param section The section string
1358 def SectionParser(self
, section
):
1360 if not S
.startswith("[DEFINES") and not S
.startswith("[FD.") and not S
.startswith("[FV.") and not S
.startswith("[CAPSULE.") \
1361 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM.") and not S
.startswith('[FMPPAYLOAD.'):
1362 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
)
1364 ## _GetDefines() method
1366 # Get Defines section contents and store its data into AllMacrosList
1368 # @param self The object pointer
1369 # @retval True Successfully find a Defines
1370 # @retval False Not able to find a Defines
1372 def _GetDefines(self
):
1373 if not self
._GetNextToken
():
1376 S
= self
._Token
.upper()
1377 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[DEFINES"):
1378 self
.SectionParser(S
)
1383 if not self
._IsToken
("[DEFINES", True):
1384 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1385 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1386 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1387 raise Warning.Expected("[DEFINES", self
.FileName
, self
.CurrentLineNumber
)
1389 if not self
._IsToken
(TAB_SECTION_END
):
1390 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
1392 while self
._GetNextWord
():
1393 # handle the SET statement
1394 if self
._Token
== 'SET':
1396 self
._GetSetStatement
(None)
1401 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1402 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1403 if not self
._GetNextToken
() or self
._Token
.startswith(TAB_SECTION_START
):
1404 raise Warning.Expected("MACRO value", self
.FileName
, self
.CurrentLineNumber
)
1409 ##_GetError() method
1410 def _GetError(self
):
1411 #save the Current information
1412 CurrentLine
= self
.CurrentLineNumber
1413 CurrentOffset
= self
.CurrentOffsetWithinLine
1414 while self
._GetNextToken
():
1415 if self
._Token
== TAB_ERROR
:
1416 EdkLogger
.error('FdfParser', ERROR_STATEMENT
, self
._CurrentLine
().replace(TAB_ERROR
, '', 1), File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
1417 self
.CurrentLineNumber
= CurrentLine
1418 self
.CurrentOffsetWithinLine
= CurrentOffset
1422 # Get FD section contents and store its data into FD dictionary of self.Profile
1424 # @param self The object pointer
1425 # @retval True Successfully find a FD
1426 # @retval False Not able to find a FD
1429 if not self
._GetNextToken
():
1432 S
= self
._Token
.upper()
1433 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FD."):
1434 if not S
.startswith("[FV.") and not S
.startswith('[FMPPAYLOAD.') and not S
.startswith("[CAPSULE.") \
1435 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM."):
1436 raise Warning("Unknown section", self
.FileName
, self
.CurrentLineNumber
)
1441 if not self
._IsToken
("[FD.", True):
1442 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1443 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1444 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1445 raise Warning.Expected("[FD.]", self
.FileName
, self
.CurrentLineNumber
)
1447 FdName
= self
._GetUiName
()
1449 if len (self
.Profile
.FdDict
) == 0:
1450 FdName
= GenFdsGlobalVariable
.PlatformName
1451 if FdName
== "" and GlobalData
.gActivePlatform
:
1452 FdName
= GlobalData
.gActivePlatform
.PlatformName
1453 self
.Profile
.FdNameNotSet
= True
1455 raise Warning.Expected("FdName in [FD.] section", self
.FileName
, self
.CurrentLineNumber
)
1456 self
.CurrentFdName
= FdName
.upper()
1458 if self
.CurrentFdName
in self
.Profile
.FdDict
:
1459 raise Warning("Unexpected the same FD name", self
.FileName
, self
.CurrentLineNumber
)
1461 if not self
._IsToken
(TAB_SECTION_END
):
1462 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
1465 FdObj
.FdUiName
= self
.CurrentFdName
1466 self
.Profile
.FdDict
[self
.CurrentFdName
] = FdObj
1468 if len (self
.Profile
.FdDict
) > 1 and self
.Profile
.FdNameNotSet
:
1469 raise Warning.Expected("all FDs have their name", self
.FileName
, self
.CurrentLineNumber
)
1471 Status
= self
._GetCreateFile
(FdObj
)
1473 raise Warning("FD name error", self
.FileName
, self
.CurrentLineNumber
)
1475 while self
._GetTokenStatements
(FdObj
):
1477 for Attr
in ("BaseAddress", "Size", "ErasePolarity"):
1478 if getattr(FdObj
, Attr
) is None:
1479 self
._GetNextToken
()
1480 raise Warning("Keyword %s missing" % Attr
, self
.FileName
, self
.CurrentLineNumber
)
1482 if not FdObj
.BlockSizeList
:
1483 FdObj
.BlockSizeList
.append((1, FdObj
.Size
, None))
1485 self
._GetDefineStatements
(FdObj
)
1487 self
._GetSetStatements
(FdObj
)
1489 if not self
._GetRegionLayout
(FdObj
):
1490 raise Warning.Expected("region layout", self
.FileName
, self
.CurrentLineNumber
)
1492 while self
._GetRegionLayout
(FdObj
):
1496 ## _GetUiName() method
1498 # Return the UI name of a section
1500 # @param self The object pointer
1501 # @retval FdName UI name
1503 def _GetUiName(self
):
1505 if self
._GetNextWord
():
1510 ## _GetCreateFile() method
1512 # Return the output file name of object
1514 # @param self The object pointer
1515 # @param Obj object whose data will be stored in file
1516 # @retval FdName UI name
1518 def _GetCreateFile(self
, Obj
):
1519 if self
._IsKeyword
("CREATE_FILE"):
1520 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1521 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1523 if not self
._GetNextToken
():
1524 raise Warning.Expected("file name", self
.FileName
, self
.CurrentLineNumber
)
1526 FileName
= self
._Token
1527 Obj
.CreateFileName
= FileName
1531 def SetPcdLocalation(self
,pcdpair
):
1532 self
.Profile
.PcdLocalDict
[pcdpair
] = (self
.Profile
.FileName
,self
.CurrentLineNumber
)
1534 ## _GetTokenStatements() method
1536 # Get token statements
1538 # @param self The object pointer
1539 # @param Obj for whom token statement is got
1541 def _GetTokenStatements(self
, Obj
):
1542 if self
._IsKeyword
("BaseAddress"):
1543 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1544 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1546 if not self
._GetNextHexNumber
():
1547 raise Warning.Expected("Hex base address", self
.FileName
, self
.CurrentLineNumber
)
1549 Obj
.BaseAddress
= self
._Token
1551 if self
._IsToken
(TAB_VALUE_SPLIT
):
1552 pcdPair
= self
._GetNextPcdSettings
()
1553 Obj
.BaseAddressPcd
= pcdPair
1554 self
.Profile
.PcdDict
[pcdPair
] = Obj
.BaseAddress
1555 self
.SetPcdLocalation(pcdPair
)
1556 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1557 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1560 if self
._IsKeyword
("Size"):
1561 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1562 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1564 if not self
._GetNextHexNumber
():
1565 raise Warning.Expected("Hex size", self
.FileName
, self
.CurrentLineNumber
)
1568 if self
._IsToken
(TAB_VALUE_SPLIT
):
1569 pcdPair
= self
._GetNextPcdSettings
()
1570 Obj
.SizePcd
= pcdPair
1571 self
.Profile
.PcdDict
[pcdPair
] = Size
1572 self
.SetPcdLocalation(pcdPair
)
1573 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1574 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1575 Obj
.Size
= long(Size
, 0)
1578 if self
._IsKeyword
("ErasePolarity"):
1579 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1580 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1582 if not self
._GetNextToken
():
1583 raise Warning.Expected("Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1585 if not self
._Token
in {"1", "0"}:
1586 raise Warning.Expected("1 or 0 Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1588 Obj
.ErasePolarity
= self
._Token
1591 return self
._GetBlockStatements
(Obj
)
1593 ## _GetAddressStatements() method
1595 # Get address statements
1597 # @param self The object pointer
1598 # @param Obj for whom address statement is got
1599 # @retval True Successfully find
1600 # @retval False Not able to find
1602 def _GetAddressStatements(self
, Obj
):
1603 if self
._IsKeyword
("BsBaseAddress"):
1604 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1605 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1607 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1608 raise Warning.Expected("address", self
.FileName
, self
.CurrentLineNumber
)
1610 BsAddress
= long(self
._Token
, 0)
1611 Obj
.BsBaseAddress
= BsAddress
1613 if self
._IsKeyword
("RtBaseAddress"):
1614 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1615 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1617 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1618 raise Warning.Expected("address", self
.FileName
, self
.CurrentLineNumber
)
1620 RtAddress
= long(self
._Token
, 0)
1621 Obj
.RtBaseAddress
= RtAddress
1623 ## _GetBlockStatements() method
1625 # Get block statements
1627 # @param self The object pointer
1628 # @param Obj for whom block statement is got
1630 def _GetBlockStatements(self
, Obj
):
1632 while self
._GetBlockStatement
(Obj
):
1635 Item
= Obj
.BlockSizeList
[-1]
1636 if Item
[0] is None or Item
[1] is None:
1637 raise Warning.Expected("block statement", self
.FileName
, self
.CurrentLineNumber
)
1640 ## _GetBlockStatement() method
1642 # Get block statement
1644 # @param self The object pointer
1645 # @param Obj for whom block statement is got
1646 # @retval True Successfully find
1647 # @retval False Not able to find
1649 def _GetBlockStatement(self
, Obj
):
1650 if not self
._IsKeyword
("BlockSize"):
1653 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1654 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1656 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
1657 raise Warning.Expected("Hex or Integer block size", self
.FileName
, self
.CurrentLineNumber
)
1659 BlockSize
= self
._Token
1661 if self
._IsToken
(TAB_VALUE_SPLIT
):
1662 PcdPair
= self
._GetNextPcdSettings
()
1663 BlockSizePcd
= PcdPair
1664 self
.Profile
.PcdDict
[PcdPair
] = BlockSize
1665 self
.SetPcdLocalation(PcdPair
)
1666 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1667 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1668 BlockSize
= long(BlockSize
, 0)
1671 if self
._IsKeyword
("NumBlocks"):
1672 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1673 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1675 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1676 raise Warning.Expected("block numbers", self
.FileName
, self
.CurrentLineNumber
)
1678 BlockNumber
= long(self
._Token
, 0)
1680 Obj
.BlockSizeList
.append((BlockSize
, BlockNumber
, BlockSizePcd
))
1683 ## _GetDefineStatements() method
1685 # Get define statements
1687 # @param self The object pointer
1688 # @param Obj for whom define statement is got
1689 # @retval True Successfully find
1690 # @retval False Not able to find
1692 def _GetDefineStatements(self
, Obj
):
1693 while self
._GetDefineStatement
(Obj
):
1696 ## _GetDefineStatement() method
1698 # Get define statement
1700 # @param self The object pointer
1701 # @param Obj for whom define statement is got
1702 # @retval True Successfully find
1703 # @retval False Not able to find
1705 def _GetDefineStatement(self
, Obj
):
1706 if self
._IsKeyword
(TAB_DEFINE
):
1707 self
._GetNextToken
()
1709 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1710 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1712 if not self
._GetNextToken
():
1713 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
1716 Macro
= '$(' + Macro
+ ')'
1717 Obj
.DefineVarDict
[Macro
] = Value
1722 ## _GetSetStatements() method
1724 # Get set statements
1726 # @param self The object pointer
1727 # @param Obj for whom set statement is got
1728 # @retval True Successfully find
1729 # @retval False Not able to find
1731 def _GetSetStatements(self
, Obj
):
1732 while self
._GetSetStatement
(Obj
):
1735 ## _GetSetStatement() method
1739 # @param self The object pointer
1740 # @param Obj for whom set statement is got
1741 # @retval True Successfully find
1742 # @retval False Not able to find
1744 def _GetSetStatement(self
, Obj
):
1745 if self
._IsKeyword
("SET"):
1746 PcdPair
= self
._GetNextPcdSettings
()
1748 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1749 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1751 Value
= self
._GetExpression
()
1752 Value
= self
._EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
1755 Obj
.SetVarDict
[PcdPair
] = Value
1756 self
.Profile
.PcdDict
[PcdPair
] = Value
1757 self
.SetPcdLocalation(PcdPair
)
1758 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1759 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1764 ## _CalcRegionExpr(self)
1766 # Calculate expression for offset or size of a region
1768 # @return: None if invalid expression
1769 # Calculated number if successfully
1771 def _CalcRegionExpr(self
):
1772 StartPos
= self
.GetFileBufferPos()
1775 while not self
._EndOfFile
():
1776 CurCh
= self
._CurrentChar
()
1782 if CurCh
in '|\r\n' and PairCount
== 0:
1788 ValueExpression(Expr
,
1789 self
._CollectMacroPcd
()
1792 self
.SetFileBufferPos(StartPos
)
1795 ## _GetRegionLayout() method
1797 # Get region layout for FD
1799 # @param self The object pointer
1800 # @param theFd for whom region is got
1801 # @retval True Successfully find
1802 # @retval False Not able to find
1804 def _GetRegionLayout(self
, theFd
):
1805 Offset
= self
._CalcRegionExpr
()
1809 RegionObj
= Region()
1810 RegionObj
.Offset
= Offset
1811 theFd
.RegionList
.append(RegionObj
)
1813 if not self
._IsToken
(TAB_VALUE_SPLIT
):
1814 raise Warning.Expected("'|'", self
.FileName
, self
.CurrentLineNumber
)
1816 Size
= self
._CalcRegionExpr
()
1818 raise Warning.Expected("Region Size", self
.FileName
, self
.CurrentLineNumber
)
1819 RegionObj
.Size
= Size
1821 if not self
._GetNextWord
():
1824 if not self
._Token
in {"SET", BINARY_FILE_TYPE_FV
, "FILE", "DATA", "CAPSULE", "INF"}:
1826 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1827 # Or it might be next region's offset described by an expression which starts with a PCD.
1828 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1831 IsRegionPcd
= (RegionSizeGuidPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]) or
1832 RegionOffsetPcdPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]))
1834 RegionObj
.PcdOffset
= self
._GetNextPcdSettings
()
1835 self
.Profile
.PcdDict
[RegionObj
.PcdOffset
] = "0x%08X" % (RegionObj
.Offset
+ long(theFd
.BaseAddress
, 0))
1836 self
.SetPcdLocalation(RegionObj
.PcdOffset
)
1837 self
._PcdDict
['%s.%s' % (RegionObj
.PcdOffset
[1], RegionObj
.PcdOffset
[0])] = "0x%x" % RegionObj
.Offset
1838 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1839 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdOffset
] = FileLineTuple
1840 if self
._IsToken
(TAB_VALUE_SPLIT
):
1841 RegionObj
.PcdSize
= self
._GetNextPcdSettings
()
1842 self
.Profile
.PcdDict
[RegionObj
.PcdSize
] = "0x%08X" % RegionObj
.Size
1843 self
.SetPcdLocalation(RegionObj
.PcdSize
)
1844 self
._PcdDict
['%s.%s' % (RegionObj
.PcdSize
[1], RegionObj
.PcdSize
[0])] = "0x%x" % RegionObj
.Size
1845 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1846 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdSize
] = FileLineTuple
1848 if not self
._GetNextWord
():
1851 if self
._Token
== "SET":
1853 self
._GetSetStatements
(RegionObj
)
1854 if not self
._GetNextWord
():
1857 elif self
._Token
== BINARY_FILE_TYPE_FV
:
1859 self
._GetRegionFvType
(RegionObj
)
1861 elif self
._Token
== "CAPSULE":
1863 self
._GetRegionCapType
(RegionObj
)
1865 elif self
._Token
== "FILE":
1867 self
._GetRegionFileType
(RegionObj
)
1869 elif self
._Token
== "INF":
1871 RegionObj
.RegionType
= "INF"
1872 while self
._IsKeyword
("INF"):
1874 ffsInf
= self
._ParseInfStatement
()
1877 RegionObj
.RegionDataList
.append(ffsInf
)
1879 elif self
._Token
== "DATA":
1881 self
._GetRegionDataType
(RegionObj
)
1884 if self
._GetRegionLayout
(theFd
):
1886 raise Warning("A valid region type was not found. "
1887 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
1888 self
.FileName
, self
.CurrentLineNumber
)
1892 ## _GetRegionFvType() method
1894 # Get region fv data for region
1896 # @param self The object pointer
1897 # @param RegionObj for whom region data is got
1899 def _GetRegionFvType(self
, RegionObj
):
1900 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1901 raise Warning.Expected("'FV'", self
.FileName
, self
.CurrentLineNumber
)
1903 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1904 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1906 if not self
._GetNextToken
():
1907 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
1909 RegionObj
.RegionType
= BINARY_FILE_TYPE_FV
1910 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1912 while self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1914 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1915 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1917 if not self
._GetNextToken
():
1918 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
1920 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1922 ## _GetRegionCapType() method
1924 # Get region capsule data for region
1926 # @param self The object pointer
1927 # @param RegionObj for whom region data is got
1929 def _GetRegionCapType(self
, RegionObj
):
1930 if not self
._IsKeyword
("CAPSULE"):
1931 raise Warning.Expected("'CAPSULE'", self
.FileName
, self
.CurrentLineNumber
)
1933 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1934 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1936 if not self
._GetNextToken
():
1937 raise Warning.Expected("CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1939 RegionObj
.RegionType
= "CAPSULE"
1940 RegionObj
.RegionDataList
.append(self
._Token
)
1942 while self
._IsKeyword
("CAPSULE"):
1944 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1945 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1947 if not self
._GetNextToken
():
1948 raise Warning.Expected("CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1950 RegionObj
.RegionDataList
.append(self
._Token
)
1952 ## _GetRegionFileType() method
1954 # Get region file data for region
1956 # @param self The object pointer
1957 # @param RegionObj for whom region data is got
1959 def _GetRegionFileType(self
, RegionObj
):
1960 if not self
._IsKeyword
("FILE"):
1961 raise Warning.Expected("'FILE'", self
.FileName
, self
.CurrentLineNumber
)
1963 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1964 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1966 if not self
._GetNextToken
():
1967 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
1969 RegionObj
.RegionType
= "FILE"
1970 RegionObj
.RegionDataList
.append(self
._Token
)
1972 while self
._IsKeyword
("FILE"):
1974 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1975 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1977 if not self
._GetNextToken
():
1978 raise Warning.Expected("FILE name", self
.FileName
, self
.CurrentLineNumber
)
1980 RegionObj
.RegionDataList
.append(self
._Token
)
1982 ## _GetRegionDataType() method
1984 # Get region array data for region
1986 # @param self The object pointer
1987 # @param RegionObj for whom region data is got
1989 def _GetRegionDataType(self
, RegionObj
):
1990 if not self
._IsKeyword
("DATA"):
1991 raise Warning.Expected("Region Data type", self
.FileName
, self
.CurrentLineNumber
)
1993 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1994 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1996 if not self
._IsToken
("{"):
1997 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
1999 if not self
._GetNextHexNumber
():
2000 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2002 if len(self
._Token
) > 18:
2003 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2005 # convert hex string value to byte hex string array
2006 AllString
= self
._Token
2007 AllStrLen
= len (AllString
)
2009 while AllStrLen
> 4:
2010 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
2011 AllStrLen
= AllStrLen
- 2
2012 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
2015 if len (self
._Token
) <= 4:
2016 while self
._IsToken
(TAB_COMMA_SPLIT
):
2017 if not self
._GetNextHexNumber
():
2018 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2019 if len(self
._Token
) > 4:
2020 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2021 DataString
+= self
._Token
2022 DataString
+= TAB_COMMA_SPLIT
2024 if not self
._IsToken
("}"):
2025 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2027 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2028 RegionObj
.RegionType
= "DATA"
2029 RegionObj
.RegionDataList
.append(DataString
)
2031 while self
._IsKeyword
("DATA"):
2033 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2034 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2036 if not self
._IsToken
("{"):
2037 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2039 if not self
._GetNextHexNumber
():
2040 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2042 if len(self
._Token
) > 18:
2043 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2045 # convert hex string value to byte hex string array
2046 AllString
= self
._Token
2047 AllStrLen
= len (AllString
)
2049 while AllStrLen
> 4:
2050 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
2051 AllStrLen
= AllStrLen
- 2
2052 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
2055 if len (self
._Token
) <= 4:
2056 while self
._IsToken
(TAB_COMMA_SPLIT
):
2057 if not self
._GetNextHexNumber
():
2058 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2059 if len(self
._Token
) > 4:
2060 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2061 DataString
+= self
._Token
2062 DataString
+= TAB_COMMA_SPLIT
2064 if not self
._IsToken
("}"):
2065 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2067 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2068 RegionObj
.RegionDataList
.append(DataString
)
2072 # Get FV section contents and store its data into FV dictionary of self.Profile
2074 # @param self The object pointer
2075 # @retval True Successfully find a FV
2076 # @retval False Not able to find a FV
2079 if not self
._GetNextToken
():
2082 S
= self
._Token
.upper()
2083 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FV."):
2084 self
.SectionParser(S
)
2089 if not self
._IsToken
("[FV.", True):
2090 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2091 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2092 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2093 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2095 FvName
= self
._GetUiName
()
2096 self
.CurrentFvName
= FvName
.upper()
2098 if not self
._IsToken
(TAB_SECTION_END
):
2099 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
2101 FvObj
= FV(Name
=self
.CurrentFvName
)
2102 self
.Profile
.FvDict
[self
.CurrentFvName
] = FvObj
2104 Status
= self
._GetCreateFile
(FvObj
)
2106 raise Warning("FV name error", self
.FileName
, self
.CurrentLineNumber
)
2108 self
._GetDefineStatements
(FvObj
)
2110 self
._GetAddressStatements
(FvObj
)
2113 self
._GetSetStatements
(FvObj
)
2115 if not (self
._GetBlockStatement
(FvObj
) or self
._GetFvBaseAddress
(FvObj
) or
2116 self
._GetFvForceRebase
(FvObj
) or self
._GetFvAlignment
(FvObj
) or
2117 self
._GetFvAttributes
(FvObj
) or self
._GetFvNameGuid
(FvObj
) or
2118 self
._GetFvExtEntryStatement
(FvObj
) or self
._GetFvNameString
(FvObj
)):
2121 if FvObj
.FvNameString
== 'TRUE' and not FvObj
.FvNameGuid
:
2122 raise Warning("FvNameString found but FvNameGuid was not found", self
.FileName
, self
.CurrentLineNumber
)
2124 self
._GetAprioriSection
(FvObj
)
2125 self
._GetAprioriSection
(FvObj
)
2128 isInf
= self
._GetInfStatement
(FvObj
)
2129 isFile
= self
._GetFileStatement
(FvObj
)
2130 if not isInf
and not isFile
:
2135 ## _GetFvAlignment() method
2137 # Get alignment for FV
2139 # @param self The object pointer
2140 # @param Obj for whom alignment is got
2141 # @retval True Successfully find a alignment statement
2142 # @retval False Not able to find a alignment statement
2144 def _GetFvAlignment(self
, Obj
):
2145 if not self
._IsKeyword
("FvAlignment"):
2148 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2149 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2151 if not self
._GetNextToken
():
2152 raise Warning.Expected("alignment value", self
.FileName
, self
.CurrentLineNumber
)
2154 if self
._Token
.upper() not in {"1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2155 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2156 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2158 raise Warning("Unknown alignment value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2159 Obj
.FvAlignment
= self
._Token
2162 ## _GetFvBaseAddress() method
2164 # Get BaseAddress for FV
2166 # @param self The object pointer
2167 # @param Obj for whom FvBaseAddress is got
2168 # @retval True Successfully find a FvBaseAddress statement
2169 # @retval False Not able to find a FvBaseAddress statement
2171 def _GetFvBaseAddress(self
, Obj
):
2172 if not self
._IsKeyword
("FvBaseAddress"):
2175 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2176 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2178 if not self
._GetNextToken
():
2179 raise Warning.Expected("FV base address value", self
.FileName
, self
.CurrentLineNumber
)
2181 if not BaseAddrValuePattern
.match(self
._Token
.upper()):
2182 raise Warning("Unknown FV base address value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2183 Obj
.FvBaseAddress
= self
._Token
2186 ## _GetFvForceRebase() method
2188 # Get FvForceRebase for FV
2190 # @param self The object pointer
2191 # @param Obj for whom FvForceRebase is got
2192 # @retval True Successfully find a FvForceRebase statement
2193 # @retval False Not able to find a FvForceRebase statement
2195 def _GetFvForceRebase(self
, Obj
):
2196 if not self
._IsKeyword
("FvForceRebase"):
2199 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2200 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2202 if not self
._GetNextToken
():
2203 raise Warning.Expected("FvForceRebase value", self
.FileName
, self
.CurrentLineNumber
)
2205 if self
._Token
.upper() not in {"TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"}:
2206 raise Warning("Unknown FvForceRebase value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2208 if self
._Token
.upper() in {"TRUE", "1", "0X1", "0X01"}:
2209 Obj
.FvForceRebase
= True
2210 elif self
._Token
.upper() in {"FALSE", "0", "0X0", "0X00"}:
2211 Obj
.FvForceRebase
= False
2213 Obj
.FvForceRebase
= None
2218 ## _GetFvAttributes() method
2220 # Get attributes for FV
2222 # @param self The object pointer
2223 # @param Obj for whom attribute is got
2226 def _GetFvAttributes(self
, FvObj
):
2228 while self
._GetNextWord
():
2231 if name
not in {"ERASE_POLARITY", "MEMORY_MAPPED", \
2232 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2233 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2234 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2235 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2236 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"}:
2240 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2241 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2243 if not self
._GetNextToken
() or self
._Token
.upper() not in {"TRUE", "FALSE", "1", "0"}:
2244 raise Warning.Expected("TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
2246 FvObj
.FvAttributeDict
[name
] = self
._Token
2250 ## _GetFvNameGuid() method
2252 # Get FV GUID for FV
2254 # @param self The object pointer
2255 # @param Obj for whom GUID is got
2258 def _GetFvNameGuid(self
, FvObj
):
2259 if not self
._IsKeyword
("FvNameGuid"):
2262 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2263 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2265 if not self
._GetNextGuid
():
2266 raise Warning.Expected("GUID value", self
.FileName
, self
.CurrentLineNumber
)
2268 FvObj
.FvNameGuid
= self
._Token
2272 def _GetFvNameString(self
, FvObj
):
2273 if not self
._IsKeyword
("FvNameString"):
2276 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2277 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2279 if not self
._GetNextToken
() or self
._Token
.upper() not in {'TRUE', 'FALSE'}:
2280 raise Warning.Expected("TRUE or FALSE for FvNameString", self
.FileName
, self
.CurrentLineNumber
)
2282 FvObj
.FvNameString
= self
._Token
2286 def _GetFvExtEntryStatement(self
, FvObj
):
2287 if not (self
._IsKeyword
("FV_EXT_ENTRY") or self
._IsKeyword
("FV_EXT_ENTRY_TYPE")):
2290 if not self
._IsKeyword
("TYPE"):
2291 raise Warning.Expected("'TYPE'", self
.FileName
, self
.CurrentLineNumber
)
2293 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2294 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2296 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
2297 raise Warning.Expected("Hex FV extension entry type value At Line ", self
.FileName
, self
.CurrentLineNumber
)
2299 FvObj
.FvExtEntryTypeValue
.append(self
._Token
)
2301 if not self
._IsToken
("{"):
2302 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2304 if not self
._IsKeyword
("FILE") and not self
._IsKeyword
("DATA"):
2305 raise Warning.Expected("'FILE' or 'DATA'", self
.FileName
, self
.CurrentLineNumber
)
2307 FvObj
.FvExtEntryType
.append(self
._Token
)
2309 if self
._Token
== 'DATA':
2310 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2311 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2313 if not self
._IsToken
("{"):
2314 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2316 if not self
._GetNextHexNumber
():
2317 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2319 if len(self
._Token
) > 4:
2320 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2322 DataString
= self
._Token
2323 DataString
+= TAB_COMMA_SPLIT
2325 while self
._IsToken
(TAB_COMMA_SPLIT
):
2326 if not self
._GetNextHexNumber
():
2327 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2328 if len(self
._Token
) > 4:
2329 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2330 DataString
+= self
._Token
2331 DataString
+= TAB_COMMA_SPLIT
2333 if not self
._IsToken
("}"):
2334 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2336 if not self
._IsToken
("}"):
2337 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2339 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2340 FvObj
.FvExtEntryData
.append(DataString
)
2342 if self
._Token
== 'FILE':
2343 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2344 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2346 if not self
._GetNextToken
():
2347 raise Warning.Expected("FV Extension Entry file path At Line ", self
.FileName
, self
.CurrentLineNumber
)
2349 FvObj
.FvExtEntryData
.append(self
._Token
)
2351 if not self
._IsToken
("}"):
2352 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2356 ## _GetAprioriSection() method
2358 # Get token statements
2360 # @param self The object pointer
2361 # @param FvObj for whom apriori is got
2362 # @retval True Successfully find apriori statement
2363 # @retval False Not able to find apriori statement
2365 def _GetAprioriSection(self
, FvObj
):
2366 if not self
._IsKeyword
("APRIORI"):
2369 if not self
._IsKeyword
("PEI") and not self
._IsKeyword
("DXE"):
2370 raise Warning.Expected("Apriori file type", self
.FileName
, self
.CurrentLineNumber
)
2371 AprType
= self
._Token
2373 if not self
._IsToken
("{"):
2374 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2376 AprSectionObj
= AprioriSection()
2377 AprSectionObj
.AprioriType
= AprType
2379 self
._GetDefineStatements
(AprSectionObj
)
2382 IsInf
= self
._GetInfStatement
(AprSectionObj
)
2383 IsFile
= self
._GetFileStatement
(AprSectionObj
)
2384 if not IsInf
and not IsFile
:
2387 if not self
._IsToken
("}"):
2388 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2390 FvObj
.AprioriSectionList
.append(AprSectionObj
)
2393 def _ParseInfStatement(self
):
2394 if not self
._IsKeyword
("INF"):
2397 ffsInf
= FfsInfStatement()
2398 self
._GetInfOptions
(ffsInf
)
2400 if not self
._GetNextToken
():
2401 raise Warning.Expected("INF file path", self
.FileName
, self
.CurrentLineNumber
)
2402 ffsInf
.InfFileName
= self
._Token
2403 if not ffsInf
.InfFileName
.endswith('.inf'):
2404 raise Warning.Expected(".inf file path", self
.FileName
, self
.CurrentLineNumber
)
2406 ffsInf
.CurrentLineNum
= self
.CurrentLineNumber
2407 ffsInf
.CurrentLineContent
= self
._CurrentLine
()
2409 #Replace $(SAPCE) with real space
2410 ffsInf
.InfFileName
= ffsInf
.InfFileName
.replace('$(SPACE)', ' ')
2412 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
2413 #do case sensitive check for file path
2414 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2416 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2418 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
2419 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
2420 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2421 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
2423 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
2424 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
2426 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
2428 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
2430 if self
._IsToken
(TAB_VALUE_SPLIT
):
2431 if self
._IsKeyword
('RELOCS_STRIPPED'):
2432 ffsInf
.KeepReloc
= False
2433 elif self
._IsKeyword
('RELOCS_RETAINED'):
2434 ffsInf
.KeepReloc
= True
2436 raise Warning("Unknown reloc strip flag '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2439 ## _GetInfStatement() method
2441 # Get INF statements
2443 # @param self The object pointer
2444 # @param Obj for whom inf statement is got
2445 # @retval True Successfully find inf statement
2446 # @retval False Not able to find inf statement
2448 def _GetInfStatement(self
, Obj
, ForCapsule
=False):
2449 ffsInf
= self
._ParseInfStatement
()
2454 myCapsuleFfs
= CapsuleFfs()
2455 myCapsuleFfs
.Ffs
= ffsInf
2456 Obj
.CapsuleDataList
.append(myCapsuleFfs
)
2458 Obj
.FfsList
.append(ffsInf
)
2461 ## _GetInfOptions() method
2463 # Get options for INF
2465 # @param self The object pointer
2466 # @param FfsInfObj for whom option is got
2468 def _GetInfOptions(self
, FfsInfObj
):
2469 if self
._IsKeyword
("FILE_GUID"):
2470 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2471 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2472 if not self
._GetNextGuid
():
2473 raise Warning.Expected("GUID value", self
.FileName
, self
.CurrentLineNumber
)
2474 FfsInfObj
.OverrideGuid
= self
._Token
2476 if self
._IsKeyword
("RuleOverride"):
2477 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2478 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2479 if not self
._GetNextToken
():
2480 raise Warning.Expected("Rule name", self
.FileName
, self
.CurrentLineNumber
)
2481 FfsInfObj
.Rule
= self
._Token
2483 if self
._IsKeyword
("VERSION"):
2484 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2485 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2486 if not self
._GetNextToken
():
2487 raise Warning.Expected("Version", self
.FileName
, self
.CurrentLineNumber
)
2489 if self
._GetStringData
():
2490 FfsInfObj
.Version
= self
._Token
2492 if self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2493 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2494 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2495 if not self
._GetNextToken
():
2496 raise Warning.Expected("UI name", self
.FileName
, self
.CurrentLineNumber
)
2498 if self
._GetStringData
():
2499 FfsInfObj
.Ui
= self
._Token
2501 if self
._IsKeyword
("USE"):
2502 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2503 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2504 if not self
._GetNextToken
():
2505 raise Warning.Expected("ARCH name", self
.FileName
, self
.CurrentLineNumber
)
2506 FfsInfObj
.UseArch
= self
._Token
2509 if self
._GetNextToken
():
2510 p
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2511 if p
.match(self
._Token
) and p
.match(self
._Token
).span()[1] == len(self
._Token
):
2512 FfsInfObj
.KeyStringList
.append(self
._Token
)
2513 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2519 while self
._GetNextToken
():
2520 if not p
.match(self
._Token
):
2521 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2522 FfsInfObj
.KeyStringList
.append(self
._Token
)
2524 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2527 ## _GetFileStatement() method
2529 # Get FILE statements
2531 # @param self The object pointer
2532 # @param Obj for whom FILE statement is got
2533 # @retval True Successfully find FILE statement
2534 # @retval False Not able to find FILE statement
2536 def _GetFileStatement(self
, Obj
, ForCapsule
= False):
2537 if not self
._IsKeyword
("FILE"):
2540 if not self
._GetNextWord
():
2541 raise Warning.Expected("FFS type", self
.FileName
, self
.CurrentLineNumber
)
2543 if ForCapsule
and self
._Token
== 'DATA':
2548 FfsFileObj
= FileStatement()
2549 FfsFileObj
.FvFileType
= self
._Token
2551 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2552 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2554 if not self
._GetNextGuid
():
2555 if not self
._GetNextWord
():
2556 raise Warning.Expected("File GUID", self
.FileName
, self
.CurrentLineNumber
)
2557 if self
._Token
== 'PCD':
2558 if not self
._IsToken
("("):
2559 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
2560 PcdPair
= self
._GetNextPcdSettings
()
2561 if not self
._IsToken
(")"):
2562 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
2563 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
2565 FfsFileObj
.NameGuid
= self
._Token
2567 self
._GetFilePart
(FfsFileObj
)
2570 capsuleFfs
= CapsuleFfs()
2571 capsuleFfs
.Ffs
= FfsFileObj
2572 Obj
.CapsuleDataList
.append(capsuleFfs
)
2574 Obj
.FfsList
.append(FfsFileObj
)
2578 ## _FileCouldHaveRelocFlag() method
2580 # Check whether reloc strip flag can be set for a file type.
2582 # @param FileType The file type to check with
2583 # @retval True This type could have relocation strip flag
2584 # @retval False No way to have it
2587 def _FileCouldHaveRelocFlag (FileType
):
2588 if FileType
in {SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
, 'PEI_DXE_COMBO'}:
2593 ## _SectionCouldHaveRelocFlag() method
2595 # Check whether reloc strip flag can be set for a section type.
2597 # @param SectionType The section type to check with
2598 # @retval True This type could have relocation strip flag
2599 # @retval False No way to have it
2602 def _SectionCouldHaveRelocFlag (SectionType
):
2603 if SectionType
in {BINARY_FILE_TYPE_TE
, BINARY_FILE_TYPE_PE32
}:
2608 ## _GetFilePart() method
2610 # Get components for FILE statement
2612 # @param self The object pointer
2613 # @param FfsFileObj for whom component is got
2615 def _GetFilePart(self
, FfsFileObj
):
2616 self
._GetFileOpts
(FfsFileObj
)
2618 if not self
._IsToken
("{"):
2619 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2620 if self
._FileCouldHaveRelocFlag
(FfsFileObj
.FvFileType
):
2621 if self
._Token
== 'RELOCS_STRIPPED':
2622 FfsFileObj
.KeepReloc
= False
2624 FfsFileObj
.KeepReloc
= True
2626 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj
.FvFileType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
2628 if not self
._IsToken
("{"):
2629 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2631 if not self
._GetNextToken
():
2632 raise Warning.Expected("File name or section data", self
.FileName
, self
.CurrentLineNumber
)
2634 if self
._Token
== BINARY_FILE_TYPE_FV
:
2635 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2636 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2637 if not self
._GetNextToken
():
2638 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
2639 FfsFileObj
.FvName
= self
._Token
2641 elif self
._Token
== "FD":
2642 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2643 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2644 if not self
._GetNextToken
():
2645 raise Warning.Expected("FD name", self
.FileName
, self
.CurrentLineNumber
)
2646 FfsFileObj
.FdName
= self
._Token
2648 elif self
._Token
in {TAB_DEFINE
, "APRIORI", "SECTION"}:
2650 self
._GetSectionData
(FfsFileObj
)
2652 elif hasattr(FfsFileObj
, 'FvFileType') and FfsFileObj
.FvFileType
== 'RAW':
2654 self
._GetRAWData
(FfsFileObj
)
2657 FfsFileObj
.CurrentLineNum
= self
.CurrentLineNumber
2658 FfsFileObj
.CurrentLineContent
= self
._CurrentLine
()
2659 FfsFileObj
.FileName
= self
._Token
.replace('$(SPACE)', ' ')
2660 self
._VerifyFile
(FfsFileObj
.FileName
)
2662 if not self
._IsToken
("}"):
2663 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2665 ## _GetRAWData() method
2667 # Get RAW data for FILE statement
2669 # @param self The object pointer
2670 # @param FfsFileObj for whom section is got
2672 def _GetRAWData(self
, FfsFileObj
):
2673 FfsFileObj
.FileName
= []
2674 FfsFileObj
.SubAlignment
= []
2677 if self
._GetAlignment
():
2678 if self
._Token
not in ALIGNMENTS
:
2679 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2680 #For FFS, Auto is default option same to ""
2681 if not self
._Token
== "Auto":
2682 AlignValue
= self
._Token
2683 if not self
._GetNextToken
():
2684 raise Warning.Expected("Filename value", self
.FileName
, self
.CurrentLineNumber
)
2686 FileName
= self
._Token
.replace('$(SPACE)', ' ')
2689 raise Warning.Expected("Filename value", self
.FileName
, self
.CurrentLineNumber
)
2691 self
._VerifyFile
(FileName
)
2692 File
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
)
2693 FfsFileObj
.FileName
.append(File
.Path
)
2694 FfsFileObj
.SubAlignment
.append(AlignValue
)
2696 if self
._IsToken
("}"):
2700 if len(FfsFileObj
.SubAlignment
) == 1:
2701 FfsFileObj
.SubAlignment
= FfsFileObj
.SubAlignment
[0]
2702 if len(FfsFileObj
.FileName
) == 1:
2703 FfsFileObj
.FileName
= FfsFileObj
.FileName
[0]
2705 ## _GetFileOpts() method
2707 # Get options for FILE statement
2709 # @param self The object pointer
2710 # @param FfsFileObj for whom options is got
2712 def _GetFileOpts(self
, FfsFileObj
):
2713 if self
._GetNextToken
():
2714 if TokenFindPattern
.match(self
._Token
):
2715 FfsFileObj
.KeyStringList
.append(self
._Token
)
2716 if self
._IsToken
(TAB_COMMA_SPLIT
):
2717 while self
._GetNextToken
():
2718 if not TokenFindPattern
.match(self
._Token
):
2719 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2720 FfsFileObj
.KeyStringList
.append(self
._Token
)
2722 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2728 if self
._IsKeyword
("FIXED", True):
2729 FfsFileObj
.Fixed
= True
2731 if self
._IsKeyword
("CHECKSUM", True):
2732 FfsFileObj
.CheckSum
= True
2734 if self
._GetAlignment
():
2735 if self
._Token
not in ALIGNMENTS
:
2736 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2737 #For FFS, Auto is default option same to ""
2738 if not self
._Token
== "Auto":
2739 FfsFileObj
.Alignment
= self
._Token
2741 ## _GetAlignment() method
2743 # Return the alignment value
2745 # @param self The object pointer
2746 # @retval True Successfully find alignment
2747 # @retval False Not able to find alignment
2749 def _GetAlignment(self
):
2750 if self
._IsKeyword
("Align", True):
2751 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2752 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2754 if not self
._GetNextToken
():
2755 raise Warning.Expected("alignment value", self
.FileName
, self
.CurrentLineNumber
)
2760 ## _GetSectionData() method
2762 # Get section data for FILE statement
2764 # @param self The object pointer
2765 # @param FfsFileObj for whom section is got
2767 def _GetSectionData(self
, FfsFileObj
):
2768 self
._GetDefineStatements
(FfsFileObj
)
2771 IsLeafSection
= self
._GetLeafSection
(FfsFileObj
)
2772 IsEncapSection
= self
._GetEncapsulationSec
(FfsFileObj
)
2773 if not IsLeafSection
and not IsEncapSection
:
2776 ## _GetLeafSection() method
2778 # Get leaf section for Obj
2780 # @param self The object pointer
2781 # @param Obj for whom leaf section is got
2782 # @retval True Successfully find section statement
2783 # @retval False Not able to find section statement
2785 def _GetLeafSection(self
, Obj
):
2786 OldPos
= self
.GetFileBufferPos()
2788 if not self
._IsKeyword
("SECTION"):
2789 if len(Obj
.SectionList
) == 0:
2790 raise Warning.Expected("SECTION", self
.FileName
, self
.CurrentLineNumber
)
2795 if self
._GetAlignment
():
2796 if self
._Token
not in ALIGNMENTS
:
2797 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2798 AlignValue
= self
._Token
2801 if self
._IsKeyword
("BUILD_NUM"):
2802 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2803 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2805 if not self
._GetNextToken
():
2806 raise Warning.Expected("Build number value", self
.FileName
, self
.CurrentLineNumber
)
2808 BuildNum
= self
._Token
2810 if self
._IsKeyword
("VERSION"):
2811 if AlignValue
== 'Auto':
2812 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2813 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2814 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2815 if not self
._GetNextToken
():
2816 raise Warning.Expected("version", self
.FileName
, self
.CurrentLineNumber
)
2817 VerSectionObj
= VerSection()
2818 VerSectionObj
.Alignment
= AlignValue
2819 VerSectionObj
.BuildNum
= BuildNum
2820 if self
._GetStringData
():
2821 VerSectionObj
.StringData
= self
._Token
2823 VerSectionObj
.FileName
= self
._Token
2824 Obj
.SectionList
.append(VerSectionObj
)
2826 elif self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2827 if AlignValue
== 'Auto':
2828 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2829 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2830 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2831 if not self
._GetNextToken
():
2832 raise Warning.Expected("UI", self
.FileName
, self
.CurrentLineNumber
)
2833 UiSectionObj
= UiSection()
2834 UiSectionObj
.Alignment
= AlignValue
2835 if self
._GetStringData
():
2836 UiSectionObj
.StringData
= self
._Token
2838 UiSectionObj
.FileName
= self
._Token
2839 Obj
.SectionList
.append(UiSectionObj
)
2841 elif self
._IsKeyword
("FV_IMAGE"):
2842 if AlignValue
== 'Auto':
2843 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2844 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2845 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2846 if not self
._GetNextToken
():
2847 raise Warning.Expected("FV name or FV file path", self
.FileName
, self
.CurrentLineNumber
)
2849 FvName
= self
._Token
2852 if self
._IsToken
("{"):
2854 FvObj
.UiFvName
= FvName
.upper()
2855 self
._GetDefineStatements
(FvObj
)
2857 self
._GetBlockStatement
(FvObj
)
2858 self
._GetSetStatements
(FvObj
)
2859 self
._GetFvAlignment
(FvObj
)
2860 self
._GetFvAttributes
(FvObj
)
2863 IsInf
= self
._GetInfStatement
(FvObj
)
2864 IsFile
= self
._GetFileStatement
(FvObj
)
2865 if not IsInf
and not IsFile
:
2868 if not self
._IsToken
("}"):
2869 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2871 FvImageSectionObj
= FvImageSection()
2872 FvImageSectionObj
.Alignment
= AlignValue
2873 if FvObj
is not None:
2874 FvImageSectionObj
.Fv
= FvObj
2875 FvImageSectionObj
.FvName
= None
2877 FvImageSectionObj
.FvName
= FvName
.upper()
2878 FvImageSectionObj
.FvFileName
= FvName
2880 Obj
.SectionList
.append(FvImageSectionObj
)
2882 elif self
._IsKeyword
("PEI_DEPEX_EXP") or self
._IsKeyword
("DXE_DEPEX_EXP") or self
._IsKeyword
("SMM_DEPEX_EXP"):
2883 if AlignValue
== 'Auto':
2884 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2885 DepexSectionObj
= DepexSection()
2886 DepexSectionObj
.Alignment
= AlignValue
2887 DepexSectionObj
.DepexType
= self
._Token
2889 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2890 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2891 if not self
._IsToken
("{"):
2892 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2893 if not self
._SkipToToken
("}"):
2894 raise Warning.Expected("Depex expression ending '}'", self
.FileName
, self
.CurrentLineNumber
)
2896 DepexSectionObj
.Expression
= self
._SkippedChars
.rstrip('}')
2897 Obj
.SectionList
.append(DepexSectionObj
)
2900 if not self
._GetNextWord
():
2901 raise Warning.Expected("section type", self
.FileName
, self
.CurrentLineNumber
)
2903 # Encapsulation section appear, UndoToken and return
2904 if self
._Token
== "COMPRESS" or self
._Token
== "GUIDED":
2905 self
.SetFileBufferPos(OldPos
)
2908 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
,\
2909 BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX
}:
2910 raise Warning("Unknown section type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2911 if AlignValue
== 'Auto'and (not self
._Token
== BINARY_FILE_TYPE_PE32
) and (not self
._Token
== BINARY_FILE_TYPE_TE
):
2912 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2915 DataSectionObj
= DataSection()
2916 DataSectionObj
.Alignment
= AlignValue
2917 DataSectionObj
.SecType
= self
._Token
2919 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2920 if self
._FileCouldHaveRelocFlag
(Obj
.FvFileType
) and self
._SectionCouldHaveRelocFlag
(DataSectionObj
.SecType
):
2921 if self
._Token
== 'RELOCS_STRIPPED':
2922 DataSectionObj
.KeepReloc
= False
2924 DataSectionObj
.KeepReloc
= True
2926 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
)
2928 if self
._IsToken
(TAB_EQUAL_SPLIT
):
2929 if not self
._GetNextToken
():
2930 raise Warning.Expected("section file path", self
.FileName
, self
.CurrentLineNumber
)
2931 DataSectionObj
.SectFileName
= self
._Token
2932 self
._VerifyFile
(DataSectionObj
.SectFileName
)
2934 if not self
._GetCglSection
(DataSectionObj
):
2937 Obj
.SectionList
.append(DataSectionObj
)
2943 # Check if file exists or not:
2944 # If current phase if GenFds, the file must exist;
2945 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
2946 # @param FileName: File path to be verified.
2948 def _VerifyFile(self
, FileName
):
2949 if FileName
.replace(TAB_WORKSPACE
, '').find('$') != -1:
2951 if not GlobalData
.gAutoGenPhase
or not self
._GetMacroValue
(TAB_DSC_DEFINES_OUTPUT_DIRECTORY
) in FileName
:
2952 ErrorCode
, ErrorInfo
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2954 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2956 ## _GetCglSection() method
2958 # Get compressed or GUIDed section for Obj
2960 # @param self The object pointer
2961 # @param Obj for whom leaf section is got
2962 # @param AlignValue alignment value for complex section
2963 # @retval True Successfully find section statement
2964 # @retval False Not able to find section statement
2966 def _GetCglSection(self
, Obj
, AlignValue
= None):
2968 if self
._IsKeyword
("COMPRESS"):
2970 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
2973 if not self
._IsToken
("{"):
2974 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2976 CompressSectionObj
= CompressSection()
2977 CompressSectionObj
.Alignment
= AlignValue
2978 CompressSectionObj
.CompType
= type
2979 # Recursive sections...
2981 IsLeafSection
= self
._GetLeafSection
(CompressSectionObj
)
2982 IsEncapSection
= self
._GetEncapsulationSec
(CompressSectionObj
)
2983 if not IsLeafSection
and not IsEncapSection
:
2987 if not self
._IsToken
("}"):
2988 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2989 Obj
.SectionList
.append(CompressSectionObj
)
2992 elif self
._IsKeyword
("GUIDED"):
2994 if self
._GetNextGuid
():
2995 GuidValue
= self
._Token
2997 AttribDict
= self
._GetGuidAttrib
()
2998 if not self
._IsToken
("{"):
2999 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
3000 GuidSectionObj
= GuidSection()
3001 GuidSectionObj
.Alignment
= AlignValue
3002 GuidSectionObj
.NameGuid
= GuidValue
3003 GuidSectionObj
.SectionType
= "GUIDED"
3004 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
3005 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
3006 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
3007 # Recursive sections...
3009 IsLeafSection
= self
._GetLeafSection
(GuidSectionObj
)
3010 IsEncapSection
= self
._GetEncapsulationSec
(GuidSectionObj
)
3011 if not IsLeafSection
and not IsEncapSection
:
3014 if not self
._IsToken
("}"):
3015 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3016 Obj
.SectionList
.append(GuidSectionObj
)
3022 ## _GetGuidAttri() method
3024 # Get attributes for GUID section
3026 # @param self The object pointer
3027 # @retval AttribDict Dictionary of key-value pair of section attributes
3029 def _GetGuidAttrib(self
):
3031 AttribDict
["PROCESSING_REQUIRED"] = "NONE"
3032 AttribDict
["AUTH_STATUS_VALID"] = "NONE"
3033 AttribDict
["EXTRA_HEADER_SIZE"] = -1
3034 while self
._IsKeyword
("PROCESSING_REQUIRED") or self
._IsKeyword
("AUTH_STATUS_VALID") \
3035 or self
._IsKeyword
("EXTRA_HEADER_SIZE"):
3036 AttribKey
= self
._Token
3038 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3039 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3041 if not self
._GetNextToken
():
3042 raise Warning.Expected("TRUE(1)/FALSE(0)/Number", self
.FileName
, self
.CurrentLineNumber
)
3043 elif AttribKey
== "EXTRA_HEADER_SIZE":
3045 if self
._Token
[0:2].upper() == "0X":
3048 AttribDict
[AttribKey
] = int(self
._Token
, Base
)
3051 raise Warning.Expected("Number", self
.FileName
, self
.CurrentLineNumber
)
3052 elif self
._Token
.upper() not in {"TRUE", "FALSE", "1", "0"}:
3053 raise Warning.Expected("TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
3054 AttribDict
[AttribKey
] = self
._Token
3058 ## _GetEncapsulationSec() method
3060 # Get encapsulation section for FILE
3062 # @param self The object pointer
3063 # @param FfsFile for whom section is got
3064 # @retval True Successfully find section statement
3065 # @retval False Not able to find section statement
3067 def _GetEncapsulationSec(self
, FfsFileObj
):
3068 OldPos
= self
.GetFileBufferPos()
3069 if not self
._IsKeyword
("SECTION"):
3070 if len(FfsFileObj
.SectionList
) == 0:
3071 raise Warning.Expected("SECTION", self
.FileName
, self
.CurrentLineNumber
)
3076 if self
._GetAlignment
():
3077 if self
._Token
not in ALIGNMENT_NOAUTO
:
3078 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3079 AlignValue
= self
._Token
3081 if not self
._GetCglSection
(FfsFileObj
, AlignValue
):
3082 self
.SetFileBufferPos(OldPos
)
3088 if not self
._GetNextToken
():
3090 S
= self
._Token
.upper()
3091 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FMPPAYLOAD."):
3092 self
.SectionParser(S
)
3097 self
._SkipToToken
("[FMPPAYLOAD.", True)
3098 FmpUiName
= self
._GetUiName
().upper()
3099 if FmpUiName
in self
.Profile
.FmpPayloadDict
:
3100 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName
, self
.FileName
, self
.CurrentLineNumber
)
3102 FmpData
= CapsulePayload()
3103 FmpData
.UiName
= FmpUiName
3105 if not self
._IsToken
(TAB_SECTION_END
):
3106 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3108 if not self
._GetNextToken
():
3109 raise Warning("The FMP payload section is empty!", self
.FileName
, self
.CurrentLineNumber
)
3110 FmpKeyList
= ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']
3111 while self
._Token
in FmpKeyList
:
3113 FmpKeyList
.remove(Name
)
3114 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3115 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3116 if Name
== 'IMAGE_TYPE_ID':
3117 if not self
._GetNextGuid
():
3118 raise Warning.Expected("GUID value for IMAGE_TYPE_ID.", self
.FileName
, self
.CurrentLineNumber
)
3119 FmpData
.ImageTypeId
= self
._Token
3120 elif Name
== 'CERTIFICATE_GUID':
3121 if not self
._GetNextGuid
():
3122 raise Warning.Expected("GUID value for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3123 FmpData
.Certificate_Guid
= self
._Token
3124 if UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_RSA2048_SHA256_GUID
and UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_PKCS7_GUID
:
3125 raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3127 if not self
._GetNextToken
():
3128 raise Warning.Expected("value of %s" % Name
, self
.FileName
, self
.CurrentLineNumber
)
3130 if Name
== 'IMAGE_HEADER_INIT_VERSION':
3131 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3132 FmpData
.Version
= Value
3133 elif Name
== 'IMAGE_INDEX':
3134 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3135 FmpData
.ImageIndex
= Value
3136 elif Name
== 'HARDWARE_INSTANCE':
3137 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3138 FmpData
.HardwareInstance
= Value
3139 elif Name
== 'MONOTONIC_COUNT':
3140 if FdfParser
._Verify
(Name
, Value
, 'UINT64'):
3141 FmpData
.MonotonicCount
= Value
3142 if FmpData
.MonotonicCount
.upper().startswith('0X'):
3143 FmpData
.MonotonicCount
= (long)(FmpData
.MonotonicCount
, 16)
3145 FmpData
.MonotonicCount
= (long)(FmpData
.MonotonicCount
)
3146 if not self
._GetNextToken
():
3151 if (FmpData
.MonotonicCount
and not FmpData
.Certificate_Guid
) or (not FmpData
.MonotonicCount
and FmpData
.Certificate_Guid
):
3152 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")
3154 # Only the IMAGE_TYPE_ID is required item
3155 if FmpKeyList
and 'IMAGE_TYPE_ID' in FmpKeyList
:
3156 raise Warning("'IMAGE_TYPE_ID' in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3157 # get the Image file and Vendor code file
3158 self
._GetFMPCapsuleData
(FmpData
)
3159 if not FmpData
.ImageFile
:
3160 raise Warning("Missing image file in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3161 # check whether more than one Vendor code file
3162 if len(FmpData
.VendorCodeFile
) > 1:
3163 raise Warning("Vendor code file max of 1 per FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3164 self
.Profile
.FmpPayloadDict
[FmpUiName
] = FmpData
3167 ## _GetCapsule() method
3169 # Get capsule section contents and store its data into capsule list of self.Profile
3171 # @param self The object pointer
3172 # @retval True Successfully find a capsule
3173 # @retval False Not able to find a capsule
3175 def _GetCapsule(self
):
3176 if not self
._GetNextToken
():
3179 S
= self
._Token
.upper()
3180 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[CAPSULE."):
3181 self
.SectionParser(S
)
3186 if not self
._IsToken
("[CAPSULE.", True):
3187 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3188 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3189 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3190 raise Warning.Expected("[Capsule.]", self
.FileName
, self
.CurrentLineNumber
)
3192 CapsuleObj
= Capsule()
3194 CapsuleName
= self
._GetUiName
()
3196 raise Warning.Expected("capsule name", self
.FileName
, self
.CurrentLineNumber
)
3198 CapsuleObj
.UiCapsuleName
= CapsuleName
.upper()
3200 if not self
._IsToken
(TAB_SECTION_END
):
3201 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3203 if self
._IsKeyword
("CREATE_FILE"):
3204 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3205 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3207 if not self
._GetNextToken
():
3208 raise Warning.Expected("file name", self
.FileName
, self
.CurrentLineNumber
)
3210 CapsuleObj
.CreateFile
= self
._Token
3212 self
._GetCapsuleStatements
(CapsuleObj
)
3213 self
.Profile
.CapsuleDict
[CapsuleObj
.UiCapsuleName
] = CapsuleObj
3216 ## _GetCapsuleStatements() method
3218 # Get statements for capsule
3220 # @param self The object pointer
3221 # @param Obj for whom statements are got
3223 def _GetCapsuleStatements(self
, Obj
):
3224 self
._GetCapsuleTokens
(Obj
)
3225 self
._GetDefineStatements
(Obj
)
3226 self
._GetSetStatements
(Obj
)
3227 self
._GetCapsuleData
(Obj
)
3229 ## _GetCapsuleTokens() method
3231 # Get token statements for capsule
3233 # @param self The object pointer
3234 # @param Obj for whom token statements are got
3236 def _GetCapsuleTokens(self
, Obj
):
3237 if not self
._GetNextToken
():
3239 while self
._Token
in {"CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"}:
3240 Name
= self
._Token
.strip()
3241 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3242 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3243 if not self
._GetNextToken
():
3244 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
3245 if Name
== 'CAPSULE_FLAGS':
3246 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3247 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3248 Value
= self
._Token
.strip()
3249 while self
._IsToken
(TAB_COMMA_SPLIT
):
3250 Value
+= TAB_COMMA_SPLIT
3251 if not self
._GetNextToken
():
3252 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
3253 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3254 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3255 Value
+= self
._Token
.strip()
3256 elif Name
== 'OEM_CAPSULE_FLAGS':
3257 Value
= self
._Token
.strip()
3258 if not Value
.upper().startswith('0X'):
3259 raise Warning.Expected("hex value starting with 0x", self
.FileName
, self
.CurrentLineNumber
)
3261 Value
= int(Value
, 0)
3263 raise Warning.Expected("hex string failed to convert to value", self
.FileName
, self
.CurrentLineNumber
)
3264 if not 0x0000 <= Value
<= 0xFFFF:
3265 raise Warning.Expected("hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3266 Value
= self
._Token
.strip()
3268 Value
= self
._Token
.strip()
3269 Obj
.TokensDict
[Name
] = Value
3270 if not self
._GetNextToken
():
3274 ## _GetCapsuleData() method
3276 # Get capsule data for capsule
3278 # @param self The object pointer
3279 # @param Obj for whom capsule data are got
3281 def _GetCapsuleData(self
, Obj
):
3283 IsInf
= self
._GetInfStatement
(Obj
, True)
3284 IsFile
= self
._GetFileStatement
(Obj
, True)
3285 IsFv
= self
._GetFvStatement
(Obj
)
3286 IsFd
= self
._GetFdStatement
(Obj
)
3287 IsAnyFile
= self
._GetAnyFileStatement
(Obj
)
3288 IsAfile
= self
._GetAfileStatement
(Obj
)
3289 IsFmp
= self
._GetFmpStatement
(Obj
)
3290 if not (IsInf
or IsFile
or IsFv
or IsFd
or IsAnyFile
or IsAfile
or IsFmp
):
3293 ## _GetFMPCapsuleData() method
3295 # Get capsule data for FMP capsule
3297 # @param self The object pointer
3298 # @param Obj for whom capsule data are got
3300 def _GetFMPCapsuleData(self
, Obj
):
3302 IsFv
= self
._GetFvStatement
(Obj
, True)
3303 IsFd
= self
._GetFdStatement
(Obj
, True)
3304 IsAnyFile
= self
._GetAnyFileStatement
(Obj
, True)
3305 if not (IsFv
or IsFd
or IsAnyFile
):
3308 ## _GetFvStatement() method
3310 # Get FV for capsule
3312 # @param self The object pointer
3313 # @param CapsuleObj for whom FV is got
3314 # @retval True Successfully find a FV statement
3315 # @retval False Not able to find a FV statement
3317 def _GetFvStatement(self
, CapsuleObj
, FMPCapsule
= False):
3318 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3321 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3322 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3324 if not self
._GetNextToken
():
3325 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
3327 if self
._Token
.upper() not in self
.Profile
.FvDict
:
3328 raise Warning("FV name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3330 myCapsuleFv
= CapsuleFv()
3331 myCapsuleFv
.FvName
= self
._Token
3333 if not CapsuleObj
.ImageFile
:
3334 CapsuleObj
.ImageFile
.append(myCapsuleFv
)
3336 CapsuleObj
.VendorCodeFile
.append(myCapsuleFv
)
3338 CapsuleObj
.CapsuleDataList
.append(myCapsuleFv
)
3341 ## _GetFdStatement() method
3343 # Get FD for capsule
3345 # @param self The object pointer
3346 # @param CapsuleObj for whom FD is got
3347 # @retval True Successfully find a FD statement
3348 # @retval False Not able to find a FD statement
3350 def _GetFdStatement(self
, CapsuleObj
, FMPCapsule
= False):
3351 if not self
._IsKeyword
("FD"):
3354 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3355 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3357 if not self
._GetNextToken
():
3358 raise Warning.Expected("FD name", self
.FileName
, self
.CurrentLineNumber
)
3360 if self
._Token
.upper() not in self
.Profile
.FdDict
:
3361 raise Warning("FD name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3363 myCapsuleFd
= CapsuleFd()
3364 myCapsuleFd
.FdName
= self
._Token
3366 if not CapsuleObj
.ImageFile
:
3367 CapsuleObj
.ImageFile
.append(myCapsuleFd
)
3369 CapsuleObj
.VendorCodeFile
.append(myCapsuleFd
)
3371 CapsuleObj
.CapsuleDataList
.append(myCapsuleFd
)
3374 def _GetFmpStatement(self
, CapsuleObj
):
3375 if not self
._IsKeyword
("FMP_PAYLOAD"):
3376 if not self
._IsKeyword
("FMP"):
3379 if not self
._IsKeyword
("PAYLOAD"):
3383 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3384 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3386 if not self
._GetNextToken
():
3387 raise Warning.Expected("payload name after FMP_PAYLOAD =", self
.FileName
, self
.CurrentLineNumber
)
3388 Payload
= self
._Token
.upper()
3389 if Payload
not in self
.Profile
.FmpPayloadDict
:
3390 raise Warning("This FMP Payload does not exist: %s" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3391 CapsuleObj
.FmpPayloadList
.append(self
.Profile
.FmpPayloadDict
[Payload
])
3394 def _ParseRawFileStatement(self
):
3395 if not self
._IsKeyword
("FILE"):
3398 if not self
._IsKeyword
("DATA"):
3402 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3403 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3405 if not self
._GetNextToken
():
3406 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
3408 AnyFileName
= self
._Token
3409 self
._VerifyFile
(AnyFileName
)
3411 if not os
.path
.isabs(AnyFileName
):
3412 AnyFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, AnyFileName
)
3416 ## _GetAnyFileStatement() method
3418 # Get AnyFile for capsule
3420 # @param self The object pointer
3421 # @param CapsuleObj for whom AnyFile is got
3422 # @retval True Successfully find a Anyfile statement
3423 # @retval False Not able to find a AnyFile statement
3425 def _GetAnyFileStatement(self
, CapsuleObj
, FMPCapsule
= False):
3426 AnyFileName
= self
._ParseRawFileStatement
()
3430 myCapsuleAnyFile
= CapsuleAnyFile()
3431 myCapsuleAnyFile
.FileName
= AnyFileName
3433 if not CapsuleObj
.ImageFile
:
3434 CapsuleObj
.ImageFile
.append(myCapsuleAnyFile
)
3436 CapsuleObj
.VendorCodeFile
.append(myCapsuleAnyFile
)
3438 CapsuleObj
.CapsuleDataList
.append(myCapsuleAnyFile
)
3441 ## _GetAfileStatement() method
3443 # Get Afile for capsule
3445 # @param self The object pointer
3446 # @param CapsuleObj for whom Afile is got
3447 # @retval True Successfully find a Afile statement
3448 # @retval False Not able to find a Afile statement
3450 def _GetAfileStatement(self
, CapsuleObj
):
3451 if not self
._IsKeyword
("APPEND"):
3454 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3455 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3457 if not self
._GetNextToken
():
3458 raise Warning.Expected("Afile name", self
.FileName
, self
.CurrentLineNumber
)
3460 AfileName
= self
._Token
3461 AfileBaseName
= os
.path
.basename(AfileName
)
3463 if os
.path
.splitext(AfileBaseName
)[1] not in {".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"}:
3464 raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \
3465 self
.FileName
, self
.CurrentLineNumber
)
3467 if not os
.path
.isabs(AfileName
):
3468 AfileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(AfileName
)
3469 self
._VerifyFile
(AfileName
)
3471 if not os
.path
.exists(AfileName
):
3472 raise Warning('%s does not exist' % AfileName
, self
.FileName
, self
.CurrentLineNumber
)
3476 myCapsuleAfile
= CapsuleAfile()
3477 myCapsuleAfile
.FileName
= AfileName
3478 CapsuleObj
.CapsuleDataList
.append(myCapsuleAfile
)
3481 ## _GetRule() method
3483 # Get Rule section contents and store its data into rule list of self.Profile
3485 # @param self The object pointer
3486 # @retval True Successfully find a Rule
3487 # @retval False Not able to find a Rule
3490 if not self
._GetNextToken
():
3493 S
= self
._Token
.upper()
3494 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[RULE."):
3495 self
.SectionParser(S
)
3499 if not self
._IsToken
("[Rule.", True):
3500 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3501 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3502 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3503 raise Warning.Expected("[Rule.]", self
.FileName
, self
.CurrentLineNumber
)
3505 if not self
._SkipToToken
(TAB_SPLIT
):
3506 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
3508 Arch
= self
._SkippedChars
.rstrip(TAB_SPLIT
)
3509 if Arch
.upper() not in ARCH_SET_FULL
:
3510 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
3512 ModuleType
= self
._GetModuleType
()
3515 if self
._IsToken
(TAB_SPLIT
):
3516 if not self
._GetNextWord
():
3517 raise Warning.Expected("template name", self
.FileName
, self
.CurrentLineNumber
)
3518 TemplateName
= self
._Token
3520 if not self
._IsToken
(TAB_SECTION_END
):
3521 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3523 RuleObj
= self
._GetRuleFileStatements
()
3524 RuleObj
.Arch
= Arch
.upper()
3525 RuleObj
.ModuleType
= ModuleType
3526 RuleObj
.TemplateName
= TemplateName
3527 if TemplateName
== '':
3528 self
.Profile
.RuleDict
['RULE' + \
3532 ModuleType
.upper() ] = RuleObj
3534 self
.Profile
.RuleDict
['RULE' + \
3538 ModuleType
.upper() + \
3540 TemplateName
.upper() ] = RuleObj
3543 ## _GetModuleType() method
3545 # Return the module type
3547 # @param self The object pointer
3548 # @retval string module type
3550 def _GetModuleType(self
):
3551 if not self
._GetNextWord
():
3552 raise Warning.Expected("Module type", self
.FileName
, self
.CurrentLineNumber
)
3553 if self
._Token
.upper() not in {
3554 SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3555 SUP_MODULE_DXE_CORE
, SUP_MODULE_DXE_DRIVER
,
3556 SUP_MODULE_DXE_SAL_DRIVER
, SUP_MODULE_DXE_SMM_DRIVER
,
3557 SUP_MODULE_DXE_RUNTIME_DRIVER
, SUP_MODULE_UEFI_DRIVER
,
3558 SUP_MODULE_UEFI_APPLICATION
, SUP_MODULE_USER_DEFINED
,
3559 TAB_DEFAULT
, SUP_MODULE_BASE
,
3560 EDK_COMPONENT_TYPE_SECURITY_CORE
,
3561 EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER
,
3562 EDK_COMPONENT_TYPE_PIC_PEIM
,
3563 EDK_COMPONENT_TYPE_RELOCATABLE_PEIM
, "PE32_PEIM",
3564 EDK_COMPONENT_TYPE_BS_DRIVER
, EDK_COMPONENT_TYPE_RT_DRIVER
,
3565 EDK_COMPONENT_TYPE_SAL_RT_DRIVER
,
3566 EDK_COMPONENT_TYPE_APPLICATION
, "ACPITABLE",
3567 SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3568 SUP_MODULE_MM_CORE_STANDALONE
}:
3569 raise Warning("Unknown Module type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3572 ## _GetFileExtension() method
3574 # Return the file extension
3576 # @param self The object pointer
3577 # @retval string file name extension
3579 def _GetFileExtension(self
):
3580 if not self
._IsToken
(TAB_SPLIT
):
3581 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
3584 if self
._GetNextToken
():
3585 if FileExtensionPattern
.match(self
._Token
):
3587 return TAB_SPLIT
+ Ext
3589 raise Warning("Unknown file extension '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3592 raise Warning.Expected("file extension", self
.FileName
, self
.CurrentLineNumber
)
3594 ## _GetRuleFileStatement() method
3598 # @param self The object pointer
3599 # @retval Rule Rule object
3601 def _GetRuleFileStatements(self
):
3602 if not self
._IsKeyword
("FILE"):
3603 raise Warning.Expected("FILE", self
.FileName
, self
.CurrentLineNumber
)
3605 if not self
._GetNextWord
():
3606 raise Warning.Expected("FFS type", self
.FileName
, self
.CurrentLineNumber
)
3608 Type
= self
._Token
.strip().upper()
3609 if Type
not in {"RAW", "FREEFORM", SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3610 "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE
, EDK_COMPONENT_TYPE_APPLICATION
,
3611 "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3612 SUP_MODULE_MM_CORE_STANDALONE
}:
3613 raise Warning("Unknown FV type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3615 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3616 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3618 if not self
._IsKeyword
("$(NAMED_GUID)"):
3619 if not self
._GetNextWord
():
3620 raise Warning.Expected("$(NAMED_GUID)", self
.FileName
, self
.CurrentLineNumber
)
3621 if self
._Token
== 'PCD':
3622 if not self
._IsToken
("("):
3623 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3624 PcdPair
= self
._GetNextPcdSettings
()
3625 if not self
._IsToken
(")"):
3626 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3627 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3629 NameGuid
= self
._Token
3632 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3633 if self
._FileCouldHaveRelocFlag
(Type
):
3634 if self
._Token
== 'RELOCS_STRIPPED':
3639 raise Warning("File type %s could not have reloc strip flag%d" % (Type
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3642 if self
._GetNextToken
():
3643 if TokenFindPattern
.match(self
._Token
):
3644 KeyStringList
.append(self
._Token
)
3645 if self
._IsToken
(TAB_COMMA_SPLIT
):
3646 while self
._GetNextToken
():
3647 if not TokenFindPattern
.match(self
._Token
):
3648 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
3649 KeyStringList
.append(self
._Token
)
3651 if not self
._IsToken
(TAB_COMMA_SPLIT
):
3659 if self
._IsKeyword
("Fixed", True):
3663 if self
._IsKeyword
("CheckSum", True):
3667 if self
._GetAlignment
():
3668 if self
._Token
not in ALIGNMENTS
:
3669 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3670 #For FFS, Auto is default option same to ""
3671 if not self
._Token
== "Auto":
3672 AlignValue
= self
._Token
3674 if self
._IsToken
("{"):
3675 # Complex file rule expected
3676 NewRule
= RuleComplexFile()
3677 NewRule
.FvFileType
= Type
3678 NewRule
.NameGuid
= NameGuid
3679 NewRule
.Alignment
= AlignValue
3680 NewRule
.CheckSum
= CheckSum
3681 NewRule
.Fixed
= Fixed
3682 NewRule
.KeyStringList
= KeyStringList
3683 if KeepReloc
is not None:
3684 NewRule
.KeepReloc
= KeepReloc
3687 IsEncapsulate
= self
._GetRuleEncapsulationSection
(NewRule
)
3688 IsLeaf
= self
._GetEfiSection
(NewRule
)
3689 if not IsEncapsulate
and not IsLeaf
:
3692 if not self
._IsToken
("}"):
3693 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3698 # Simple file rule expected
3699 if not self
._GetNextWord
():
3700 raise Warning.Expected("leaf section type", self
.FileName
, self
.CurrentLineNumber
)
3702 SectionName
= self
._Token
3704 if SectionName
not in {
3705 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3706 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3707 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3708 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3709 BINARY_FILE_TYPE_SMM_DEPEX
}:
3710 raise Warning("Unknown leaf section name '%s'" % SectionName
, self
.FileName
, self
.CurrentLineNumber
)
3713 if self
._IsKeyword
("Fixed", True):
3716 if self
._IsKeyword
("CheckSum", True):
3720 if self
._GetAlignment
():
3721 if self
._Token
not in ALIGNMENTS
:
3722 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3723 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3724 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3725 SectAlignment
= self
._Token
3728 if self
._IsToken
(TAB_VALUE_SPLIT
):
3729 Ext
= self
._GetFileExtension
()
3730 elif not self
._GetNextToken
():
3731 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
3733 NewRule
= RuleSimpleFile()
3734 NewRule
.SectionType
= SectionName
3735 NewRule
.FvFileType
= Type
3736 NewRule
.NameGuid
= NameGuid
3737 NewRule
.Alignment
= AlignValue
3738 NewRule
.SectAlignment
= SectAlignment
3739 NewRule
.CheckSum
= CheckSum
3740 NewRule
.Fixed
= Fixed
3741 NewRule
.KeyStringList
= KeyStringList
3742 if KeepReloc
is not None:
3743 NewRule
.KeepReloc
= KeepReloc
3744 NewRule
.FileExtension
= Ext
3745 NewRule
.FileName
= self
._Token
3748 ## _GetEfiSection() method
3750 # Get section list for Rule
3752 # @param self The object pointer
3753 # @param Obj for whom section is got
3754 # @retval True Successfully find section statement
3755 # @retval False Not able to find section statement
3757 def _GetEfiSection(self
, Obj
):
3758 OldPos
= self
.GetFileBufferPos()
3759 if not self
._GetNextWord
():
3761 SectionName
= self
._Token
3763 if SectionName
not in {
3764 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3765 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3766 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3767 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3768 BINARY_FILE_TYPE_SMM_DEPEX
, BINARY_FILE_TYPE_GUID
}:
3772 if SectionName
== "FV_IMAGE":
3773 FvImageSectionObj
= FvImageSection()
3774 if self
._IsKeyword
("FV_IMAGE"):
3776 if self
._IsToken
("{"):
3778 self
._GetDefineStatements
(FvObj
)
3779 self
._GetBlockStatement
(FvObj
)
3780 self
._GetSetStatements
(FvObj
)
3781 self
._GetFvAlignment
(FvObj
)
3782 self
._GetFvAttributes
(FvObj
)
3783 self
._GetAprioriSection
(FvObj
)
3784 self
._GetAprioriSection
(FvObj
)
3787 IsInf
= self
._GetInfStatement
(FvObj
)
3788 IsFile
= self
._GetFileStatement
(FvObj
)
3789 if not IsInf
and not IsFile
:
3792 if not self
._IsToken
("}"):
3793 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3794 FvImageSectionObj
.Fv
= FvObj
3795 FvImageSectionObj
.FvName
= None
3798 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3799 raise Warning.Expected("'FV'", self
.FileName
, self
.CurrentLineNumber
)
3800 FvImageSectionObj
.FvFileType
= self
._Token
3802 if self
._GetAlignment
():
3803 if self
._Token
not in ALIGNMENT_NOAUTO
:
3804 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3805 FvImageSectionObj
.Alignment
= self
._Token
3807 if self
._IsToken
(TAB_VALUE_SPLIT
):
3808 FvImageSectionObj
.FvFileExtension
= self
._GetFileExtension
()
3809 elif self
._GetNextToken
():
3810 if self
._Token
not in {
3811 "}", "COMPAT16", BINARY_FILE_TYPE_PE32
,
3812 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3813 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3814 BINARY_FILE_TYPE_UI
, "VERSION",
3815 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3816 BINARY_FILE_TYPE_SMM_DEPEX
}:
3817 FvImageSectionObj
.FvFileName
= self
._Token
3821 raise Warning.Expected("FV file name", self
.FileName
, self
.CurrentLineNumber
)
3823 Obj
.SectionList
.append(FvImageSectionObj
)
3826 EfiSectionObj
= EfiSection()
3827 EfiSectionObj
.SectionType
= SectionName
3829 if not self
._GetNextToken
():
3830 raise Warning.Expected("file type", self
.FileName
, self
.CurrentLineNumber
)
3832 if self
._Token
== "STRING":
3833 if not self
._RuleSectionCouldHaveString
(EfiSectionObj
.SectionType
):
3834 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3836 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3837 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3839 if not self
._GetNextToken
():
3840 raise Warning.Expected("Quoted String", self
.FileName
, self
.CurrentLineNumber
)
3842 if self
._GetStringData
():
3843 EfiSectionObj
.StringData
= self
._Token
3845 if self
._IsKeyword
("BUILD_NUM"):
3846 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3847 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3849 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3850 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3851 if not self
._GetNextToken
():
3852 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3853 EfiSectionObj
.BuildNum
= self
._Token
3856 EfiSectionObj
.FileType
= self
._Token
3857 self
._CheckRuleSectionFileType
(EfiSectionObj
.SectionType
, EfiSectionObj
.FileType
)
3859 if self
._IsKeyword
("Optional"):
3860 if not self
._RuleSectionCouldBeOptional
(EfiSectionObj
.SectionType
):
3861 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3862 EfiSectionObj
.Optional
= True
3864 if self
._IsKeyword
("BUILD_NUM"):
3865 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3866 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3868 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3869 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3870 if not self
._GetNextToken
():
3871 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3872 EfiSectionObj
.BuildNum
= self
._Token
3874 if self
._GetAlignment
():
3875 if self
._Token
not in ALIGNMENTS
:
3876 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3877 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3878 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3879 EfiSectionObj
.Alignment
= self
._Token
3881 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3882 if self
._SectionCouldHaveRelocFlag
(EfiSectionObj
.SectionType
):
3883 if self
._Token
== 'RELOCS_STRIPPED':
3884 EfiSectionObj
.KeepReloc
= False
3886 EfiSectionObj
.KeepReloc
= True
3887 if Obj
.KeepReloc
is not None and Obj
.KeepReloc
!= EfiSectionObj
.KeepReloc
:
3888 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3890 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3893 if self
._IsToken
(TAB_VALUE_SPLIT
):
3894 EfiSectionObj
.FileExtension
= self
._GetFileExtension
()
3895 elif self
._GetNextToken
():
3896 if self
._Token
not in {
3897 "}", "COMPAT16", BINARY_FILE_TYPE_PE32
,
3898 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3899 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3900 BINARY_FILE_TYPE_UI
, "VERSION",
3901 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3902 BINARY_FILE_TYPE_SMM_DEPEX
}:
3904 if self
._Token
.startswith('PCD'):
3908 if self
._Token
== 'PCD':
3909 if not self
._IsToken
("("):
3910 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3911 PcdPair
= self
._GetNextPcdSettings
()
3912 if not self
._IsToken
(")"):
3913 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3914 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3916 EfiSectionObj
.FileName
= self
._Token
3921 raise Warning.Expected("section file name", self
.FileName
, self
.CurrentLineNumber
)
3923 Obj
.SectionList
.append(EfiSectionObj
)
3926 ## _RuleSectionCouldBeOptional() method
3928 # Get whether a section could be optional
3930 # @param SectionType The section type to check
3931 # @retval True section could be optional
3932 # @retval False section never optional
3935 def _RuleSectionCouldBeOptional(SectionType
):
3936 if SectionType
in {BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "RAW", BINARY_FILE_TYPE_SMM_DEPEX
}:
3941 ## _RuleSectionCouldHaveBuildNum() method
3943 # Get whether a section could have build number information
3945 # @param SectionType The section type to check
3946 # @retval True section could have build number information
3947 # @retval False section never have build number information
3950 def _RuleSectionCouldHaveBuildNum(SectionType
):
3951 if SectionType
== "VERSION":
3956 ## _RuleSectionCouldHaveString() method
3958 # Get whether a section could have string
3960 # @param SectionType The section type to check
3961 # @retval True section could have string
3962 # @retval False section never have string
3965 def _RuleSectionCouldHaveString(SectionType
):
3966 if SectionType
in {BINARY_FILE_TYPE_UI
, "VERSION"}:
3971 ## _CheckRuleSectionFileType() method
3973 # Get whether a section matches a file type
3975 # @param self The object pointer
3976 # @param SectionType The section type to check
3977 # @param FileType The file type to check
3979 def _CheckRuleSectionFileType(self
, SectionType
, FileType
):
3980 WarningString
= "Incorrect section file type '%s'"
3981 if SectionType
== "COMPAT16":
3982 if FileType
not in {"COMPAT16", "SEC_COMPAT16"}:
3983 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3984 elif SectionType
== BINARY_FILE_TYPE_PE32
:
3985 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_PE32"}:
3986 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3987 elif SectionType
== BINARY_FILE_TYPE_PIC
:
3988 if FileType
not in {BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_PIC
}:
3989 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3990 elif SectionType
== BINARY_FILE_TYPE_TE
:
3991 if FileType
not in {BINARY_FILE_TYPE_TE
, "SEC_TE"}:
3992 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3993 elif SectionType
== "RAW":
3994 if FileType
not in {BINARY_FILE_TYPE_BIN
, "SEC_BIN", "RAW", "ASL", "ACPI"}:
3995 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3996 elif SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
or SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
3997 if FileType
not in {BINARY_FILE_TYPE_DXE_DEPEX
, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX
}:
3998 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3999 elif SectionType
== BINARY_FILE_TYPE_UI
:
4000 if FileType
not in {BINARY_FILE_TYPE_UI
, "SEC_UI"}:
4001 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4002 elif SectionType
== "VERSION":
4003 if FileType
not in {"VERSION", "SEC_VERSION"}:
4004 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4005 elif SectionType
== BINARY_FILE_TYPE_PEI_DEPEX
:
4006 if FileType
not in {BINARY_FILE_TYPE_PEI_DEPEX
, "SEC_PEI_DEPEX"}:
4007 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4008 elif SectionType
== BINARY_FILE_TYPE_GUID
:
4009 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_GUID"}:
4010 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4012 ## _GetRuleEncapsulationSection() method
4014 # Get encapsulation section for Rule
4016 # @param self The object pointer
4017 # @param theRule for whom section is got
4018 # @retval True Successfully find section statement
4019 # @retval False Not able to find section statement
4021 def _GetRuleEncapsulationSection(self
, theRule
):
4022 if self
._IsKeyword
("COMPRESS"):
4024 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
4027 if not self
._IsToken
("{"):
4028 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4030 CompressSectionObj
= CompressSection()
4032 CompressSectionObj
.CompType
= Type
4033 # Recursive sections...
4035 IsEncapsulate
= self
._GetRuleEncapsulationSection
(CompressSectionObj
)
4036 IsLeaf
= self
._GetEfiSection
(CompressSectionObj
)
4037 if not IsEncapsulate
and not IsLeaf
:
4040 if not self
._IsToken
("}"):
4041 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4042 theRule
.SectionList
.append(CompressSectionObj
)
4046 elif self
._IsKeyword
("GUIDED"):
4048 if self
._GetNextGuid
():
4049 GuidValue
= self
._Token
4051 if self
._IsKeyword
("$(NAMED_GUID)"):
4052 GuidValue
= self
._Token
4054 AttribDict
= self
._GetGuidAttrib
()
4056 if not self
._IsToken
("{"):
4057 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4058 GuidSectionObj
= GuidSection()
4059 GuidSectionObj
.NameGuid
= GuidValue
4060 GuidSectionObj
.SectionType
= "GUIDED"
4061 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
4062 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
4063 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
4067 IsEncapsulate
= self
._GetRuleEncapsulationSection
(GuidSectionObj
)
4068 IsLeaf
= self
._GetEfiSection
(GuidSectionObj
)
4069 if not IsEncapsulate
and not IsLeaf
:
4072 if not self
._IsToken
("}"):
4073 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4074 theRule
.SectionList
.append(GuidSectionObj
)
4082 # Get VTF section contents and store its data into VTF list of self.Profile
4084 # @param self The object pointer
4085 # @retval True Successfully find a VTF
4086 # @retval False Not able to find a VTF
4089 HW_ARCH_SET
= {TAB_ARCH_IA32
, TAB_ARCH_X64
, TAB_ARCH_IPF
, TAB_ARCH_ARM
, TAB_ARCH_AARCH64
}
4090 if not self
._GetNextToken
():
4093 S
= self
._Token
.upper()
4094 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[VTF."):
4095 self
.SectionParser(S
)
4100 if not self
._IsToken
("[VTF.", True):
4101 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4102 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
4103 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
4104 raise Warning.Expected("[VTF.]", self
.FileName
, self
.CurrentLineNumber
)
4106 if not self
._SkipToToken
(TAB_SPLIT
):
4107 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
4109 Arch
= self
._SkippedChars
.rstrip(TAB_SPLIT
).upper()
4110 if Arch
not in HW_ARCH_SET
:
4111 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
4113 if not self
._GetNextWord
():
4114 raise Warning.Expected("VTF name", self
.FileName
, self
.CurrentLineNumber
)
4115 Name
= self
._Token
.upper()
4118 VtfObj
.UiName
= Name
4119 VtfObj
.KeyArch
= Arch
4121 if self
._IsToken
(TAB_COMMA_SPLIT
):
4122 if not self
._GetNextWord
():
4123 raise Warning.Expected("Arch list", self
.FileName
, self
.CurrentLineNumber
)
4124 if self
._Token
.upper() not in HW_ARCH_SET
:
4125 raise Warning("Unknown Arch '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4126 VtfObj
.ArchList
= self
._Token
.upper()
4128 if not self
._IsToken
(TAB_SECTION_END
):
4129 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
4131 if self
._IsKeyword
("IA32_RST_BIN"):
4132 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4133 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4135 if not self
._GetNextToken
():
4136 raise Warning.Expected("Reset file", self
.FileName
, self
.CurrentLineNumber
)
4138 VtfObj
.ResetBin
= self
._Token
4139 if VtfObj
.ResetBin
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4140 #check for file path
4141 ErrorCode
, ErrorInfo
= PathClass(NormPath(VtfObj
.ResetBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4143 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4145 while self
._GetComponentStatement
(VtfObj
):
4148 self
.Profile
.VtfList
.append(VtfObj
)
4151 ## _GetComponentStatement() method
4153 # Get components in VTF
4155 # @param self The object pointer
4156 # @param VtfObj for whom component is got
4157 # @retval True Successfully find a component
4158 # @retval False Not able to find a component
4160 def _GetComponentStatement(self
, VtfObj
):
4161 if not self
._IsKeyword
("COMP_NAME"):
4164 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4165 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4167 if not self
._GetNextWord
():
4168 raise Warning.Expected("Component Name", self
.FileName
, self
.CurrentLineNumber
)
4170 CompStatementObj
= ComponentStatement()
4171 CompStatementObj
.CompName
= self
._Token
4173 if not self
._IsKeyword
("COMP_LOC"):
4174 raise Warning.Expected("COMP_LOC", self
.FileName
, self
.CurrentLineNumber
)
4176 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4177 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4179 CompStatementObj
.CompLoc
= ""
4180 if self
._GetNextWord
():
4181 CompStatementObj
.CompLoc
= self
._Token
4182 if self
._IsToken
(TAB_VALUE_SPLIT
):
4183 if not self
._GetNextWord
():
4184 raise Warning.Expected("Region Name", self
.FileName
, self
.CurrentLineNumber
)
4186 if self
._Token
not in {"F", "N", "S"}: #, "H", "L", "PH", "PL"): not support
4187 raise Warning("Unknown location type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4189 CompStatementObj
.FilePos
= self
._Token
4191 self
.CurrentLineNumber
+= 1
4192 self
.CurrentOffsetWithinLine
= 0
4194 if not self
._IsKeyword
("COMP_TYPE"):
4195 raise Warning.Expected("COMP_TYPE", self
.FileName
, self
.CurrentLineNumber
)
4197 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4198 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4200 if not self
._GetNextToken
():
4201 raise Warning.Expected("Component type", self
.FileName
, self
.CurrentLineNumber
)
4202 if self
._Token
not in {"FIT", "PAL_B", "PAL_A", "OEM"}:
4203 if not self
._Token
.startswith("0x") or len(self
._Token
) < 3 or len(self
._Token
) > 4 or \
4204 not self
._Token
[2] in hexdigits
or not self
._Token
[-1] in hexdigits
:
4205 raise Warning("Unknown location type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4206 CompStatementObj
.CompType
= self
._Token
4208 if not self
._IsKeyword
("COMP_VER"):
4209 raise Warning.Expected("COMP_VER", self
.FileName
, self
.CurrentLineNumber
)
4211 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4212 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4214 if not self
._GetNextToken
():
4215 raise Warning.Expected("Component version", self
.FileName
, self
.CurrentLineNumber
)
4217 Pattern
= compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', DOTALL
)
4218 if Pattern
.match(self
._Token
) is None:
4219 raise Warning("Unknown version format '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4220 CompStatementObj
.CompVer
= self
._Token
4222 if not self
._IsKeyword
("COMP_CS"):
4223 raise Warning.Expected("COMP_CS", self
.FileName
, self
.CurrentLineNumber
)
4225 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4226 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4228 if not self
._GetNextToken
():
4229 raise Warning.Expected("Component CS", self
.FileName
, self
.CurrentLineNumber
)
4230 if self
._Token
not in {"1", "0"}:
4231 raise Warning("Unknown Component CS '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4232 CompStatementObj
.CompCs
= self
._Token
4235 if not self
._IsKeyword
("COMP_BIN"):
4236 raise Warning.Expected("COMP_BIN", self
.FileName
, self
.CurrentLineNumber
)
4238 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4239 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4241 if not self
._GetNextToken
():
4242 raise Warning.Expected("Component file", self
.FileName
, self
.CurrentLineNumber
)
4244 CompStatementObj
.CompBin
= self
._Token
4245 if CompStatementObj
.CompBin
!= '-' and CompStatementObj
.CompBin
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4246 #check for file path
4247 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4249 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4251 if not self
._IsKeyword
("COMP_SYM"):
4252 raise Warning.Expected("COMP_SYM", self
.FileName
, self
.CurrentLineNumber
)
4254 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4255 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4257 if not self
._GetNextToken
():
4258 raise Warning.Expected("Component symbol file", self
.FileName
, self
.CurrentLineNumber
)
4260 CompStatementObj
.CompSym
= self
._Token
4261 if CompStatementObj
.CompSym
!= '-' and CompStatementObj
.CompSym
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4262 #check for file path
4263 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompSym
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4265 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4267 if not self
._IsKeyword
("COMP_SIZE"):
4268 raise Warning.Expected("COMP_SIZE", self
.FileName
, self
.CurrentLineNumber
)
4270 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4271 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4273 if self
._IsToken
("-"):
4274 CompStatementObj
.CompSize
= self
._Token
4275 elif self
._GetNextDecimalNumber
():
4276 CompStatementObj
.CompSize
= self
._Token
4277 elif self
._GetNextHexNumber
():
4278 CompStatementObj
.CompSize
= self
._Token
4280 raise Warning("Unknown size '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4282 VtfObj
.ComponentStatementList
.append(CompStatementObj
)
4285 ## _GetOptionRom() method
4287 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
4289 # @param self The object pointer
4290 # @retval True Successfully find a OptionROM
4291 # @retval False Not able to find a OptionROM
4293 def _GetOptionRom(self
):
4294 if not self
._GetNextToken
():
4297 S
= self
._Token
.upper()
4298 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[OPTIONROM."):
4299 self
.SectionParser(S
)
4304 if not self
._IsToken
("[OptionRom.", True):
4305 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4307 OptRomName
= self
._GetUiName
()
4309 if not self
._IsToken
(TAB_SECTION_END
):
4310 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
4312 OptRomObj
= OPTIONROM(OptRomName
)
4313 self
.Profile
.OptRomDict
[OptRomName
] = OptRomObj
4316 isInf
= self
._GetOptRomInfStatement
(OptRomObj
)
4317 isFile
= self
._GetOptRomFileStatement
(OptRomObj
)
4318 if not isInf
and not isFile
:
4323 ## _GetOptRomInfStatement() method
4325 # Get INF statements
4327 # @param self The object pointer
4328 # @param Obj for whom inf statement is got
4329 # @retval True Successfully find inf statement
4330 # @retval False Not able to find inf statement
4332 def _GetOptRomInfStatement(self
, Obj
):
4333 if not self
._IsKeyword
("INF"):
4336 ffsInf
= OptRomInfStatement()
4337 self
._GetInfOptions
(ffsInf
)
4339 if not self
._GetNextToken
():
4340 raise Warning.Expected("INF file path", self
.FileName
, self
.CurrentLineNumber
)
4341 ffsInf
.InfFileName
= self
._Token
4342 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4343 #check for file path
4344 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4346 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4348 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
4349 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
4350 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4351 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
4353 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
4354 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
4356 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
4358 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
4361 self
._GetOptRomOverrides
(ffsInf
)
4363 Obj
.FfsList
.append(ffsInf
)
4366 ## _GetOptRomOverrides() method
4368 # Get overrides for OptROM INF & FILE
4370 # @param self The object pointer
4371 # @param FfsInfObj for whom overrides is got
4373 def _GetOptRomOverrides(self
, Obj
):
4374 if self
._IsToken
('{'):
4375 Overrides
= OverrideAttribs()
4377 if self
._IsKeyword
("PCI_VENDOR_ID"):
4378 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4379 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4380 if not self
._GetNextHexNumber
():
4381 raise Warning.Expected("Hex vendor id", self
.FileName
, self
.CurrentLineNumber
)
4382 Overrides
.PciVendorId
= self
._Token
4385 if self
._IsKeyword
("PCI_CLASS_CODE"):
4386 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4387 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4388 if not self
._GetNextHexNumber
():
4389 raise Warning.Expected("Hex class code", self
.FileName
, self
.CurrentLineNumber
)
4390 Overrides
.PciClassCode
= self
._Token
4393 if self
._IsKeyword
("PCI_DEVICE_ID"):
4394 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4395 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4396 if not self
._GetNextHexNumber
():
4397 raise Warning.Expected("Hex device id", self
.FileName
, self
.CurrentLineNumber
)
4399 Overrides
.PciDeviceId
= self
._Token
4402 if self
._IsKeyword
("PCI_REVISION"):
4403 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4404 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4405 if not self
._GetNextHexNumber
():
4406 raise Warning.Expected("Hex revision", self
.FileName
, self
.CurrentLineNumber
)
4407 Overrides
.PciRevision
= self
._Token
4410 if self
._IsKeyword
("PCI_COMPRESS"):
4411 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4412 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4413 if not self
._GetNextToken
():
4414 raise Warning.Expected("TRUE/FALSE for compress", self
.FileName
, self
.CurrentLineNumber
)
4415 Overrides
.NeedCompress
= self
._Token
.upper() == 'TRUE'
4418 if self
._IsToken
("}"):
4421 EdkLogger
.error("FdfParser", FORMAT_INVALID
, File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
4423 Obj
.OverrideAttribs
= Overrides
4425 ## _GetOptRomFileStatement() method
4427 # Get FILE statements
4429 # @param self The object pointer
4430 # @param Obj for whom FILE statement is got
4431 # @retval True Successfully find FILE statement
4432 # @retval False Not able to find FILE statement
4434 def _GetOptRomFileStatement(self
, Obj
):
4435 if not self
._IsKeyword
("FILE"):
4438 FfsFileObj
= OptRomFileStatement()
4440 if not self
._IsKeyword
("EFI") and not self
._IsKeyword
(BINARY_FILE_TYPE_BIN
):
4441 raise Warning.Expected("Binary type (EFI/BIN)", self
.FileName
, self
.CurrentLineNumber
)
4442 FfsFileObj
.FileType
= self
._Token
4444 if not self
._GetNextToken
():
4445 raise Warning.Expected("File path", self
.FileName
, self
.CurrentLineNumber
)
4446 FfsFileObj
.FileName
= self
._Token
4447 if FfsFileObj
.FileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4448 #check for file path
4449 ErrorCode
, ErrorInfo
= PathClass(NormPath(FfsFileObj
.FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4451 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4453 if FfsFileObj
.FileType
== 'EFI':
4454 self
._GetOptRomOverrides
(FfsFileObj
)
4456 Obj
.FfsList
.append(FfsFileObj
)
4460 ## _GetCapInFd() method
4462 # Get Cap list contained in FD
4464 # @param self The object pointer
4465 # @param FdName FD name
4466 # @retval CapList List of Capsule in FD
4468 def _GetCapInFd (self
, FdName
):
4470 if FdName
.upper() in self
.Profile
.FdDict
:
4471 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4472 for elementRegion
in FdObj
.RegionList
:
4473 if elementRegion
.RegionType
== 'CAPSULE':
4474 for elementRegionData
in elementRegion
.RegionDataList
:
4475 if elementRegionData
.endswith(".cap"):
4477 if elementRegionData
is not None and elementRegionData
.upper() not in CapList
:
4478 CapList
.append(elementRegionData
.upper())
4481 ## _GetReferencedFdCapTuple() method
4483 # Get FV and FD list referenced by a capsule image
4485 # @param self The object pointer
4486 # @param CapObj Capsule section to be searched
4487 # @param RefFdList referenced FD by section
4488 # @param RefFvList referenced FV by section
4490 def _GetReferencedFdCapTuple(self
, CapObj
, RefFdList
= [], RefFvList
= []):
4491 for CapsuleDataObj
in CapObj
.CapsuleDataList
:
4492 if hasattr(CapsuleDataObj
, 'FvName') and CapsuleDataObj
.FvName
is not None and CapsuleDataObj
.FvName
.upper() not in RefFvList
:
4493 RefFvList
.append (CapsuleDataObj
.FvName
.upper())
4494 elif hasattr(CapsuleDataObj
, 'FdName') and CapsuleDataObj
.FdName
is not None and CapsuleDataObj
.FdName
.upper() not in RefFdList
:
4495 RefFdList
.append (CapsuleDataObj
.FdName
.upper())
4496 elif CapsuleDataObj
.Ffs
is not None:
4497 if isinstance(CapsuleDataObj
.Ffs
, FileStatement
):
4498 if CapsuleDataObj
.Ffs
.FvName
is not None and CapsuleDataObj
.Ffs
.FvName
.upper() not in RefFvList
:
4499 RefFvList
.append(CapsuleDataObj
.Ffs
.FvName
.upper())
4500 elif CapsuleDataObj
.Ffs
.FdName
is not None and CapsuleDataObj
.Ffs
.FdName
.upper() not in RefFdList
:
4501 RefFdList
.append(CapsuleDataObj
.Ffs
.FdName
.upper())
4503 self
._GetReferencedFdFvTupleFromSection
(CapsuleDataObj
.Ffs
, RefFdList
, RefFvList
)
4505 ## _GetFvInFd() method
4507 # Get FV list contained in FD
4509 # @param self The object pointer
4510 # @param FdName FD name
4511 # @retval FvList list of FV in FD
4513 def _GetFvInFd (self
, FdName
):
4515 if FdName
.upper() in self
.Profile
.FdDict
:
4516 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4517 for elementRegion
in FdObj
.RegionList
:
4518 if elementRegion
.RegionType
== BINARY_FILE_TYPE_FV
:
4519 for elementRegionData
in elementRegion
.RegionDataList
:
4520 if elementRegionData
.endswith(".fv"):
4522 if elementRegionData
is not None and elementRegionData
.upper() not in FvList
:
4523 FvList
.append(elementRegionData
.upper())
4526 ## _GetReferencedFdFvTuple() method
4528 # Get FD and FV list referenced by a FFS file
4530 # @param self The object pointer
4531 # @param FfsFile contains sections to be searched
4532 # @param RefFdList referenced FD by section
4533 # @param RefFvList referenced FV by section
4535 def _GetReferencedFdFvTuple(self
, FvObj
, RefFdList
= [], RefFvList
= []):
4536 for FfsObj
in FvObj
.FfsList
:
4537 if isinstance(FfsObj
, FileStatement
):
4538 if FfsObj
.FvName
is not None and FfsObj
.FvName
.upper() not in RefFvList
:
4539 RefFvList
.append(FfsObj
.FvName
.upper())
4540 elif FfsObj
.FdName
is not None and FfsObj
.FdName
.upper() not in RefFdList
:
4541 RefFdList
.append(FfsObj
.FdName
.upper())
4543 self
._GetReferencedFdFvTupleFromSection
(FfsObj
, RefFdList
, RefFvList
)
4545 ## _GetReferencedFdFvTupleFromSection() method
4547 # Get FD and FV list referenced by a FFS section
4549 # @param self The object pointer
4550 # @param FfsFile contains sections to be searched
4551 # @param FdList referenced FD by section
4552 # @param FvList referenced FV by section
4554 def _GetReferencedFdFvTupleFromSection(self
, FfsFile
, FdList
= [], FvList
= []):
4555 SectionStack
= list(FfsFile
.SectionList
)
4556 while SectionStack
!= []:
4557 SectionObj
= SectionStack
.pop()
4558 if isinstance(SectionObj
, FvImageSection
):
4559 if SectionObj
.FvName
is not None and SectionObj
.FvName
.upper() not in FvList
:
4560 FvList
.append(SectionObj
.FvName
.upper())
4561 if SectionObj
.Fv
is not None and SectionObj
.Fv
.UiFvName
is not None and SectionObj
.Fv
.UiFvName
.upper() not in FvList
:
4562 FvList
.append(SectionObj
.Fv
.UiFvName
.upper())
4563 self
._GetReferencedFdFvTuple
(SectionObj
.Fv
, FdList
, FvList
)
4565 if isinstance(SectionObj
, CompressSection
) or isinstance(SectionObj
, GuidSection
):
4566 SectionStack
.extend(SectionObj
.SectionList
)
4568 ## CycleReferenceCheck() method
4570 # Check whether cycle reference exists in FDF
4572 # @param self The object pointer
4573 # @retval True cycle reference exists
4574 # @retval False Not exists cycle reference
4576 def CycleReferenceCheck(self
):
4578 # Check the cycle between FV and FD image
4580 MaxLength
= len (self
.Profile
.FvDict
)
4581 for FvName
in self
.Profile
.FvDict
:
4582 LogStr
= "\nCycle Reference Checking for FV: %s\n" % FvName
4583 RefFvStack
= set(FvName
)
4584 FdAnalyzedList
= set()
4587 while RefFvStack
and Index
< MaxLength
:
4589 FvNameFromStack
= RefFvStack
.pop()
4590 if FvNameFromStack
.upper() in self
.Profile
.FvDict
:
4591 FvObj
= self
.Profile
.FvDict
[FvNameFromStack
.upper()]
4597 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4599 for RefFdName
in RefFdList
:
4600 if RefFdName
in FdAnalyzedList
:
4603 LogStr
+= "FV %s contains FD %s\n" % (FvNameFromStack
, RefFdName
)
4604 FvInFdList
= self
._GetFvInFd
(RefFdName
)
4605 if FvInFdList
!= []:
4606 for FvNameInFd
in FvInFdList
:
4607 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4608 if FvNameInFd
not in RefFvStack
:
4609 RefFvStack
.add(FvNameInFd
)
4611 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4612 EdkLogger
.info(LogStr
)
4614 FdAnalyzedList
.add(RefFdName
)
4616 for RefFvName
in RefFvList
:
4617 LogStr
+= "FV %s contains FV %s\n" % (FvNameFromStack
, RefFvName
)
4618 if RefFvName
not in RefFvStack
:
4619 RefFvStack
.add(RefFvName
)
4621 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4622 EdkLogger
.info(LogStr
)
4626 # Check the cycle between Capsule and FD image
4628 MaxLength
= len (self
.Profile
.CapsuleDict
)
4629 for CapName
in self
.Profile
.CapsuleDict
:
4631 # Capsule image to be checked.
4633 LogStr
= "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4634 RefCapStack
= {CapName}
4635 FdAnalyzedList
= set()
4636 FvAnalyzedList
= set()
4639 while RefCapStack
and Index
< MaxLength
:
4641 CapNameFromStack
= RefCapStack
.pop()
4642 if CapNameFromStack
.upper() in self
.Profile
.CapsuleDict
:
4643 CapObj
= self
.Profile
.CapsuleDict
[CapNameFromStack
.upper()]
4649 self
._GetReferencedFdCapTuple
(CapObj
, RefFdList
, RefFvList
)
4653 while FvListLength
< len (RefFvList
) or FdListLength
< len (RefFdList
):
4654 for RefFdName
in RefFdList
:
4655 if RefFdName
in FdAnalyzedList
:
4658 LogStr
+= "Capsule %s contains FD %s\n" % (CapNameFromStack
, RefFdName
)
4659 for CapNameInFd
in self
._GetCapInFd
(RefFdName
):
4660 LogStr
+= "FD %s contains Capsule %s\n" % (RefFdName
, CapNameInFd
)
4661 if CapNameInFd
not in RefCapStack
:
4662 RefCapStack
.append(CapNameInFd
)
4664 if CapName
in RefCapStack
or CapNameFromStack
in RefCapStack
:
4665 EdkLogger
.info(LogStr
)
4668 for FvNameInFd
in self
._GetFvInFd
(RefFdName
):
4669 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4670 if FvNameInFd
not in RefFvList
:
4671 RefFvList
.append(FvNameInFd
)
4673 FdAnalyzedList
.add(RefFdName
)
4675 # the number of the parsed FV and FD image
4677 FvListLength
= len (RefFvList
)
4678 FdListLength
= len (RefFdList
)
4679 for RefFvName
in RefFvList
:
4680 if RefFvName
in FvAnalyzedList
:
4682 LogStr
+= "Capsule %s contains FV %s\n" % (CapNameFromStack
, RefFvName
)
4683 if RefFvName
.upper() in self
.Profile
.FvDict
:
4684 FvObj
= self
.Profile
.FvDict
[RefFvName
.upper()]
4687 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4688 FvAnalyzedList
.add(RefFvName
)
4692 def GetAllIncludedFile (self
):
4693 global AllIncludeFileList
4694 return AllIncludeFileList
4696 if __name__
== "__main__":
4699 test_file
= sys
.argv
[1]
4700 except IndexError as v
:
4701 print("Usage: %s filename" % sys
.argv
[0])
4704 parser
= FdfParser(test_file
)
4707 parser
.CycleReferenceCheck()
4708 except Warning as X
: