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
, ProcessDuplicatedInf
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
, '{', T_CHAR_BRACE_R
}
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
() == TAB_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
() == TAB_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 GlobalData
.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 GlobalData
.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
(T_CHAR_BRACE_R
):
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
(T_CHAR_BRACE_R
):
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
(T_CHAR_BRACE_R
):
2334 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2336 if not self
._IsToken
(T_CHAR_BRACE_R
):
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
(T_CHAR_BRACE_R
):
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
(T_CHAR_BRACE_R
):
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 NewFileName
= ffsInf
.InfFileName
2419 if ffsInf
.OverrideGuid
:
2420 NewFileName
= ProcessDuplicatedInf(PathClass(ffsInf
.InfFileName
,GenFdsGlobalVariable
.WorkSpaceDir
), ffsInf
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
).Path
2422 if not NewFileName
in self
.Profile
.InfList
:
2423 self
.Profile
.InfList
.append(NewFileName
)
2424 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2425 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
2427 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
2428 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
2430 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
2432 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
2434 if self
._IsToken
(TAB_VALUE_SPLIT
):
2435 if self
._IsKeyword
('RELOCS_STRIPPED'):
2436 ffsInf
.KeepReloc
= False
2437 elif self
._IsKeyword
('RELOCS_RETAINED'):
2438 ffsInf
.KeepReloc
= True
2440 raise Warning("Unknown reloc strip flag '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2443 ## _GetInfStatement() method
2445 # Get INF statements
2447 # @param self The object pointer
2448 # @param Obj for whom inf statement is got
2449 # @retval True Successfully find inf statement
2450 # @retval False Not able to find inf statement
2452 def _GetInfStatement(self
, Obj
, ForCapsule
=False):
2453 ffsInf
= self
._ParseInfStatement
()
2458 myCapsuleFfs
= CapsuleFfs()
2459 myCapsuleFfs
.Ffs
= ffsInf
2460 Obj
.CapsuleDataList
.append(myCapsuleFfs
)
2462 Obj
.FfsList
.append(ffsInf
)
2465 ## _GetInfOptions() method
2467 # Get options for INF
2469 # @param self The object pointer
2470 # @param FfsInfObj for whom option is got
2472 def _GetInfOptions(self
, FfsInfObj
):
2473 if self
._IsKeyword
("FILE_GUID"):
2474 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2475 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2476 if not self
._GetNextGuid
():
2477 raise Warning.Expected("GUID value", self
.FileName
, self
.CurrentLineNumber
)
2478 FfsInfObj
.OverrideGuid
= self
._Token
2480 if self
._IsKeyword
("RuleOverride"):
2481 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2482 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2483 if not self
._GetNextToken
():
2484 raise Warning.Expected("Rule name", self
.FileName
, self
.CurrentLineNumber
)
2485 FfsInfObj
.Rule
= self
._Token
2487 if self
._IsKeyword
("VERSION"):
2488 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2489 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2490 if not self
._GetNextToken
():
2491 raise Warning.Expected("Version", self
.FileName
, self
.CurrentLineNumber
)
2493 if self
._GetStringData
():
2494 FfsInfObj
.Version
= self
._Token
2496 if self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2497 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2498 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2499 if not self
._GetNextToken
():
2500 raise Warning.Expected("UI name", self
.FileName
, self
.CurrentLineNumber
)
2502 if self
._GetStringData
():
2503 FfsInfObj
.Ui
= self
._Token
2505 if self
._IsKeyword
("USE"):
2506 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2507 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2508 if not self
._GetNextToken
():
2509 raise Warning.Expected("ARCH name", self
.FileName
, self
.CurrentLineNumber
)
2510 FfsInfObj
.UseArch
= self
._Token
2513 if self
._GetNextToken
():
2514 p
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2515 if p
.match(self
._Token
) and p
.match(self
._Token
).span()[1] == len(self
._Token
):
2516 FfsInfObj
.KeyStringList
.append(self
._Token
)
2517 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2523 while self
._GetNextToken
():
2524 if not p
.match(self
._Token
):
2525 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2526 FfsInfObj
.KeyStringList
.append(self
._Token
)
2528 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2531 ## _GetFileStatement() method
2533 # Get FILE statements
2535 # @param self The object pointer
2536 # @param Obj for whom FILE statement is got
2537 # @retval True Successfully find FILE statement
2538 # @retval False Not able to find FILE statement
2540 def _GetFileStatement(self
, Obj
, ForCapsule
= False):
2541 if not self
._IsKeyword
("FILE"):
2544 if not self
._GetNextWord
():
2545 raise Warning.Expected("FFS type", self
.FileName
, self
.CurrentLineNumber
)
2547 if ForCapsule
and self
._Token
== 'DATA':
2552 FfsFileObj
= FileStatement()
2553 FfsFileObj
.FvFileType
= self
._Token
2555 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2556 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2558 if not self
._GetNextGuid
():
2559 if not self
._GetNextWord
():
2560 raise Warning.Expected("File GUID", self
.FileName
, self
.CurrentLineNumber
)
2561 if self
._Token
== 'PCD':
2562 if not self
._IsToken
("("):
2563 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
2564 PcdPair
= self
._GetNextPcdSettings
()
2565 if not self
._IsToken
(")"):
2566 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
2567 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
2569 FfsFileObj
.NameGuid
= self
._Token
2571 self
._GetFilePart
(FfsFileObj
)
2574 capsuleFfs
= CapsuleFfs()
2575 capsuleFfs
.Ffs
= FfsFileObj
2576 Obj
.CapsuleDataList
.append(capsuleFfs
)
2578 Obj
.FfsList
.append(FfsFileObj
)
2582 ## _FileCouldHaveRelocFlag() method
2584 # Check whether reloc strip flag can be set for a file type.
2586 # @param FileType The file type to check with
2587 # @retval True This type could have relocation strip flag
2588 # @retval False No way to have it
2591 def _FileCouldHaveRelocFlag (FileType
):
2592 if FileType
in {SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
, SUP_MODULE_MM_CORE_STANDALONE
, 'PEI_DXE_COMBO'}:
2597 ## _SectionCouldHaveRelocFlag() method
2599 # Check whether reloc strip flag can be set for a section type.
2601 # @param SectionType The section type to check with
2602 # @retval True This type could have relocation strip flag
2603 # @retval False No way to have it
2606 def _SectionCouldHaveRelocFlag (SectionType
):
2607 if SectionType
in {BINARY_FILE_TYPE_TE
, BINARY_FILE_TYPE_PE32
}:
2612 ## _GetFilePart() method
2614 # Get components for FILE statement
2616 # @param self The object pointer
2617 # @param FfsFileObj for whom component is got
2619 def _GetFilePart(self
, FfsFileObj
):
2620 self
._GetFileOpts
(FfsFileObj
)
2622 if not self
._IsToken
("{"):
2623 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2624 if self
._FileCouldHaveRelocFlag
(FfsFileObj
.FvFileType
):
2625 if self
._Token
== 'RELOCS_STRIPPED':
2626 FfsFileObj
.KeepReloc
= False
2628 FfsFileObj
.KeepReloc
= True
2630 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj
.FvFileType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
2632 if not self
._IsToken
("{"):
2633 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2635 if not self
._GetNextToken
():
2636 raise Warning.Expected("File name or section data", self
.FileName
, self
.CurrentLineNumber
)
2638 if self
._Token
== BINARY_FILE_TYPE_FV
:
2639 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2640 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2641 if not self
._GetNextToken
():
2642 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
2643 FfsFileObj
.FvName
= self
._Token
2645 elif self
._Token
== "FD":
2646 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2647 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2648 if not self
._GetNextToken
():
2649 raise Warning.Expected("FD name", self
.FileName
, self
.CurrentLineNumber
)
2650 FfsFileObj
.FdName
= self
._Token
2652 elif self
._Token
in {TAB_DEFINE
, "APRIORI", "SECTION"}:
2654 self
._GetSectionData
(FfsFileObj
)
2656 elif hasattr(FfsFileObj
, 'FvFileType') and FfsFileObj
.FvFileType
== 'RAW':
2658 self
._GetRAWData
(FfsFileObj
)
2661 FfsFileObj
.CurrentLineNum
= self
.CurrentLineNumber
2662 FfsFileObj
.CurrentLineContent
= self
._CurrentLine
()
2663 FfsFileObj
.FileName
= self
._Token
.replace('$(SPACE)', ' ')
2664 self
._VerifyFile
(FfsFileObj
.FileName
)
2666 if not self
._IsToken
(T_CHAR_BRACE_R
):
2667 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2669 ## _GetRAWData() method
2671 # Get RAW data for FILE statement
2673 # @param self The object pointer
2674 # @param FfsFileObj for whom section is got
2676 def _GetRAWData(self
, FfsFileObj
):
2677 FfsFileObj
.FileName
= []
2678 FfsFileObj
.SubAlignment
= []
2681 if self
._GetAlignment
():
2682 if self
._Token
not in ALIGNMENTS
:
2683 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2684 #For FFS, Auto is default option same to ""
2685 if not self
._Token
== "Auto":
2686 AlignValue
= self
._Token
2687 if not self
._GetNextToken
():
2688 raise Warning.Expected("Filename value", self
.FileName
, self
.CurrentLineNumber
)
2690 FileName
= self
._Token
.replace('$(SPACE)', ' ')
2691 if FileName
== T_CHAR_BRACE_R
:
2693 raise Warning.Expected("Filename value", self
.FileName
, self
.CurrentLineNumber
)
2695 self
._VerifyFile
(FileName
)
2696 File
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
)
2697 FfsFileObj
.FileName
.append(File
.Path
)
2698 FfsFileObj
.SubAlignment
.append(AlignValue
)
2700 if self
._IsToken
(T_CHAR_BRACE_R
):
2704 if len(FfsFileObj
.SubAlignment
) == 1:
2705 FfsFileObj
.SubAlignment
= FfsFileObj
.SubAlignment
[0]
2706 if len(FfsFileObj
.FileName
) == 1:
2707 FfsFileObj
.FileName
= FfsFileObj
.FileName
[0]
2709 ## _GetFileOpts() method
2711 # Get options for FILE statement
2713 # @param self The object pointer
2714 # @param FfsFileObj for whom options is got
2716 def _GetFileOpts(self
, FfsFileObj
):
2717 if self
._GetNextToken
():
2718 if TokenFindPattern
.match(self
._Token
):
2719 FfsFileObj
.KeyStringList
.append(self
._Token
)
2720 if self
._IsToken
(TAB_COMMA_SPLIT
):
2721 while self
._GetNextToken
():
2722 if not TokenFindPattern
.match(self
._Token
):
2723 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2724 FfsFileObj
.KeyStringList
.append(self
._Token
)
2726 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2732 if self
._IsKeyword
("FIXED", True):
2733 FfsFileObj
.Fixed
= True
2735 if self
._IsKeyword
("CHECKSUM", True):
2736 FfsFileObj
.CheckSum
= True
2738 if self
._GetAlignment
():
2739 if self
._Token
not in ALIGNMENTS
:
2740 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2741 #For FFS, Auto is default option same to ""
2742 if not self
._Token
== "Auto":
2743 FfsFileObj
.Alignment
= self
._Token
2745 ## _GetAlignment() method
2747 # Return the alignment value
2749 # @param self The object pointer
2750 # @retval True Successfully find alignment
2751 # @retval False Not able to find alignment
2753 def _GetAlignment(self
):
2754 if self
._IsKeyword
("Align", True):
2755 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2756 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2758 if not self
._GetNextToken
():
2759 raise Warning.Expected("alignment value", self
.FileName
, self
.CurrentLineNumber
)
2764 ## _GetSectionData() method
2766 # Get section data for FILE statement
2768 # @param self The object pointer
2769 # @param FfsFileObj for whom section is got
2771 def _GetSectionData(self
, FfsFileObj
):
2772 self
._GetDefineStatements
(FfsFileObj
)
2775 IsLeafSection
= self
._GetLeafSection
(FfsFileObj
)
2776 IsEncapSection
= self
._GetEncapsulationSec
(FfsFileObj
)
2777 if not IsLeafSection
and not IsEncapSection
:
2780 ## _GetLeafSection() method
2782 # Get leaf section for Obj
2784 # @param self The object pointer
2785 # @param Obj for whom leaf section is got
2786 # @retval True Successfully find section statement
2787 # @retval False Not able to find section statement
2789 def _GetLeafSection(self
, Obj
):
2790 OldPos
= self
.GetFileBufferPos()
2792 if not self
._IsKeyword
("SECTION"):
2793 if len(Obj
.SectionList
) == 0:
2794 raise Warning.Expected("SECTION", self
.FileName
, self
.CurrentLineNumber
)
2799 if self
._GetAlignment
():
2800 if self
._Token
not in ALIGNMENTS
:
2801 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2802 AlignValue
= self
._Token
2805 if self
._IsKeyword
("BUILD_NUM"):
2806 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2807 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2809 if not self
._GetNextToken
():
2810 raise Warning.Expected("Build number value", self
.FileName
, self
.CurrentLineNumber
)
2812 BuildNum
= self
._Token
2814 if self
._IsKeyword
("VERSION"):
2815 if AlignValue
== 'Auto':
2816 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2817 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2818 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2819 if not self
._GetNextToken
():
2820 raise Warning.Expected("version", self
.FileName
, self
.CurrentLineNumber
)
2821 VerSectionObj
= VerSection()
2822 VerSectionObj
.Alignment
= AlignValue
2823 VerSectionObj
.BuildNum
= BuildNum
2824 if self
._GetStringData
():
2825 VerSectionObj
.StringData
= self
._Token
2827 VerSectionObj
.FileName
= self
._Token
2828 Obj
.SectionList
.append(VerSectionObj
)
2830 elif self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2831 if AlignValue
== 'Auto':
2832 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2833 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2834 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2835 if not self
._GetNextToken
():
2836 raise Warning.Expected("UI", self
.FileName
, self
.CurrentLineNumber
)
2837 UiSectionObj
= UiSection()
2838 UiSectionObj
.Alignment
= AlignValue
2839 if self
._GetStringData
():
2840 UiSectionObj
.StringData
= self
._Token
2842 UiSectionObj
.FileName
= self
._Token
2843 Obj
.SectionList
.append(UiSectionObj
)
2845 elif self
._IsKeyword
("FV_IMAGE"):
2846 if AlignValue
== 'Auto':
2847 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2848 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2849 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2850 if not self
._GetNextToken
():
2851 raise Warning.Expected("FV name or FV file path", self
.FileName
, self
.CurrentLineNumber
)
2853 FvName
= self
._Token
2856 if self
._IsToken
("{"):
2858 FvObj
.UiFvName
= FvName
.upper()
2859 self
._GetDefineStatements
(FvObj
)
2861 self
._GetBlockStatement
(FvObj
)
2862 self
._GetSetStatements
(FvObj
)
2863 self
._GetFvAlignment
(FvObj
)
2864 self
._GetFvAttributes
(FvObj
)
2867 IsInf
= self
._GetInfStatement
(FvObj
)
2868 IsFile
= self
._GetFileStatement
(FvObj
)
2869 if not IsInf
and not IsFile
:
2872 if not self
._IsToken
(T_CHAR_BRACE_R
):
2873 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2875 FvImageSectionObj
= FvImageSection()
2876 FvImageSectionObj
.Alignment
= AlignValue
2877 if FvObj
is not None:
2878 FvImageSectionObj
.Fv
= FvObj
2879 FvImageSectionObj
.FvName
= None
2881 FvImageSectionObj
.FvName
= FvName
.upper()
2882 FvImageSectionObj
.FvFileName
= FvName
2884 Obj
.SectionList
.append(FvImageSectionObj
)
2886 elif self
._IsKeyword
("PEI_DEPEX_EXP") or self
._IsKeyword
("DXE_DEPEX_EXP") or self
._IsKeyword
("SMM_DEPEX_EXP"):
2887 if AlignValue
== 'Auto':
2888 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2889 DepexSectionObj
= DepexSection()
2890 DepexSectionObj
.Alignment
= AlignValue
2891 DepexSectionObj
.DepexType
= self
._Token
2893 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2894 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2895 if not self
._IsToken
("{"):
2896 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2897 if not self
._SkipToToken
(T_CHAR_BRACE_R
):
2898 raise Warning.Expected("Depex expression ending '}'", self
.FileName
, self
.CurrentLineNumber
)
2900 DepexSectionObj
.Expression
= self
._SkippedChars
.rstrip(T_CHAR_BRACE_R
)
2901 Obj
.SectionList
.append(DepexSectionObj
)
2904 if not self
._GetNextWord
():
2905 raise Warning.Expected("section type", self
.FileName
, self
.CurrentLineNumber
)
2907 # Encapsulation section appear, UndoToken and return
2908 if self
._Token
== "COMPRESS" or self
._Token
== "GUIDED":
2909 self
.SetFileBufferPos(OldPos
)
2912 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
,\
2913 BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX
}:
2914 raise Warning("Unknown section type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2915 if AlignValue
== 'Auto'and (not self
._Token
== BINARY_FILE_TYPE_PE32
) and (not self
._Token
== BINARY_FILE_TYPE_TE
):
2916 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2919 DataSectionObj
= DataSection()
2920 DataSectionObj
.Alignment
= AlignValue
2921 DataSectionObj
.SecType
= self
._Token
2923 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2924 if self
._FileCouldHaveRelocFlag
(Obj
.FvFileType
) and self
._SectionCouldHaveRelocFlag
(DataSectionObj
.SecType
):
2925 if self
._Token
== 'RELOCS_STRIPPED':
2926 DataSectionObj
.KeepReloc
= False
2928 DataSectionObj
.KeepReloc
= True
2930 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
)
2932 if self
._IsToken
(TAB_EQUAL_SPLIT
):
2933 if not self
._GetNextToken
():
2934 raise Warning.Expected("section file path", self
.FileName
, self
.CurrentLineNumber
)
2935 DataSectionObj
.SectFileName
= self
._Token
2936 self
._VerifyFile
(DataSectionObj
.SectFileName
)
2938 if not self
._GetCglSection
(DataSectionObj
):
2941 Obj
.SectionList
.append(DataSectionObj
)
2947 # Check if file exists or not:
2948 # If current phase if GenFds, the file must exist;
2949 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
2950 # @param FileName: File path to be verified.
2952 def _VerifyFile(self
, FileName
):
2953 if FileName
.replace(TAB_WORKSPACE
, '').find('$') != -1:
2955 if not GlobalData
.gAutoGenPhase
or not self
._GetMacroValue
(TAB_DSC_DEFINES_OUTPUT_DIRECTORY
) in FileName
:
2956 ErrorCode
, ErrorInfo
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2958 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2960 ## _GetCglSection() method
2962 # Get compressed or GUIDed section for Obj
2964 # @param self The object pointer
2965 # @param Obj for whom leaf section is got
2966 # @param AlignValue alignment value for complex section
2967 # @retval True Successfully find section statement
2968 # @retval False Not able to find section statement
2970 def _GetCglSection(self
, Obj
, AlignValue
= None):
2972 if self
._IsKeyword
("COMPRESS"):
2974 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
2977 if not self
._IsToken
("{"):
2978 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2980 CompressSectionObj
= CompressSection()
2981 CompressSectionObj
.Alignment
= AlignValue
2982 CompressSectionObj
.CompType
= type
2983 # Recursive sections...
2985 IsLeafSection
= self
._GetLeafSection
(CompressSectionObj
)
2986 IsEncapSection
= self
._GetEncapsulationSec
(CompressSectionObj
)
2987 if not IsLeafSection
and not IsEncapSection
:
2991 if not self
._IsToken
(T_CHAR_BRACE_R
):
2992 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2993 Obj
.SectionList
.append(CompressSectionObj
)
2996 elif self
._IsKeyword
("GUIDED"):
2998 if self
._GetNextGuid
():
2999 GuidValue
= self
._Token
3001 AttribDict
= self
._GetGuidAttrib
()
3002 if not self
._IsToken
("{"):
3003 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
3004 GuidSectionObj
= GuidSection()
3005 GuidSectionObj
.Alignment
= AlignValue
3006 GuidSectionObj
.NameGuid
= GuidValue
3007 GuidSectionObj
.SectionType
= "GUIDED"
3008 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
3009 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
3010 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
3011 # Recursive sections...
3013 IsLeafSection
= self
._GetLeafSection
(GuidSectionObj
)
3014 IsEncapSection
= self
._GetEncapsulationSec
(GuidSectionObj
)
3015 if not IsLeafSection
and not IsEncapSection
:
3018 if not self
._IsToken
(T_CHAR_BRACE_R
):
3019 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3020 Obj
.SectionList
.append(GuidSectionObj
)
3026 ## _GetGuidAttri() method
3028 # Get attributes for GUID section
3030 # @param self The object pointer
3031 # @retval AttribDict Dictionary of key-value pair of section attributes
3033 def _GetGuidAttrib(self
):
3035 AttribDict
["PROCESSING_REQUIRED"] = "NONE"
3036 AttribDict
["AUTH_STATUS_VALID"] = "NONE"
3037 AttribDict
["EXTRA_HEADER_SIZE"] = -1
3038 while self
._IsKeyword
("PROCESSING_REQUIRED") or self
._IsKeyword
("AUTH_STATUS_VALID") \
3039 or self
._IsKeyword
("EXTRA_HEADER_SIZE"):
3040 AttribKey
= self
._Token
3042 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3043 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3045 if not self
._GetNextToken
():
3046 raise Warning.Expected("TRUE(1)/FALSE(0)/Number", self
.FileName
, self
.CurrentLineNumber
)
3047 elif AttribKey
== "EXTRA_HEADER_SIZE":
3049 if self
._Token
[0:2].upper() == "0X":
3052 AttribDict
[AttribKey
] = int(self
._Token
, Base
)
3055 raise Warning.Expected("Number", self
.FileName
, self
.CurrentLineNumber
)
3056 elif self
._Token
.upper() not in {"TRUE", "FALSE", "1", "0"}:
3057 raise Warning.Expected("TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
3058 AttribDict
[AttribKey
] = self
._Token
3062 ## _GetEncapsulationSec() method
3064 # Get encapsulation section for FILE
3066 # @param self The object pointer
3067 # @param FfsFile for whom section is got
3068 # @retval True Successfully find section statement
3069 # @retval False Not able to find section statement
3071 def _GetEncapsulationSec(self
, FfsFileObj
):
3072 OldPos
= self
.GetFileBufferPos()
3073 if not self
._IsKeyword
("SECTION"):
3074 if len(FfsFileObj
.SectionList
) == 0:
3075 raise Warning.Expected("SECTION", self
.FileName
, self
.CurrentLineNumber
)
3080 if self
._GetAlignment
():
3081 if self
._Token
not in ALIGNMENT_NOAUTO
:
3082 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3083 AlignValue
= self
._Token
3085 if not self
._GetCglSection
(FfsFileObj
, AlignValue
):
3086 self
.SetFileBufferPos(OldPos
)
3092 if not self
._GetNextToken
():
3094 S
= self
._Token
.upper()
3095 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FMPPAYLOAD."):
3096 self
.SectionParser(S
)
3101 self
._SkipToToken
("[FMPPAYLOAD.", True)
3102 FmpUiName
= self
._GetUiName
().upper()
3103 if FmpUiName
in self
.Profile
.FmpPayloadDict
:
3104 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName
, self
.FileName
, self
.CurrentLineNumber
)
3106 FmpData
= CapsulePayload()
3107 FmpData
.UiName
= FmpUiName
3109 if not self
._IsToken
(TAB_SECTION_END
):
3110 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3112 if not self
._GetNextToken
():
3113 raise Warning("The FMP payload section is empty!", self
.FileName
, self
.CurrentLineNumber
)
3114 FmpKeyList
= ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']
3115 while self
._Token
in FmpKeyList
:
3117 FmpKeyList
.remove(Name
)
3118 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3119 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3120 if Name
== 'IMAGE_TYPE_ID':
3121 if not self
._GetNextGuid
():
3122 raise Warning.Expected("GUID value for IMAGE_TYPE_ID.", self
.FileName
, self
.CurrentLineNumber
)
3123 FmpData
.ImageTypeId
= self
._Token
3124 elif Name
== 'CERTIFICATE_GUID':
3125 if not self
._GetNextGuid
():
3126 raise Warning.Expected("GUID value for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3127 FmpData
.Certificate_Guid
= self
._Token
3128 if UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_RSA2048_SHA256_GUID
and UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_PKCS7_GUID
:
3129 raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3131 if not self
._GetNextToken
():
3132 raise Warning.Expected("value of %s" % Name
, self
.FileName
, self
.CurrentLineNumber
)
3134 if Name
== 'IMAGE_HEADER_INIT_VERSION':
3135 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3136 FmpData
.Version
= Value
3137 elif Name
== 'IMAGE_INDEX':
3138 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3139 FmpData
.ImageIndex
= Value
3140 elif Name
== 'HARDWARE_INSTANCE':
3141 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3142 FmpData
.HardwareInstance
= Value
3143 elif Name
== 'MONOTONIC_COUNT':
3144 if FdfParser
._Verify
(Name
, Value
, 'UINT64'):
3145 FmpData
.MonotonicCount
= Value
3146 if FmpData
.MonotonicCount
.upper().startswith('0X'):
3147 FmpData
.MonotonicCount
= (long)(FmpData
.MonotonicCount
, 16)
3149 FmpData
.MonotonicCount
= (long)(FmpData
.MonotonicCount
)
3150 if not self
._GetNextToken
():
3155 if (FmpData
.MonotonicCount
and not FmpData
.Certificate_Guid
) or (not FmpData
.MonotonicCount
and FmpData
.Certificate_Guid
):
3156 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")
3158 # Only the IMAGE_TYPE_ID is required item
3159 if FmpKeyList
and 'IMAGE_TYPE_ID' in FmpKeyList
:
3160 raise Warning("'IMAGE_TYPE_ID' in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3161 # get the Image file and Vendor code file
3162 self
._GetFMPCapsuleData
(FmpData
)
3163 if not FmpData
.ImageFile
:
3164 raise Warning("Missing image file in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3165 # check whether more than one Vendor code file
3166 if len(FmpData
.VendorCodeFile
) > 1:
3167 raise Warning("Vendor code file max of 1 per FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3168 self
.Profile
.FmpPayloadDict
[FmpUiName
] = FmpData
3171 ## _GetCapsule() method
3173 # Get capsule section contents and store its data into capsule list of self.Profile
3175 # @param self The object pointer
3176 # @retval True Successfully find a capsule
3177 # @retval False Not able to find a capsule
3179 def _GetCapsule(self
):
3180 if not self
._GetNextToken
():
3183 S
= self
._Token
.upper()
3184 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[CAPSULE."):
3185 self
.SectionParser(S
)
3190 if not self
._IsToken
("[CAPSULE.", True):
3191 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3192 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3193 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3194 raise Warning.Expected("[Capsule.]", self
.FileName
, self
.CurrentLineNumber
)
3196 CapsuleObj
= Capsule()
3198 CapsuleName
= self
._GetUiName
()
3200 raise Warning.Expected("capsule name", self
.FileName
, self
.CurrentLineNumber
)
3202 CapsuleObj
.UiCapsuleName
= CapsuleName
.upper()
3204 if not self
._IsToken
(TAB_SECTION_END
):
3205 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3207 if self
._IsKeyword
("CREATE_FILE"):
3208 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3209 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3211 if not self
._GetNextToken
():
3212 raise Warning.Expected("file name", self
.FileName
, self
.CurrentLineNumber
)
3214 CapsuleObj
.CreateFile
= self
._Token
3216 self
._GetCapsuleStatements
(CapsuleObj
)
3217 self
.Profile
.CapsuleDict
[CapsuleObj
.UiCapsuleName
] = CapsuleObj
3220 ## _GetCapsuleStatements() method
3222 # Get statements for capsule
3224 # @param self The object pointer
3225 # @param Obj for whom statements are got
3227 def _GetCapsuleStatements(self
, Obj
):
3228 self
._GetCapsuleTokens
(Obj
)
3229 self
._GetDefineStatements
(Obj
)
3230 self
._GetSetStatements
(Obj
)
3231 self
._GetCapsuleData
(Obj
)
3233 ## _GetCapsuleTokens() method
3235 # Get token statements for capsule
3237 # @param self The object pointer
3238 # @param Obj for whom token statements are got
3240 def _GetCapsuleTokens(self
, Obj
):
3241 if not self
._GetNextToken
():
3243 while self
._Token
in {"CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"}:
3244 Name
= self
._Token
.strip()
3245 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3246 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3247 if not self
._GetNextToken
():
3248 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
3249 if Name
== 'CAPSULE_FLAGS':
3250 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3251 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3252 Value
= self
._Token
.strip()
3253 while self
._IsToken
(TAB_COMMA_SPLIT
):
3254 Value
+= TAB_COMMA_SPLIT
3255 if not self
._GetNextToken
():
3256 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
3257 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3258 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3259 Value
+= self
._Token
.strip()
3260 elif Name
== 'OEM_CAPSULE_FLAGS':
3261 Value
= self
._Token
.strip()
3262 if not Value
.upper().startswith('0X'):
3263 raise Warning.Expected("hex value starting with 0x", self
.FileName
, self
.CurrentLineNumber
)
3265 Value
= int(Value
, 0)
3267 raise Warning.Expected("hex string failed to convert to value", self
.FileName
, self
.CurrentLineNumber
)
3268 if not 0x0000 <= Value
<= 0xFFFF:
3269 raise Warning.Expected("hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3270 Value
= self
._Token
.strip()
3272 Value
= self
._Token
.strip()
3273 Obj
.TokensDict
[Name
] = Value
3274 if not self
._GetNextToken
():
3278 ## _GetCapsuleData() method
3280 # Get capsule data for capsule
3282 # @param self The object pointer
3283 # @param Obj for whom capsule data are got
3285 def _GetCapsuleData(self
, Obj
):
3287 IsInf
= self
._GetInfStatement
(Obj
, True)
3288 IsFile
= self
._GetFileStatement
(Obj
, True)
3289 IsFv
= self
._GetFvStatement
(Obj
)
3290 IsFd
= self
._GetFdStatement
(Obj
)
3291 IsAnyFile
= self
._GetAnyFileStatement
(Obj
)
3292 IsAfile
= self
._GetAfileStatement
(Obj
)
3293 IsFmp
= self
._GetFmpStatement
(Obj
)
3294 if not (IsInf
or IsFile
or IsFv
or IsFd
or IsAnyFile
or IsAfile
or IsFmp
):
3297 ## _GetFMPCapsuleData() method
3299 # Get capsule data for FMP capsule
3301 # @param self The object pointer
3302 # @param Obj for whom capsule data are got
3304 def _GetFMPCapsuleData(self
, Obj
):
3306 IsFv
= self
._GetFvStatement
(Obj
, True)
3307 IsFd
= self
._GetFdStatement
(Obj
, True)
3308 IsAnyFile
= self
._GetAnyFileStatement
(Obj
, True)
3309 if not (IsFv
or IsFd
or IsAnyFile
):
3312 ## _GetFvStatement() method
3314 # Get FV for capsule
3316 # @param self The object pointer
3317 # @param CapsuleObj for whom FV is got
3318 # @retval True Successfully find a FV statement
3319 # @retval False Not able to find a FV statement
3321 def _GetFvStatement(self
, CapsuleObj
, FMPCapsule
= False):
3322 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3325 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3326 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3328 if not self
._GetNextToken
():
3329 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
3331 if self
._Token
.upper() not in self
.Profile
.FvDict
:
3332 raise Warning("FV name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3334 myCapsuleFv
= CapsuleFv()
3335 myCapsuleFv
.FvName
= self
._Token
3337 if not CapsuleObj
.ImageFile
:
3338 CapsuleObj
.ImageFile
.append(myCapsuleFv
)
3340 CapsuleObj
.VendorCodeFile
.append(myCapsuleFv
)
3342 CapsuleObj
.CapsuleDataList
.append(myCapsuleFv
)
3345 ## _GetFdStatement() method
3347 # Get FD for capsule
3349 # @param self The object pointer
3350 # @param CapsuleObj for whom FD is got
3351 # @retval True Successfully find a FD statement
3352 # @retval False Not able to find a FD statement
3354 def _GetFdStatement(self
, CapsuleObj
, FMPCapsule
= False):
3355 if not self
._IsKeyword
("FD"):
3358 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3359 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3361 if not self
._GetNextToken
():
3362 raise Warning.Expected("FD name", self
.FileName
, self
.CurrentLineNumber
)
3364 if self
._Token
.upper() not in self
.Profile
.FdDict
:
3365 raise Warning("FD name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3367 myCapsuleFd
= CapsuleFd()
3368 myCapsuleFd
.FdName
= self
._Token
3370 if not CapsuleObj
.ImageFile
:
3371 CapsuleObj
.ImageFile
.append(myCapsuleFd
)
3373 CapsuleObj
.VendorCodeFile
.append(myCapsuleFd
)
3375 CapsuleObj
.CapsuleDataList
.append(myCapsuleFd
)
3378 def _GetFmpStatement(self
, CapsuleObj
):
3379 if not self
._IsKeyword
("FMP_PAYLOAD"):
3380 if not self
._IsKeyword
("FMP"):
3383 if not self
._IsKeyword
("PAYLOAD"):
3387 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3388 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3390 if not self
._GetNextToken
():
3391 raise Warning.Expected("payload name after FMP_PAYLOAD =", self
.FileName
, self
.CurrentLineNumber
)
3392 Payload
= self
._Token
.upper()
3393 if Payload
not in self
.Profile
.FmpPayloadDict
:
3394 raise Warning("This FMP Payload does not exist: %s" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3395 CapsuleObj
.FmpPayloadList
.append(self
.Profile
.FmpPayloadDict
[Payload
])
3398 def _ParseRawFileStatement(self
):
3399 if not self
._IsKeyword
("FILE"):
3402 if not self
._IsKeyword
("DATA"):
3406 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3407 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3409 if not self
._GetNextToken
():
3410 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
3412 AnyFileName
= self
._Token
3413 self
._VerifyFile
(AnyFileName
)
3415 if not os
.path
.isabs(AnyFileName
):
3416 AnyFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, AnyFileName
)
3420 ## _GetAnyFileStatement() method
3422 # Get AnyFile for capsule
3424 # @param self The object pointer
3425 # @param CapsuleObj for whom AnyFile is got
3426 # @retval True Successfully find a Anyfile statement
3427 # @retval False Not able to find a AnyFile statement
3429 def _GetAnyFileStatement(self
, CapsuleObj
, FMPCapsule
= False):
3430 AnyFileName
= self
._ParseRawFileStatement
()
3434 myCapsuleAnyFile
= CapsuleAnyFile()
3435 myCapsuleAnyFile
.FileName
= AnyFileName
3437 if not CapsuleObj
.ImageFile
:
3438 CapsuleObj
.ImageFile
.append(myCapsuleAnyFile
)
3440 CapsuleObj
.VendorCodeFile
.append(myCapsuleAnyFile
)
3442 CapsuleObj
.CapsuleDataList
.append(myCapsuleAnyFile
)
3445 ## _GetAfileStatement() method
3447 # Get Afile for capsule
3449 # @param self The object pointer
3450 # @param CapsuleObj for whom Afile is got
3451 # @retval True Successfully find a Afile statement
3452 # @retval False Not able to find a Afile statement
3454 def _GetAfileStatement(self
, CapsuleObj
):
3455 if not self
._IsKeyword
("APPEND"):
3458 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3459 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3461 if not self
._GetNextToken
():
3462 raise Warning.Expected("Afile name", self
.FileName
, self
.CurrentLineNumber
)
3464 AfileName
= self
._Token
3465 AfileBaseName
= os
.path
.basename(AfileName
)
3467 if os
.path
.splitext(AfileBaseName
)[1] not in {".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"}:
3468 raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \
3469 self
.FileName
, self
.CurrentLineNumber
)
3471 if not os
.path
.isabs(AfileName
):
3472 AfileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(AfileName
)
3473 self
._VerifyFile
(AfileName
)
3475 if not os
.path
.exists(AfileName
):
3476 raise Warning('%s does not exist' % AfileName
, self
.FileName
, self
.CurrentLineNumber
)
3480 myCapsuleAfile
= CapsuleAfile()
3481 myCapsuleAfile
.FileName
= AfileName
3482 CapsuleObj
.CapsuleDataList
.append(myCapsuleAfile
)
3485 ## _GetRule() method
3487 # Get Rule section contents and store its data into rule list of self.Profile
3489 # @param self The object pointer
3490 # @retval True Successfully find a Rule
3491 # @retval False Not able to find a Rule
3494 if not self
._GetNextToken
():
3497 S
= self
._Token
.upper()
3498 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[RULE."):
3499 self
.SectionParser(S
)
3503 if not self
._IsToken
("[Rule.", True):
3504 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3505 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3506 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3507 raise Warning.Expected("[Rule.]", self
.FileName
, self
.CurrentLineNumber
)
3509 if not self
._SkipToToken
(TAB_SPLIT
):
3510 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
3512 Arch
= self
._SkippedChars
.rstrip(TAB_SPLIT
)
3513 if Arch
.upper() not in ARCH_SET_FULL
:
3514 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
3516 ModuleType
= self
._GetModuleType
()
3519 if self
._IsToken
(TAB_SPLIT
):
3520 if not self
._GetNextWord
():
3521 raise Warning.Expected("template name", self
.FileName
, self
.CurrentLineNumber
)
3522 TemplateName
= self
._Token
3524 if not self
._IsToken
(TAB_SECTION_END
):
3525 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3527 RuleObj
= self
._GetRuleFileStatements
()
3528 RuleObj
.Arch
= Arch
.upper()
3529 RuleObj
.ModuleType
= ModuleType
3530 RuleObj
.TemplateName
= TemplateName
3531 if TemplateName
== '':
3532 self
.Profile
.RuleDict
['RULE' + \
3536 ModuleType
.upper() ] = RuleObj
3538 self
.Profile
.RuleDict
['RULE' + \
3542 ModuleType
.upper() + \
3544 TemplateName
.upper() ] = RuleObj
3547 ## _GetModuleType() method
3549 # Return the module type
3551 # @param self The object pointer
3552 # @retval string module type
3554 def _GetModuleType(self
):
3555 if not self
._GetNextWord
():
3556 raise Warning.Expected("Module type", self
.FileName
, self
.CurrentLineNumber
)
3557 if self
._Token
.upper() not in {
3558 SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3559 SUP_MODULE_DXE_CORE
, SUP_MODULE_DXE_DRIVER
,
3560 SUP_MODULE_DXE_SAL_DRIVER
, SUP_MODULE_DXE_SMM_DRIVER
,
3561 SUP_MODULE_DXE_RUNTIME_DRIVER
, SUP_MODULE_UEFI_DRIVER
,
3562 SUP_MODULE_UEFI_APPLICATION
, SUP_MODULE_USER_DEFINED
,
3563 TAB_DEFAULT
, SUP_MODULE_BASE
,
3564 EDK_COMPONENT_TYPE_SECURITY_CORE
,
3565 EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER
,
3566 EDK_COMPONENT_TYPE_PIC_PEIM
,
3567 EDK_COMPONENT_TYPE_RELOCATABLE_PEIM
, "PE32_PEIM",
3568 EDK_COMPONENT_TYPE_BS_DRIVER
, EDK_COMPONENT_TYPE_RT_DRIVER
,
3569 EDK_COMPONENT_TYPE_SAL_RT_DRIVER
,
3570 EDK_COMPONENT_TYPE_APPLICATION
, "ACPITABLE",
3571 SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3572 SUP_MODULE_MM_CORE_STANDALONE
}:
3573 raise Warning("Unknown Module type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3576 ## _GetFileExtension() method
3578 # Return the file extension
3580 # @param self The object pointer
3581 # @retval string file name extension
3583 def _GetFileExtension(self
):
3584 if not self
._IsToken
(TAB_SPLIT
):
3585 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
3588 if self
._GetNextToken
():
3589 if FileExtensionPattern
.match(self
._Token
):
3591 return TAB_SPLIT
+ Ext
3593 raise Warning("Unknown file extension '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3596 raise Warning.Expected("file extension", self
.FileName
, self
.CurrentLineNumber
)
3598 ## _GetRuleFileStatement() method
3602 # @param self The object pointer
3603 # @retval Rule Rule object
3605 def _GetRuleFileStatements(self
):
3606 if not self
._IsKeyword
("FILE"):
3607 raise Warning.Expected("FILE", self
.FileName
, self
.CurrentLineNumber
)
3609 if not self
._GetNextWord
():
3610 raise Warning.Expected("FFS type", self
.FileName
, self
.CurrentLineNumber
)
3612 Type
= self
._Token
.strip().upper()
3613 if Type
not in {"RAW", "FREEFORM", SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3614 "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE
, EDK_COMPONENT_TYPE_APPLICATION
,
3615 "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3616 SUP_MODULE_MM_CORE_STANDALONE
}:
3617 raise Warning("Unknown FV type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3619 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3620 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3622 if not self
._IsKeyword
("$(NAMED_GUID)"):
3623 if not self
._GetNextWord
():
3624 raise Warning.Expected("$(NAMED_GUID)", self
.FileName
, self
.CurrentLineNumber
)
3625 if self
._Token
== 'PCD':
3626 if not self
._IsToken
("("):
3627 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3628 PcdPair
= self
._GetNextPcdSettings
()
3629 if not self
._IsToken
(")"):
3630 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3631 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3633 NameGuid
= self
._Token
3636 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3637 if self
._FileCouldHaveRelocFlag
(Type
):
3638 if self
._Token
== 'RELOCS_STRIPPED':
3643 raise Warning("File type %s could not have reloc strip flag%d" % (Type
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3646 if self
._GetNextToken
():
3647 if TokenFindPattern
.match(self
._Token
):
3648 KeyStringList
.append(self
._Token
)
3649 if self
._IsToken
(TAB_COMMA_SPLIT
):
3650 while self
._GetNextToken
():
3651 if not TokenFindPattern
.match(self
._Token
):
3652 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
3653 KeyStringList
.append(self
._Token
)
3655 if not self
._IsToken
(TAB_COMMA_SPLIT
):
3663 if self
._IsKeyword
("Fixed", True):
3667 if self
._IsKeyword
("CheckSum", True):
3671 if self
._GetAlignment
():
3672 if self
._Token
not in ALIGNMENTS
:
3673 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3674 #For FFS, Auto is default option same to ""
3675 if not self
._Token
== "Auto":
3676 AlignValue
= self
._Token
3678 if self
._IsToken
("{"):
3679 # Complex file rule expected
3680 NewRule
= RuleComplexFile()
3681 NewRule
.FvFileType
= Type
3682 NewRule
.NameGuid
= NameGuid
3683 NewRule
.Alignment
= AlignValue
3684 NewRule
.CheckSum
= CheckSum
3685 NewRule
.Fixed
= Fixed
3686 NewRule
.KeyStringList
= KeyStringList
3687 if KeepReloc
is not None:
3688 NewRule
.KeepReloc
= KeepReloc
3691 IsEncapsulate
= self
._GetRuleEncapsulationSection
(NewRule
)
3692 IsLeaf
= self
._GetEfiSection
(NewRule
)
3693 if not IsEncapsulate
and not IsLeaf
:
3696 if not self
._IsToken
(T_CHAR_BRACE_R
):
3697 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3702 # Simple file rule expected
3703 if not self
._GetNextWord
():
3704 raise Warning.Expected("leaf section type", self
.FileName
, self
.CurrentLineNumber
)
3706 SectionName
= self
._Token
3708 if SectionName
not in {
3709 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3710 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3711 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3712 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3713 BINARY_FILE_TYPE_SMM_DEPEX
}:
3714 raise Warning("Unknown leaf section name '%s'" % SectionName
, self
.FileName
, self
.CurrentLineNumber
)
3717 if self
._IsKeyword
("Fixed", True):
3720 if self
._IsKeyword
("CheckSum", True):
3724 if self
._GetAlignment
():
3725 if self
._Token
not in ALIGNMENTS
:
3726 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3727 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3728 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3729 SectAlignment
= self
._Token
3732 if self
._IsToken
(TAB_VALUE_SPLIT
):
3733 Ext
= self
._GetFileExtension
()
3734 elif not self
._GetNextToken
():
3735 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
3737 NewRule
= RuleSimpleFile()
3738 NewRule
.SectionType
= SectionName
3739 NewRule
.FvFileType
= Type
3740 NewRule
.NameGuid
= NameGuid
3741 NewRule
.Alignment
= AlignValue
3742 NewRule
.SectAlignment
= SectAlignment
3743 NewRule
.CheckSum
= CheckSum
3744 NewRule
.Fixed
= Fixed
3745 NewRule
.KeyStringList
= KeyStringList
3746 if KeepReloc
is not None:
3747 NewRule
.KeepReloc
= KeepReloc
3748 NewRule
.FileExtension
= Ext
3749 NewRule
.FileName
= self
._Token
3752 ## _GetEfiSection() method
3754 # Get section list for Rule
3756 # @param self The object pointer
3757 # @param Obj for whom section is got
3758 # @retval True Successfully find section statement
3759 # @retval False Not able to find section statement
3761 def _GetEfiSection(self
, Obj
):
3762 OldPos
= self
.GetFileBufferPos()
3763 if not self
._GetNextWord
():
3765 SectionName
= self
._Token
3767 if SectionName
not in {
3768 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3769 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3770 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3771 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3772 BINARY_FILE_TYPE_SMM_DEPEX
, BINARY_FILE_TYPE_GUID
}:
3776 if SectionName
== "FV_IMAGE":
3777 FvImageSectionObj
= FvImageSection()
3778 if self
._IsKeyword
("FV_IMAGE"):
3780 if self
._IsToken
("{"):
3782 self
._GetDefineStatements
(FvObj
)
3783 self
._GetBlockStatement
(FvObj
)
3784 self
._GetSetStatements
(FvObj
)
3785 self
._GetFvAlignment
(FvObj
)
3786 self
._GetFvAttributes
(FvObj
)
3787 self
._GetAprioriSection
(FvObj
)
3788 self
._GetAprioriSection
(FvObj
)
3791 IsInf
= self
._GetInfStatement
(FvObj
)
3792 IsFile
= self
._GetFileStatement
(FvObj
)
3793 if not IsInf
and not IsFile
:
3796 if not self
._IsToken
(T_CHAR_BRACE_R
):
3797 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3798 FvImageSectionObj
.Fv
= FvObj
3799 FvImageSectionObj
.FvName
= None
3802 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3803 raise Warning.Expected("'FV'", self
.FileName
, self
.CurrentLineNumber
)
3804 FvImageSectionObj
.FvFileType
= self
._Token
3806 if self
._GetAlignment
():
3807 if self
._Token
not in ALIGNMENT_NOAUTO
:
3808 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3809 FvImageSectionObj
.Alignment
= self
._Token
3811 if self
._IsToken
(TAB_VALUE_SPLIT
):
3812 FvImageSectionObj
.FvFileExtension
= self
._GetFileExtension
()
3813 elif self
._GetNextToken
():
3814 if self
._Token
not in {
3815 T_CHAR_BRACE_R
, "COMPAT16", BINARY_FILE_TYPE_PE32
,
3816 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3817 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3818 BINARY_FILE_TYPE_UI
, "VERSION",
3819 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3820 BINARY_FILE_TYPE_SMM_DEPEX
}:
3821 FvImageSectionObj
.FvFileName
= self
._Token
3825 raise Warning.Expected("FV file name", self
.FileName
, self
.CurrentLineNumber
)
3827 Obj
.SectionList
.append(FvImageSectionObj
)
3830 EfiSectionObj
= EfiSection()
3831 EfiSectionObj
.SectionType
= SectionName
3833 if not self
._GetNextToken
():
3834 raise Warning.Expected("file type", self
.FileName
, self
.CurrentLineNumber
)
3836 if self
._Token
== "STRING":
3837 if not self
._RuleSectionCouldHaveString
(EfiSectionObj
.SectionType
):
3838 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3840 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3841 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3843 if not self
._GetNextToken
():
3844 raise Warning.Expected("Quoted String", self
.FileName
, self
.CurrentLineNumber
)
3846 if self
._GetStringData
():
3847 EfiSectionObj
.StringData
= self
._Token
3849 if self
._IsKeyword
("BUILD_NUM"):
3850 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3851 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3853 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3854 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3855 if not self
._GetNextToken
():
3856 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3857 EfiSectionObj
.BuildNum
= self
._Token
3860 EfiSectionObj
.FileType
= self
._Token
3861 self
._CheckRuleSectionFileType
(EfiSectionObj
.SectionType
, EfiSectionObj
.FileType
)
3863 if self
._IsKeyword
("Optional"):
3864 if not self
._RuleSectionCouldBeOptional
(EfiSectionObj
.SectionType
):
3865 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3866 EfiSectionObj
.Optional
= True
3868 if self
._IsKeyword
("BUILD_NUM"):
3869 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3870 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3872 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3873 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3874 if not self
._GetNextToken
():
3875 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3876 EfiSectionObj
.BuildNum
= self
._Token
3878 if self
._GetAlignment
():
3879 if self
._Token
not in ALIGNMENTS
:
3880 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3881 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3882 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3883 EfiSectionObj
.Alignment
= self
._Token
3885 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3886 if self
._SectionCouldHaveRelocFlag
(EfiSectionObj
.SectionType
):
3887 if self
._Token
== 'RELOCS_STRIPPED':
3888 EfiSectionObj
.KeepReloc
= False
3890 EfiSectionObj
.KeepReloc
= True
3891 if Obj
.KeepReloc
is not None and Obj
.KeepReloc
!= EfiSectionObj
.KeepReloc
:
3892 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3894 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3897 if self
._IsToken
(TAB_VALUE_SPLIT
):
3898 EfiSectionObj
.FileExtension
= self
._GetFileExtension
()
3899 elif self
._GetNextToken
():
3900 if self
._Token
not in {
3901 T_CHAR_BRACE_R
, "COMPAT16", BINARY_FILE_TYPE_PE32
,
3902 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3903 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3904 BINARY_FILE_TYPE_UI
, "VERSION",
3905 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3906 BINARY_FILE_TYPE_SMM_DEPEX
}:
3908 if self
._Token
.startswith('PCD'):
3912 if self
._Token
== 'PCD':
3913 if not self
._IsToken
("("):
3914 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3915 PcdPair
= self
._GetNextPcdSettings
()
3916 if not self
._IsToken
(")"):
3917 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3918 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3920 EfiSectionObj
.FileName
= self
._Token
3925 raise Warning.Expected("section file name", self
.FileName
, self
.CurrentLineNumber
)
3927 Obj
.SectionList
.append(EfiSectionObj
)
3930 ## _RuleSectionCouldBeOptional() method
3932 # Get whether a section could be optional
3934 # @param SectionType The section type to check
3935 # @retval True section could be optional
3936 # @retval False section never optional
3939 def _RuleSectionCouldBeOptional(SectionType
):
3940 if SectionType
in {BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "RAW", BINARY_FILE_TYPE_SMM_DEPEX
}:
3945 ## _RuleSectionCouldHaveBuildNum() method
3947 # Get whether a section could have build number information
3949 # @param SectionType The section type to check
3950 # @retval True section could have build number information
3951 # @retval False section never have build number information
3954 def _RuleSectionCouldHaveBuildNum(SectionType
):
3955 if SectionType
== "VERSION":
3960 ## _RuleSectionCouldHaveString() method
3962 # Get whether a section could have string
3964 # @param SectionType The section type to check
3965 # @retval True section could have string
3966 # @retval False section never have string
3969 def _RuleSectionCouldHaveString(SectionType
):
3970 if SectionType
in {BINARY_FILE_TYPE_UI
, "VERSION"}:
3975 ## _CheckRuleSectionFileType() method
3977 # Get whether a section matches a file type
3979 # @param self The object pointer
3980 # @param SectionType The section type to check
3981 # @param FileType The file type to check
3983 def _CheckRuleSectionFileType(self
, SectionType
, FileType
):
3984 WarningString
= "Incorrect section file type '%s'"
3985 if SectionType
== "COMPAT16":
3986 if FileType
not in {"COMPAT16", "SEC_COMPAT16"}:
3987 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3988 elif SectionType
== BINARY_FILE_TYPE_PE32
:
3989 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_PE32"}:
3990 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3991 elif SectionType
== BINARY_FILE_TYPE_PIC
:
3992 if FileType
not in {BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_PIC
}:
3993 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3994 elif SectionType
== BINARY_FILE_TYPE_TE
:
3995 if FileType
not in {BINARY_FILE_TYPE_TE
, "SEC_TE"}:
3996 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3997 elif SectionType
== "RAW":
3998 if FileType
not in {BINARY_FILE_TYPE_BIN
, "SEC_BIN", "RAW", "ASL", "ACPI"}:
3999 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4000 elif SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
or SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
4001 if FileType
not in {BINARY_FILE_TYPE_DXE_DEPEX
, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX
}:
4002 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4003 elif SectionType
== BINARY_FILE_TYPE_UI
:
4004 if FileType
not in {BINARY_FILE_TYPE_UI
, "SEC_UI"}:
4005 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4006 elif SectionType
== "VERSION":
4007 if FileType
not in {"VERSION", "SEC_VERSION"}:
4008 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4009 elif SectionType
== BINARY_FILE_TYPE_PEI_DEPEX
:
4010 if FileType
not in {BINARY_FILE_TYPE_PEI_DEPEX
, "SEC_PEI_DEPEX"}:
4011 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4012 elif SectionType
== BINARY_FILE_TYPE_GUID
:
4013 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_GUID"}:
4014 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4016 ## _GetRuleEncapsulationSection() method
4018 # Get encapsulation section for Rule
4020 # @param self The object pointer
4021 # @param theRule for whom section is got
4022 # @retval True Successfully find section statement
4023 # @retval False Not able to find section statement
4025 def _GetRuleEncapsulationSection(self
, theRule
):
4026 if self
._IsKeyword
("COMPRESS"):
4028 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
4031 if not self
._IsToken
("{"):
4032 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4034 CompressSectionObj
= CompressSection()
4036 CompressSectionObj
.CompType
= Type
4037 # Recursive sections...
4039 IsEncapsulate
= self
._GetRuleEncapsulationSection
(CompressSectionObj
)
4040 IsLeaf
= self
._GetEfiSection
(CompressSectionObj
)
4041 if not IsEncapsulate
and not IsLeaf
:
4044 if not self
._IsToken
(T_CHAR_BRACE_R
):
4045 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4046 theRule
.SectionList
.append(CompressSectionObj
)
4050 elif self
._IsKeyword
("GUIDED"):
4052 if self
._GetNextGuid
():
4053 GuidValue
= self
._Token
4055 if self
._IsKeyword
("$(NAMED_GUID)"):
4056 GuidValue
= self
._Token
4058 AttribDict
= self
._GetGuidAttrib
()
4060 if not self
._IsToken
("{"):
4061 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4062 GuidSectionObj
= GuidSection()
4063 GuidSectionObj
.NameGuid
= GuidValue
4064 GuidSectionObj
.SectionType
= "GUIDED"
4065 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
4066 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
4067 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
4071 IsEncapsulate
= self
._GetRuleEncapsulationSection
(GuidSectionObj
)
4072 IsLeaf
= self
._GetEfiSection
(GuidSectionObj
)
4073 if not IsEncapsulate
and not IsLeaf
:
4076 if not self
._IsToken
(T_CHAR_BRACE_R
):
4077 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4078 theRule
.SectionList
.append(GuidSectionObj
)
4086 # Get VTF section contents and store its data into VTF list of self.Profile
4088 # @param self The object pointer
4089 # @retval True Successfully find a VTF
4090 # @retval False Not able to find a VTF
4093 HW_ARCH_SET
= {TAB_ARCH_IA32
, TAB_ARCH_X64
, TAB_ARCH_IPF
, TAB_ARCH_ARM
, TAB_ARCH_AARCH64
}
4094 if not self
._GetNextToken
():
4097 S
= self
._Token
.upper()
4098 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[VTF."):
4099 self
.SectionParser(S
)
4104 if not self
._IsToken
("[VTF.", True):
4105 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4106 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
4107 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
4108 raise Warning.Expected("[VTF.]", self
.FileName
, self
.CurrentLineNumber
)
4110 if not self
._SkipToToken
(TAB_SPLIT
):
4111 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
4113 Arch
= self
._SkippedChars
.rstrip(TAB_SPLIT
).upper()
4114 if Arch
not in HW_ARCH_SET
:
4115 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
4117 if not self
._GetNextWord
():
4118 raise Warning.Expected("VTF name", self
.FileName
, self
.CurrentLineNumber
)
4119 Name
= self
._Token
.upper()
4122 VtfObj
.UiName
= Name
4123 VtfObj
.KeyArch
= Arch
4125 if self
._IsToken
(TAB_COMMA_SPLIT
):
4126 if not self
._GetNextWord
():
4127 raise Warning.Expected("Arch list", self
.FileName
, self
.CurrentLineNumber
)
4128 if self
._Token
.upper() not in HW_ARCH_SET
:
4129 raise Warning("Unknown Arch '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4130 VtfObj
.ArchList
= self
._Token
.upper()
4132 if not self
._IsToken
(TAB_SECTION_END
):
4133 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
4135 if self
._IsKeyword
("IA32_RST_BIN"):
4136 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4137 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4139 if not self
._GetNextToken
():
4140 raise Warning.Expected("Reset file", self
.FileName
, self
.CurrentLineNumber
)
4142 VtfObj
.ResetBin
= self
._Token
4143 if VtfObj
.ResetBin
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4144 #check for file path
4145 ErrorCode
, ErrorInfo
= PathClass(NormPath(VtfObj
.ResetBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4147 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4149 while self
._GetComponentStatement
(VtfObj
):
4152 self
.Profile
.VtfList
.append(VtfObj
)
4155 ## _GetComponentStatement() method
4157 # Get components in VTF
4159 # @param self The object pointer
4160 # @param VtfObj for whom component is got
4161 # @retval True Successfully find a component
4162 # @retval False Not able to find a component
4164 def _GetComponentStatement(self
, VtfObj
):
4165 if not self
._IsKeyword
("COMP_NAME"):
4168 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4169 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4171 if not self
._GetNextWord
():
4172 raise Warning.Expected("Component Name", self
.FileName
, self
.CurrentLineNumber
)
4174 CompStatementObj
= ComponentStatement()
4175 CompStatementObj
.CompName
= self
._Token
4177 if not self
._IsKeyword
("COMP_LOC"):
4178 raise Warning.Expected("COMP_LOC", self
.FileName
, self
.CurrentLineNumber
)
4180 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4181 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4183 CompStatementObj
.CompLoc
= ""
4184 if self
._GetNextWord
():
4185 CompStatementObj
.CompLoc
= self
._Token
4186 if self
._IsToken
(TAB_VALUE_SPLIT
):
4187 if not self
._GetNextWord
():
4188 raise Warning.Expected("Region Name", self
.FileName
, self
.CurrentLineNumber
)
4190 if self
._Token
not in {"F", "N", "S"}: #, "H", "L", "PH", "PL"): not support
4191 raise Warning("Unknown location type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4193 CompStatementObj
.FilePos
= self
._Token
4195 self
.CurrentLineNumber
+= 1
4196 self
.CurrentOffsetWithinLine
= 0
4198 if not self
._IsKeyword
("COMP_TYPE"):
4199 raise Warning.Expected("COMP_TYPE", self
.FileName
, self
.CurrentLineNumber
)
4201 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4202 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4204 if not self
._GetNextToken
():
4205 raise Warning.Expected("Component type", self
.FileName
, self
.CurrentLineNumber
)
4206 if self
._Token
not in {"FIT", "PAL_B", "PAL_A", "OEM"}:
4207 if not self
._Token
.startswith("0x") or len(self
._Token
) < 3 or len(self
._Token
) > 4 or \
4208 not self
._Token
[2] in hexdigits
or not self
._Token
[-1] in hexdigits
:
4209 raise Warning("Unknown location type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4210 CompStatementObj
.CompType
= self
._Token
4212 if not self
._IsKeyword
("COMP_VER"):
4213 raise Warning.Expected("COMP_VER", self
.FileName
, self
.CurrentLineNumber
)
4215 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4216 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4218 if not self
._GetNextToken
():
4219 raise Warning.Expected("Component version", self
.FileName
, self
.CurrentLineNumber
)
4221 Pattern
= compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', DOTALL
)
4222 if Pattern
.match(self
._Token
) is None:
4223 raise Warning("Unknown version format '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4224 CompStatementObj
.CompVer
= self
._Token
4226 if not self
._IsKeyword
("COMP_CS"):
4227 raise Warning.Expected("COMP_CS", self
.FileName
, self
.CurrentLineNumber
)
4229 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4230 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4232 if not self
._GetNextToken
():
4233 raise Warning.Expected("Component CS", self
.FileName
, self
.CurrentLineNumber
)
4234 if self
._Token
not in {"1", "0"}:
4235 raise Warning("Unknown Component CS '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4236 CompStatementObj
.CompCs
= self
._Token
4239 if not self
._IsKeyword
("COMP_BIN"):
4240 raise Warning.Expected("COMP_BIN", self
.FileName
, self
.CurrentLineNumber
)
4242 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4243 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4245 if not self
._GetNextToken
():
4246 raise Warning.Expected("Component file", self
.FileName
, self
.CurrentLineNumber
)
4248 CompStatementObj
.CompBin
= self
._Token
4249 if CompStatementObj
.CompBin
!= '-' and CompStatementObj
.CompBin
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4250 #check for file path
4251 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4253 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4255 if not self
._IsKeyword
("COMP_SYM"):
4256 raise Warning.Expected("COMP_SYM", self
.FileName
, self
.CurrentLineNumber
)
4258 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4259 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4261 if not self
._GetNextToken
():
4262 raise Warning.Expected("Component symbol file", self
.FileName
, self
.CurrentLineNumber
)
4264 CompStatementObj
.CompSym
= self
._Token
4265 if CompStatementObj
.CompSym
!= '-' and CompStatementObj
.CompSym
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4266 #check for file path
4267 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompSym
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4269 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4271 if not self
._IsKeyword
("COMP_SIZE"):
4272 raise Warning.Expected("COMP_SIZE", self
.FileName
, self
.CurrentLineNumber
)
4274 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4275 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4277 if self
._IsToken
("-"):
4278 CompStatementObj
.CompSize
= self
._Token
4279 elif self
._GetNextDecimalNumber
():
4280 CompStatementObj
.CompSize
= self
._Token
4281 elif self
._GetNextHexNumber
():
4282 CompStatementObj
.CompSize
= self
._Token
4284 raise Warning("Unknown size '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4286 VtfObj
.ComponentStatementList
.append(CompStatementObj
)
4289 ## _GetOptionRom() method
4291 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
4293 # @param self The object pointer
4294 # @retval True Successfully find a OptionROM
4295 # @retval False Not able to find a OptionROM
4297 def _GetOptionRom(self
):
4298 if not self
._GetNextToken
():
4301 S
= self
._Token
.upper()
4302 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[OPTIONROM."):
4303 self
.SectionParser(S
)
4308 if not self
._IsToken
("[OptionRom.", True):
4309 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4311 OptRomName
= self
._GetUiName
()
4313 if not self
._IsToken
(TAB_SECTION_END
):
4314 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
4316 OptRomObj
= OPTIONROM(OptRomName
)
4317 self
.Profile
.OptRomDict
[OptRomName
] = OptRomObj
4320 isInf
= self
._GetOptRomInfStatement
(OptRomObj
)
4321 isFile
= self
._GetOptRomFileStatement
(OptRomObj
)
4322 if not isInf
and not isFile
:
4327 ## _GetOptRomInfStatement() method
4329 # Get INF statements
4331 # @param self The object pointer
4332 # @param Obj for whom inf statement is got
4333 # @retval True Successfully find inf statement
4334 # @retval False Not able to find inf statement
4336 def _GetOptRomInfStatement(self
, Obj
):
4337 if not self
._IsKeyword
("INF"):
4340 ffsInf
= OptRomInfStatement()
4341 self
._GetInfOptions
(ffsInf
)
4343 if not self
._GetNextToken
():
4344 raise Warning.Expected("INF file path", self
.FileName
, self
.CurrentLineNumber
)
4345 ffsInf
.InfFileName
= self
._Token
4346 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4347 #check for file path
4348 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4350 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4352 NewFileName
= ffsInf
.InfFileName
4353 if ffsInf
.OverrideGuid
:
4354 NewFileName
= ProcessDuplicatedInf(PathClass(ffsInf
.InfFileName
,GenFdsGlobalVariable
.WorkSpaceDir
), ffsInf
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
).Path
4356 if not NewFileName
in self
.Profile
.InfList
:
4357 self
.Profile
.InfList
.append(NewFileName
)
4358 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4359 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
4361 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
4362 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
4364 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
4366 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
4369 self
._GetOptRomOverrides
(ffsInf
)
4371 Obj
.FfsList
.append(ffsInf
)
4374 ## _GetOptRomOverrides() method
4376 # Get overrides for OptROM INF & FILE
4378 # @param self The object pointer
4379 # @param FfsInfObj for whom overrides is got
4381 def _GetOptRomOverrides(self
, Obj
):
4382 if self
._IsToken
('{'):
4383 Overrides
= OverrideAttribs()
4385 if self
._IsKeyword
("PCI_VENDOR_ID"):
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 vendor id", self
.FileName
, self
.CurrentLineNumber
)
4390 Overrides
.PciVendorId
= self
._Token
4393 if self
._IsKeyword
("PCI_CLASS_CODE"):
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 class code", self
.FileName
, self
.CurrentLineNumber
)
4398 Overrides
.PciClassCode
= self
._Token
4401 if self
._IsKeyword
("PCI_DEVICE_ID"):
4402 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4403 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4404 # Get a list of PCI IDs
4405 Overrides
.PciDeviceId
= ""
4406 while (self
._GetNextHexNumber
()):
4407 Overrides
.PciDeviceId
= "{} {}".format(Overrides
.PciDeviceId
, self
._Token
)
4408 if not Overrides
.PciDeviceId
:
4409 raise Warning.Expected("one or more Hex device ids", self
.FileName
, self
.CurrentLineNumber
)
4412 if self
._IsKeyword
("PCI_REVISION"):
4413 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4414 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4415 if not self
._GetNextHexNumber
():
4416 raise Warning.Expected("Hex revision", self
.FileName
, self
.CurrentLineNumber
)
4417 Overrides
.PciRevision
= self
._Token
4420 if self
._IsKeyword
("PCI_COMPRESS"):
4421 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4422 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4423 if not self
._GetNextToken
():
4424 raise Warning.Expected("TRUE/FALSE for compress", self
.FileName
, self
.CurrentLineNumber
)
4425 Overrides
.NeedCompress
= self
._Token
.upper() == 'TRUE'
4428 if self
._IsToken
(T_CHAR_BRACE_R
):
4431 EdkLogger
.error("FdfParser", FORMAT_INVALID
, File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
4433 Obj
.OverrideAttribs
= Overrides
4435 ## _GetOptRomFileStatement() method
4437 # Get FILE statements
4439 # @param self The object pointer
4440 # @param Obj for whom FILE statement is got
4441 # @retval True Successfully find FILE statement
4442 # @retval False Not able to find FILE statement
4444 def _GetOptRomFileStatement(self
, Obj
):
4445 if not self
._IsKeyword
("FILE"):
4448 FfsFileObj
= OptRomFileStatement()
4450 if not self
._IsKeyword
("EFI") and not self
._IsKeyword
(BINARY_FILE_TYPE_BIN
):
4451 raise Warning.Expected("Binary type (EFI/BIN)", self
.FileName
, self
.CurrentLineNumber
)
4452 FfsFileObj
.FileType
= self
._Token
4454 if not self
._GetNextToken
():
4455 raise Warning.Expected("File path", self
.FileName
, self
.CurrentLineNumber
)
4456 FfsFileObj
.FileName
= self
._Token
4457 if FfsFileObj
.FileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4458 #check for file path
4459 ErrorCode
, ErrorInfo
= PathClass(NormPath(FfsFileObj
.FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4461 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4463 if FfsFileObj
.FileType
== 'EFI':
4464 self
._GetOptRomOverrides
(FfsFileObj
)
4466 Obj
.FfsList
.append(FfsFileObj
)
4470 ## _GetCapInFd() method
4472 # Get Cap list contained in FD
4474 # @param self The object pointer
4475 # @param FdName FD name
4476 # @retval CapList List of Capsule in FD
4478 def _GetCapInFd (self
, FdName
):
4480 if FdName
.upper() in self
.Profile
.FdDict
:
4481 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4482 for elementRegion
in FdObj
.RegionList
:
4483 if elementRegion
.RegionType
== 'CAPSULE':
4484 for elementRegionData
in elementRegion
.RegionDataList
:
4485 if elementRegionData
.endswith(".cap"):
4487 if elementRegionData
is not None and elementRegionData
.upper() not in CapList
:
4488 CapList
.append(elementRegionData
.upper())
4491 ## _GetReferencedFdCapTuple() method
4493 # Get FV and FD list referenced by a capsule image
4495 # @param self The object pointer
4496 # @param CapObj Capsule section to be searched
4497 # @param RefFdList referenced FD by section
4498 # @param RefFvList referenced FV by section
4500 def _GetReferencedFdCapTuple(self
, CapObj
, RefFdList
= [], RefFvList
= []):
4501 for CapsuleDataObj
in CapObj
.CapsuleDataList
:
4502 if hasattr(CapsuleDataObj
, 'FvName') and CapsuleDataObj
.FvName
is not None and CapsuleDataObj
.FvName
.upper() not in RefFvList
:
4503 RefFvList
.append (CapsuleDataObj
.FvName
.upper())
4504 elif hasattr(CapsuleDataObj
, 'FdName') and CapsuleDataObj
.FdName
is not None and CapsuleDataObj
.FdName
.upper() not in RefFdList
:
4505 RefFdList
.append (CapsuleDataObj
.FdName
.upper())
4506 elif CapsuleDataObj
.Ffs
is not None:
4507 if isinstance(CapsuleDataObj
.Ffs
, FileStatement
):
4508 if CapsuleDataObj
.Ffs
.FvName
is not None and CapsuleDataObj
.Ffs
.FvName
.upper() not in RefFvList
:
4509 RefFvList
.append(CapsuleDataObj
.Ffs
.FvName
.upper())
4510 elif CapsuleDataObj
.Ffs
.FdName
is not None and CapsuleDataObj
.Ffs
.FdName
.upper() not in RefFdList
:
4511 RefFdList
.append(CapsuleDataObj
.Ffs
.FdName
.upper())
4513 self
._GetReferencedFdFvTupleFromSection
(CapsuleDataObj
.Ffs
, RefFdList
, RefFvList
)
4515 ## _GetFvInFd() method
4517 # Get FV list contained in FD
4519 # @param self The object pointer
4520 # @param FdName FD name
4521 # @retval FvList list of FV in FD
4523 def _GetFvInFd (self
, FdName
):
4525 if FdName
.upper() in self
.Profile
.FdDict
:
4526 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4527 for elementRegion
in FdObj
.RegionList
:
4528 if elementRegion
.RegionType
== BINARY_FILE_TYPE_FV
:
4529 for elementRegionData
in elementRegion
.RegionDataList
:
4530 if elementRegionData
.endswith(".fv"):
4532 if elementRegionData
is not None and elementRegionData
.upper() not in FvList
:
4533 FvList
.append(elementRegionData
.upper())
4536 ## _GetReferencedFdFvTuple() method
4538 # Get FD and FV list referenced by a FFS file
4540 # @param self The object pointer
4541 # @param FfsFile contains sections to be searched
4542 # @param RefFdList referenced FD by section
4543 # @param RefFvList referenced FV by section
4545 def _GetReferencedFdFvTuple(self
, FvObj
, RefFdList
= [], RefFvList
= []):
4546 for FfsObj
in FvObj
.FfsList
:
4547 if isinstance(FfsObj
, FileStatement
):
4548 if FfsObj
.FvName
is not None and FfsObj
.FvName
.upper() not in RefFvList
:
4549 RefFvList
.append(FfsObj
.FvName
.upper())
4550 elif FfsObj
.FdName
is not None and FfsObj
.FdName
.upper() not in RefFdList
:
4551 RefFdList
.append(FfsObj
.FdName
.upper())
4553 self
._GetReferencedFdFvTupleFromSection
(FfsObj
, RefFdList
, RefFvList
)
4555 ## _GetReferencedFdFvTupleFromSection() method
4557 # Get FD and FV list referenced by a FFS section
4559 # @param self The object pointer
4560 # @param FfsFile contains sections to be searched
4561 # @param FdList referenced FD by section
4562 # @param FvList referenced FV by section
4564 def _GetReferencedFdFvTupleFromSection(self
, FfsFile
, FdList
= [], FvList
= []):
4565 SectionStack
= list(FfsFile
.SectionList
)
4566 while SectionStack
!= []:
4567 SectionObj
= SectionStack
.pop()
4568 if isinstance(SectionObj
, FvImageSection
):
4569 if SectionObj
.FvName
is not None and SectionObj
.FvName
.upper() not in FvList
:
4570 FvList
.append(SectionObj
.FvName
.upper())
4571 if SectionObj
.Fv
is not None and SectionObj
.Fv
.UiFvName
is not None and SectionObj
.Fv
.UiFvName
.upper() not in FvList
:
4572 FvList
.append(SectionObj
.Fv
.UiFvName
.upper())
4573 self
._GetReferencedFdFvTuple
(SectionObj
.Fv
, FdList
, FvList
)
4575 if isinstance(SectionObj
, CompressSection
) or isinstance(SectionObj
, GuidSection
):
4576 SectionStack
.extend(SectionObj
.SectionList
)
4578 ## CycleReferenceCheck() method
4580 # Check whether cycle reference exists in FDF
4582 # @param self The object pointer
4583 # @retval True cycle reference exists
4584 # @retval False Not exists cycle reference
4586 def CycleReferenceCheck(self
):
4588 # Check the cycle between FV and FD image
4590 MaxLength
= len (self
.Profile
.FvDict
)
4591 for FvName
in self
.Profile
.FvDict
:
4592 LogStr
= "\nCycle Reference Checking for FV: %s\n" % FvName
4593 RefFvStack
= set(FvName
)
4594 FdAnalyzedList
= set()
4597 while RefFvStack
and Index
< MaxLength
:
4599 FvNameFromStack
= RefFvStack
.pop()
4600 if FvNameFromStack
.upper() in self
.Profile
.FvDict
:
4601 FvObj
= self
.Profile
.FvDict
[FvNameFromStack
.upper()]
4607 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4609 for RefFdName
in RefFdList
:
4610 if RefFdName
in FdAnalyzedList
:
4613 LogStr
+= "FV %s contains FD %s\n" % (FvNameFromStack
, RefFdName
)
4614 FvInFdList
= self
._GetFvInFd
(RefFdName
)
4615 if FvInFdList
!= []:
4616 for FvNameInFd
in FvInFdList
:
4617 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4618 if FvNameInFd
not in RefFvStack
:
4619 RefFvStack
.add(FvNameInFd
)
4621 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4622 EdkLogger
.info(LogStr
)
4624 FdAnalyzedList
.add(RefFdName
)
4626 for RefFvName
in RefFvList
:
4627 LogStr
+= "FV %s contains FV %s\n" % (FvNameFromStack
, RefFvName
)
4628 if RefFvName
not in RefFvStack
:
4629 RefFvStack
.add(RefFvName
)
4631 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4632 EdkLogger
.info(LogStr
)
4636 # Check the cycle between Capsule and FD image
4638 MaxLength
= len (self
.Profile
.CapsuleDict
)
4639 for CapName
in self
.Profile
.CapsuleDict
:
4641 # Capsule image to be checked.
4643 LogStr
= "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4644 RefCapStack
= {CapName}
4645 FdAnalyzedList
= set()
4646 FvAnalyzedList
= set()
4649 while RefCapStack
and Index
< MaxLength
:
4651 CapNameFromStack
= RefCapStack
.pop()
4652 if CapNameFromStack
.upper() in self
.Profile
.CapsuleDict
:
4653 CapObj
= self
.Profile
.CapsuleDict
[CapNameFromStack
.upper()]
4659 self
._GetReferencedFdCapTuple
(CapObj
, RefFdList
, RefFvList
)
4663 while FvListLength
< len (RefFvList
) or FdListLength
< len (RefFdList
):
4664 for RefFdName
in RefFdList
:
4665 if RefFdName
in FdAnalyzedList
:
4668 LogStr
+= "Capsule %s contains FD %s\n" % (CapNameFromStack
, RefFdName
)
4669 for CapNameInFd
in self
._GetCapInFd
(RefFdName
):
4670 LogStr
+= "FD %s contains Capsule %s\n" % (RefFdName
, CapNameInFd
)
4671 if CapNameInFd
not in RefCapStack
:
4672 RefCapStack
.append(CapNameInFd
)
4674 if CapName
in RefCapStack
or CapNameFromStack
in RefCapStack
:
4675 EdkLogger
.info(LogStr
)
4678 for FvNameInFd
in self
._GetFvInFd
(RefFdName
):
4679 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4680 if FvNameInFd
not in RefFvList
:
4681 RefFvList
.append(FvNameInFd
)
4683 FdAnalyzedList
.add(RefFdName
)
4685 # the number of the parsed FV and FD image
4687 FvListLength
= len (RefFvList
)
4688 FdListLength
= len (RefFdList
)
4689 for RefFvName
in RefFvList
:
4690 if RefFvName
in FvAnalyzedList
:
4692 LogStr
+= "Capsule %s contains FV %s\n" % (CapNameFromStack
, RefFvName
)
4693 if RefFvName
.upper() in self
.Profile
.FvDict
:
4694 FvObj
= self
.Profile
.FvDict
[RefFvName
.upper()]
4697 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4698 FvAnalyzedList
.add(RefFvName
)
4702 def GetAllIncludedFile (self
):
4703 global AllIncludeFileList
4704 return AllIncludeFileList
4706 if __name__
== "__main__":
4709 test_file
= sys
.argv
[1]
4710 except IndexError as v
:
4711 print("Usage: %s filename" % sys
.argv
[0])
4714 parser
= FdfParser(test_file
)
4717 parser
.CycleReferenceCheck()
4718 except Warning as X
: