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
56 from .OptionRom
import OPTIONROM
57 from .OptRomInfStatement
import OptRomInfStatement
, OverrideAttribs
58 from .OptRomFileStatement
import OptRomFileStatement
59 from .GenFdsGlobalVariable
import GenFdsGlobalVariable
63 T_CHAR_DOUBLE_QUOTE
= '\"'
64 T_CHAR_SINGLE_QUOTE
= '\''
67 SEPARATORS
= {TAB_EQUAL_SPLIT
, TAB_VALUE_SPLIT
, TAB_COMMA_SPLIT
, '{', T_CHAR_BRACE_R
}
68 ALIGNMENTS
= {"Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K", "64K", "128K",
69 "256K", "512K", "1M", "2M", "4M", "8M", "16M"}
70 ALIGNMENT_NOAUTO
= ALIGNMENTS
- {"Auto"}
71 CR_LB_SET
= {T_CHAR_CR
, TAB_LINE_BREAK
}
73 RegionSizePattern
= compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
74 RegionSizeGuidPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*")
75 RegionOffsetPcdPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$")
76 ShortcutPcdPattern
= compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
77 BaseAddrValuePattern
= compile('^0[xX][0-9a-fA-F]+')
78 FileExtensionPattern
= compile(r
'([a-zA-Z][a-zA-Z0-9]*)')
79 TokenFindPattern
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
80 AllIncludeFileList
= []
82 # Get the closest parent
83 def GetParentAtLine (Line
):
84 for Profile
in AllIncludeFileList
:
85 if Profile
.IsLineInFile(Line
):
90 def IsValidInclude (File
, Line
):
91 for Profile
in AllIncludeFileList
:
92 if Profile
.IsLineInFile(Line
) and Profile
.FileName
== File
:
97 def GetRealFileLine (File
, Line
):
99 for Profile
in AllIncludeFileList
:
100 if Profile
.IsLineInFile(Line
):
101 return Profile
.GetLineInFile(Line
)
102 elif Line
>= Profile
.InsertStartLineNumber
and Profile
.Level
== 1:
103 InsertedLines
+= Profile
.GetTotalLines()
105 return (File
, Line
- InsertedLines
)
107 ## The exception class that used to report error messages when parsing FDF
109 # Currently the "ToolName" is set to be "FdfParser".
111 class Warning (Exception):
114 # @param self The object pointer
115 # @param Str The message to record
116 # @param File The FDF name
117 # @param Line The Line number that error occurs
119 def __init__(self
, Str
, File
= None, Line
= None):
120 FileLineTuple
= GetRealFileLine(File
, Line
)
121 self
.FileName
= FileLineTuple
[0]
122 self
.LineNumber
= FileLineTuple
[1]
123 self
.OriginalLineNumber
= Line
125 self
.ToolName
= 'FdfParser'
130 # helper functions to facilitate consistency in warnings
131 # each function is for a different common warning
133 def Expected(Str
, File
, Line
):
134 return Warning("expected {}".format(Str
), File
, Line
)
136 def ExpectedEquals(File
, Line
):
137 return Warning.Expected("'='", File
, Line
)
139 def ExpectedCurlyOpen(File
, Line
):
140 return Warning.Expected("'{'", File
, Line
)
142 def ExpectedCurlyClose(File
, Line
):
143 return Warning.Expected("'}'", File
, Line
)
145 def ExpectedBracketClose(File
, Line
):
146 return Warning.Expected("']'", File
, Line
)
148 ## The Include file content class that used to record file data when parsing include file
150 # May raise Exception when opening file.
152 class IncludeFileProfile
:
155 # @param self The object pointer
156 # @param FileName The file that to be parsed
158 def __init__(self
, FileName
):
159 self
.FileName
= FileName
160 self
.FileLinesList
= []
162 with
open(FileName
, "r") as fsock
:
163 self
.FileLinesList
= fsock
.readlines()
164 for index
, line
in enumerate(self
.FileLinesList
):
165 if not line
.endswith(TAB_LINE_BREAK
):
166 self
.FileLinesList
[index
] += TAB_LINE_BREAK
168 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
170 self
.InsertStartLineNumber
= None
171 self
.InsertAdjust
= 0
172 self
.IncludeFileList
= []
173 self
.Level
= 1 # first level include file
175 def GetTotalLines(self
):
176 TotalLines
= self
.InsertAdjust
+ len(self
.FileLinesList
)
178 for Profile
in self
.IncludeFileList
:
179 TotalLines
+= Profile
.GetTotalLines()
183 def IsLineInFile(self
, Line
):
184 if Line
>= self
.InsertStartLineNumber
and Line
< self
.InsertStartLineNumber
+ self
.GetTotalLines():
189 def GetLineInFile(self
, Line
):
190 if not self
.IsLineInFile (Line
):
191 return (self
.FileName
, -1)
193 InsertedLines
= self
.InsertStartLineNumber
195 for Profile
in self
.IncludeFileList
:
196 if Profile
.IsLineInFile(Line
):
197 return Profile
.GetLineInFile(Line
)
198 elif Line
>= Profile
.InsertStartLineNumber
:
199 InsertedLines
+= Profile
.GetTotalLines()
201 return (self
.FileName
, Line
- InsertedLines
+ 1)
203 ## The FDF content class that used to record file data when parsing FDF
205 # May raise Exception when opening file.
210 # @param self The object pointer
211 # @param FileName The file that to be parsed
213 def __init__(self
, FileName
):
214 self
.FileLinesList
= []
216 with
open(FileName
, "r") as fsock
:
217 self
.FileLinesList
= fsock
.readlines()
220 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
222 self
.FileName
= FileName
223 self
.PcdDict
= OrderedDict()
224 self
.PcdLocalDict
= OrderedDict()
226 self
.InfDict
= {'ArchTBD':[]}
227 # ECC will use this Dict and List information
228 self
.PcdFileLineDict
= {}
229 self
.InfFileLineList
= []
232 self
.FdNameNotSet
= False
234 self
.CapsuleDict
= {}
237 self
.FmpPayloadDict
= {}
239 ## The syntax parser for FDF
241 # PreprocessFile method should be called prior to ParseFile
242 # CycleReferenceCheck method can detect cycles in FDF contents
244 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
245 # Get*** procedures mean these procedures will make judgement on current token only.
250 # @param self The object pointer
251 # @param FileName The file that to be parsed
253 def __init__(self
, FileName
):
254 self
.Profile
= FileProfile(FileName
)
255 self
.FileName
= FileName
256 self
.CurrentLineNumber
= 1
257 self
.CurrentOffsetWithinLine
= 0
258 self
.CurrentFdName
= None
259 self
.CurrentFvName
= None
261 self
._SkippedChars
= ""
262 GlobalData
.gFdfParser
= self
264 # Used to section info
265 self
._CurSection
= []
266 # Key: [section name, UI name, arch]
267 # Value: {MACRO_NAME: MACRO_VALUE}
268 self
._MacroDict
= tdict(True, 3)
269 self
._PcdDict
= OrderedDict()
271 self
._WipeOffArea
= []
272 if GenFdsGlobalVariable
.WorkSpaceDir
== '':
273 GenFdsGlobalVariable
.WorkSpaceDir
= os
.getenv("WORKSPACE")
275 ## _SkipWhiteSpace() method
277 # Skip white spaces from current char.
279 # @param self The object pointer
281 def _SkipWhiteSpace(self
):
282 while not self
._EndOfFile
():
283 if self
._CurrentChar
() in {TAB_PRINTCHAR_NUL
, T_CHAR_CR
, TAB_LINE_BREAK
, TAB_SPACE_SPLIT
, T_CHAR_TAB
}:
284 self
._SkippedChars
+= str(self
._CurrentChar
())
290 ## _EndOfFile() method
292 # Judge current buffer pos is at file end
294 # @param self The object pointer
295 # @retval True Current File buffer position is at file end
296 # @retval False Current File buffer position is NOT at file end
298 def _EndOfFile(self
):
299 NumberOfLines
= len(self
.Profile
.FileLinesList
)
300 SizeOfLastLine
= len(self
.Profile
.FileLinesList
[-1])
301 if self
.CurrentLineNumber
== NumberOfLines
and self
.CurrentOffsetWithinLine
>= SizeOfLastLine
- 1:
303 if self
.CurrentLineNumber
> NumberOfLines
:
307 ## _EndOfLine() method
309 # Judge current buffer pos is at line end
311 # @param self The object pointer
312 # @retval True Current File buffer position is at line end
313 # @retval False Current File buffer position is NOT at line end
315 def _EndOfLine(self
):
316 if self
.CurrentLineNumber
> len(self
.Profile
.FileLinesList
):
318 SizeOfCurrentLine
= len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
319 if self
.CurrentOffsetWithinLine
>= SizeOfCurrentLine
:
325 # Reset file data buffer to the initial state
327 # @param self The object pointer
328 # @param DestLine Optional new destination line number.
329 # @param DestOffset Optional new destination offset.
331 def Rewind(self
, DestLine
= 1, DestOffset
= 0):
332 self
.CurrentLineNumber
= DestLine
333 self
.CurrentOffsetWithinLine
= DestOffset
335 ## _UndoOneChar() method
337 # Go back one char in the file buffer
339 # @param self The object pointer
340 # @retval True Successfully go back one char
341 # @retval False Not able to go back one char as file beginning reached
343 def _UndoOneChar(self
):
344 if self
.CurrentLineNumber
== 1 and self
.CurrentOffsetWithinLine
== 0:
346 elif self
.CurrentOffsetWithinLine
== 0:
347 self
.CurrentLineNumber
-= 1
348 self
.CurrentOffsetWithinLine
= len(self
._CurrentLine
()) - 1
350 self
.CurrentOffsetWithinLine
-= 1
353 ## _GetOneChar() method
355 # Move forward one char in the file buffer
357 # @param self The object pointer
359 def _GetOneChar(self
):
360 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
361 self
.CurrentLineNumber
+= 1
362 self
.CurrentOffsetWithinLine
= 0
364 self
.CurrentOffsetWithinLine
+= 1
366 ## _CurrentChar() method
368 # Get the char pointed to by the file buffer pointer
370 # @param self The object pointer
371 # @retval Char Current char
373 def _CurrentChar(self
):
374 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
]
376 ## _NextChar() method
378 # Get the one char pass the char pointed to by the file buffer pointer
380 # @param self The object pointer
381 # @retval Char Next char
384 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
385 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
][0]
386 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
+ 1]
388 ## _SetCurrentCharValue() method
390 # Modify the value of current char
392 # @param self The object pointer
393 # @param Value The new value of current char
395 def _SetCurrentCharValue(self
, Value
):
396 self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
] = Value
398 ## _CurrentLine() method
400 # Get the list that contains current line contents
402 # @param self The object pointer
403 # @retval List current line contents
405 def _CurrentLine(self
):
406 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
408 def _StringToList(self
):
409 self
.Profile
.FileLinesList
= [list(s
) for s
in self
.Profile
.FileLinesList
]
410 if not self
.Profile
.FileLinesList
:
411 EdkLogger
.error('FdfParser', FILE_READ_FAILURE
, 'The file is empty!', File
=self
.FileName
)
412 self
.Profile
.FileLinesList
[-1].append(' ')
414 def _ReplaceFragment(self
, StartPos
, EndPos
, Value
= ' '):
415 if StartPos
[0] == EndPos
[0]:
417 while Offset
<= EndPos
[1]:
418 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
423 while self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] not in CR_LB_SET
:
424 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
428 while Line
< EndPos
[0]:
430 while self
.Profile
.FileLinesList
[Line
][Offset
] not in CR_LB_SET
:
431 self
.Profile
.FileLinesList
[Line
][Offset
] = Value
436 while Offset
<= EndPos
[1]:
437 self
.Profile
.FileLinesList
[EndPos
[0]][Offset
] = Value
440 def _SetMacroValue(self
, Macro
, Value
):
441 if not self
._CurSection
:
445 if not self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]:
446 self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]] = MacroDict
448 MacroDict
= self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]
449 MacroDict
[Macro
] = Value
451 def _GetMacroValue(self
, Macro
):
453 if Macro
in GlobalData
.gCommandLineDefines
:
454 return GlobalData
.gCommandLineDefines
[Macro
]
455 if Macro
in GlobalData
.gGlobalDefines
:
456 return GlobalData
.gGlobalDefines
[Macro
]
459 MacroDict
= self
._MacroDict
[
464 if MacroDict
and Macro
in MacroDict
:
465 return MacroDict
[Macro
]
468 if Macro
in GlobalData
.gPlatformDefines
:
469 return GlobalData
.gPlatformDefines
[Macro
]
472 def _SectionHeaderParser(self
, Section
):
474 # [FD.UiName]: use dummy instead if UI name is optional
477 # [Rule]: don't take rule section into account, macro is not allowed in this section
478 # [OptionRom.DriverName]
479 self
._CurSection
= []
480 Section
= Section
.strip()[1:-1].upper().replace(' ', '').strip(TAB_SPLIT
)
481 ItemList
= Section
.split(TAB_SPLIT
)
483 if Item
== '' or Item
== 'RULE':
486 if Item
== TAB_COMMON_DEFINES
.upper():
487 self
._CurSection
= [TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
488 elif len(ItemList
) > 1:
489 self
._CurSection
= [ItemList
[0], ItemList
[1], TAB_COMMON
]
490 elif len(ItemList
) > 0:
491 self
._CurSection
= [ItemList
[0], 'DUMMY', TAB_COMMON
]
493 ## PreprocessFile() method
495 # Preprocess file contents, replace comments with spaces.
496 # In the end, rewind the file buffer pointer to the beginning
497 # BUGBUG: No !include statement processing contained in this procedure
498 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
500 # @param self The object pointer
502 def PreprocessFile(self
):
505 DoubleSlashComment
= False
507 # HashComment in quoted string " " is ignored.
510 while not self
._EndOfFile
():
512 if self
._CurrentChar
() == T_CHAR_DOUBLE_QUOTE
and not InComment
:
513 InString
= not InString
514 # meet new line, then no longer in a comment for // and '#'
515 if self
._CurrentChar
() == TAB_LINE_BREAK
:
516 self
.CurrentLineNumber
+= 1
517 self
.CurrentOffsetWithinLine
= 0
518 if InComment
and DoubleSlashComment
:
520 DoubleSlashComment
= False
521 if InComment
and HashComment
:
524 # check for */ comment end
525 elif InComment
and not DoubleSlashComment
and not HashComment
and self
._CurrentChar
() == TAB_STAR
and self
._NextChar
() == TAB_BACK_SLASH
:
526 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
528 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
531 # set comments to spaces
533 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
535 # check for // comment
536 elif self
._CurrentChar
() == TAB_BACK_SLASH
and self
._NextChar
() == TAB_BACK_SLASH
and not self
._EndOfLine
():
538 DoubleSlashComment
= True
539 # check for '#' comment
540 elif self
._CurrentChar
() == TAB_COMMENT_SPLIT
and not self
._EndOfLine
() and not InString
:
543 # check for /* comment start
544 elif self
._CurrentChar
() == TAB_BACK_SLASH
and self
._NextChar
() == TAB_STAR
:
545 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
547 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
553 # restore from ListOfList to ListOfString
554 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
557 ## PreprocessIncludeFile() method
559 # Preprocess file contents, replace !include statements with file contents.
560 # In the end, rewind the file buffer pointer to the beginning
562 # @param self The object pointer
564 def PreprocessIncludeFile(self
):
565 # nested include support
568 while self
._GetNextToken
():
570 if self
._Token
== TAB_DEFINE
:
571 if not self
._GetNextToken
():
572 raise Warning.Expected("Macro name", self
.FileName
, self
.CurrentLineNumber
)
574 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
575 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
576 Value
= self
._GetExpression
()
577 MacroDict
[Macro
] = Value
579 elif self
._Token
== TAB_INCLUDE
:
581 IncludeLine
= self
.CurrentLineNumber
582 IncludeOffset
= self
.CurrentOffsetWithinLine
- len(TAB_INCLUDE
)
583 if not self
._GetNextToken
():
584 raise Warning.Expected("include file name", self
.FileName
, self
.CurrentLineNumber
)
585 IncFileName
= self
._Token
587 StartPos
= IncFileName
.find('$(', PreIndex
)
588 EndPos
= IncFileName
.find(')', StartPos
+2)
589 while StartPos
!= -1 and EndPos
!= -1:
590 Macro
= IncFileName
[StartPos
+2: EndPos
]
591 MacroVal
= self
._GetMacroValue
(Macro
)
593 if Macro
in MacroDict
:
594 MacroVal
= MacroDict
[Macro
]
595 if MacroVal
is not None:
596 IncFileName
= IncFileName
.replace('$(' + Macro
+ ')', MacroVal
, 1)
597 if MacroVal
.find('$(') != -1:
600 PreIndex
= StartPos
+ len(MacroVal
)
602 raise Warning("The Macro %s is not defined" %Macro
, self
.FileName
, self
.CurrentLineNumber
)
603 StartPos
= IncFileName
.find('$(', PreIndex
)
604 EndPos
= IncFileName
.find(')', StartPos
+2)
606 IncludedFile
= NormPath(IncFileName
)
608 # First search the include file under the same directory as FDF file
610 IncludedFile1
= PathClass(IncludedFile
, os
.path
.dirname(self
.FileName
))
611 ErrorCode
= IncludedFile1
.Validate()[0]
614 # Then search the include file under the same directory as DSC file
617 if GenFdsGlobalVariable
.ActivePlatform
:
618 PlatformDir
= GenFdsGlobalVariable
.ActivePlatform
.Dir
619 elif GlobalData
.gActivePlatform
:
620 PlatformDir
= GlobalData
.gActivePlatform
.MetaFile
.Dir
621 IncludedFile1
= PathClass(IncludedFile
, PlatformDir
)
622 ErrorCode
= IncludedFile1
.Validate()[0]
625 # Also search file under the WORKSPACE directory
627 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
628 ErrorCode
= IncludedFile1
.Validate()[0]
630 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
),
631 self
.FileName
, self
.CurrentLineNumber
)
633 if not IsValidInclude (IncludedFile1
.Path
, self
.CurrentLineNumber
):
634 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1
.Path
), self
.FileName
, self
.CurrentLineNumber
)
636 IncFileProfile
= IncludeFileProfile(IncludedFile1
.Path
)
638 CurrentLine
= self
.CurrentLineNumber
639 CurrentOffset
= self
.CurrentOffsetWithinLine
640 # list index of the insertion, note that line number is 'CurrentLine + 1'
641 InsertAtLine
= CurrentLine
642 ParentProfile
= GetParentAtLine (CurrentLine
)
643 if ParentProfile
is not None:
644 ParentProfile
.IncludeFileList
.insert(0, IncFileProfile
)
645 IncFileProfile
.Level
= ParentProfile
.Level
+ 1
646 IncFileProfile
.InsertStartLineNumber
= InsertAtLine
+ 1
647 # deal with remaining portions after "!include filename", if exists.
648 if self
._GetNextToken
():
649 if self
.CurrentLineNumber
== CurrentLine
:
650 RemainingLine
= self
._CurrentLine
()[CurrentOffset
:]
651 self
.Profile
.FileLinesList
.insert(self
.CurrentLineNumber
, RemainingLine
)
652 IncFileProfile
.InsertAdjust
+= 1
653 self
.CurrentLineNumber
+= 1
654 self
.CurrentOffsetWithinLine
= 0
656 for Line
in IncFileProfile
.FileLinesList
:
657 self
.Profile
.FileLinesList
.insert(InsertAtLine
, Line
)
658 self
.CurrentLineNumber
+= 1
661 # reversely sorted to better determine error in file
662 AllIncludeFileList
.insert(0, IncFileProfile
)
664 # comment out the processed include file statement
665 TempList
= list(self
.Profile
.FileLinesList
[IncludeLine
- 1])
666 TempList
.insert(IncludeOffset
, TAB_COMMENT_SPLIT
)
667 self
.Profile
.FileLinesList
[IncludeLine
- 1] = ''.join(TempList
)
668 if Processed
: # Nested and back-to-back support
669 self
.Rewind(DestLine
= IncFileProfile
.InsertStartLineNumber
- 1)
675 def _GetIfListCurrentItemStat(IfList
):
685 ## PreprocessConditionalStatement() method
687 # Preprocess conditional statement.
688 # In the end, rewind the file buffer pointer to the beginning
690 # @param self The object pointer
692 def PreprocessConditionalStatement(self
):
693 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
697 while self
._GetNextToken
():
698 # Determine section name and the location dependent macro
699 if self
._GetIfListCurrentItemStat
(IfList
):
700 if self
._Token
.startswith(TAB_SECTION_START
):
702 if not self
._Token
.endswith(TAB_SECTION_END
):
703 self
._SkipToToken
(TAB_SECTION_END
)
704 Header
+= self
._SkippedChars
705 if Header
.find('$(') != -1:
706 raise Warning("macro cannot be used in section header", self
.FileName
, self
.CurrentLineNumber
)
707 self
._SectionHeaderParser
(Header
)
709 # Replace macros except in RULE section or out of section
710 elif self
._CurSection
and ReplacedLine
!= self
.CurrentLineNumber
:
711 ReplacedLine
= self
.CurrentLineNumber
713 CurLine
= self
.Profile
.FileLinesList
[ReplacedLine
- 1]
715 StartPos
= CurLine
.find('$(', PreIndex
)
716 EndPos
= CurLine
.find(')', StartPos
+2)
717 while StartPos
!= -1 and EndPos
!= -1 and self
._Token
not in {TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_IF
, TAB_ELSE_IF
}:
718 MacroName
= CurLine
[StartPos
+2: EndPos
]
719 MacorValue
= self
._GetMacroValue
(MacroName
)
720 if MacorValue
is not None:
721 CurLine
= CurLine
.replace('$(' + MacroName
+ ')', MacorValue
, 1)
722 if MacorValue
.find('$(') != -1:
725 PreIndex
= StartPos
+ len(MacorValue
)
727 PreIndex
= EndPos
+ 1
728 StartPos
= CurLine
.find('$(', PreIndex
)
729 EndPos
= CurLine
.find(')', StartPos
+2)
730 self
.Profile
.FileLinesList
[ReplacedLine
- 1] = CurLine
733 if self
._Token
== TAB_DEFINE
:
734 if self
._GetIfListCurrentItemStat
(IfList
):
735 if not self
._CurSection
:
736 raise Warning("macro cannot be defined in Rule section or out of section", self
.FileName
, self
.CurrentLineNumber
)
737 DefineLine
= self
.CurrentLineNumber
- 1
738 DefineOffset
= self
.CurrentOffsetWithinLine
- len(TAB_DEFINE
)
739 if not self
._GetNextToken
():
740 raise Warning.Expected("Macro name", self
.FileName
, self
.CurrentLineNumber
)
742 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
743 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
745 Value
= self
._GetExpression
()
746 self
._SetMacroValue
(Macro
, Value
)
747 self
._WipeOffArea
.append(((DefineLine
, DefineOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
748 elif self
._Token
== 'SET':
749 if not self
._GetIfListCurrentItemStat
(IfList
):
751 SetLine
= self
.CurrentLineNumber
- 1
752 SetOffset
= self
.CurrentOffsetWithinLine
- len('SET')
753 PcdPair
= self
._GetNextPcdSettings
()
754 PcdName
= "%s.%s" % (PcdPair
[1], PcdPair
[0])
755 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
756 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
758 Value
= self
._GetExpression
()
759 Value
= self
._EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
761 self
._PcdDict
[PcdName
] = Value
763 self
.Profile
.PcdDict
[PcdPair
] = Value
764 self
.SetPcdLocalation(PcdPair
)
765 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
766 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
768 self
._WipeOffArea
.append(((SetLine
, SetOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
769 elif self
._Token
in {TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_IF
}:
770 IfStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
._Token
))
771 IfList
.append([IfStartPos
, None, None])
773 CondLabel
= self
._Token
774 Expression
= self
._GetExpression
()
776 if CondLabel
== TAB_IF
:
777 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
779 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'in')
780 if CondLabel
== TAB_IF_N_DEF
:
781 ConditionSatisfied
= not ConditionSatisfied
783 BranchDetermined
= ConditionSatisfied
784 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, BranchDetermined
]
785 if ConditionSatisfied
:
786 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
787 elif self
._Token
in {TAB_ELSE_IF
, TAB_ELSE
}:
788 ElseStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
._Token
))
790 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
793 IfList
[-1] = [ElseStartPos
, False, True]
794 self
._WipeOffArea
.append((ElseStartPos
, (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
796 self
._WipeOffArea
.append((IfList
[-1][0], ElseStartPos
))
797 IfList
[-1] = [ElseStartPos
, True, IfList
[-1][2]]
798 if self
._Token
== TAB_ELSE_IF
:
799 Expression
= self
._GetExpression
()
800 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
801 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, IfList
[-1][2]]
805 IfList
[-1][1] = False
808 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
809 elif self
._Token
== '!endif':
811 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
813 self
._WipeOffArea
.append(((self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len('!endif')), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
815 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
818 elif not IfList
: # Don't use PCDs inside conditional directive
819 if self
.CurrentLineNumber
<= RegionLayoutLine
:
820 # Don't try the same line twice
822 SetPcd
= ShortcutPcdPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
824 self
._PcdDict
[SetPcd
.group('name')] = SetPcd
.group('value')
825 RegionLayoutLine
= self
.CurrentLineNumber
827 RegionSize
= RegionSizePattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
829 RegionLayoutLine
= self
.CurrentLineNumber
831 RegionSizeGuid
= RegionSizeGuidPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
])
832 if not RegionSizeGuid
:
833 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
835 self
._PcdDict
[RegionSizeGuid
.group('base')] = RegionSize
.group('base')
836 self
._PcdDict
[RegionSizeGuid
.group('size')] = RegionSize
.group('size')
837 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
840 raise Warning("Missing !endif", self
.FileName
, self
.CurrentLineNumber
)
843 def _CollectMacroPcd(self
):
847 MacroDict
.update(GlobalData
.gPlatformPcds
)
848 MacroDict
.update(self
._PcdDict
)
851 MacroDict
.update(GlobalData
.gPlatformDefines
)
855 ScopeMacro
= self
._MacroDict
[TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
857 MacroDict
.update(ScopeMacro
)
860 ScopeMacro
= self
._MacroDict
[
866 MacroDict
.update(ScopeMacro
)
868 MacroDict
.update(GlobalData
.gGlobalDefines
)
869 MacroDict
.update(GlobalData
.gCommandLineDefines
)
870 for Item
in GlobalData
.BuildOptionPcd
:
871 if isinstance(Item
, tuple):
873 PcdName
, TmpValue
= Item
.split(TAB_EQUAL_SPLIT
)
874 TmpValue
= BuildOptionValue(TmpValue
, {})
875 MacroDict
[PcdName
.strip()] = TmpValue
880 def _EvaluateConditional(self
, Expression
, Line
, Op
= None, Value
= None):
881 MacroPcdDict
= self
._CollectMacroPcd
()
885 return ValueExpression(Expression
, MacroPcdDict
)(True)
887 return ValueExpression(Expression
, MacroPcdDict
)()
888 except WrnExpression
as Excpt
:
890 # Catch expression evaluation warning here. We need to report
891 # the precise number of line and return the evaluation result
893 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
894 File
=self
.FileName
, ExtraData
=self
._CurrentLine
(),
897 except Exception as Excpt
:
898 if hasattr(Excpt
, 'Pcd'):
899 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
900 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
901 raise Warning("Cannot use this PCD (%s) in an expression as"
902 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
903 " of the DSC file (%s), and it is currently defined in this section:"
904 " %s, line #: %d." % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE'], Info
[0], Info
[1]),
907 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE']),
910 raise Warning(str(Excpt
), self
.FileName
, Line
)
912 if Expression
.startswith('$(') and Expression
[-1] == ')':
913 Expression
= Expression
[2:-1]
914 return Expression
in MacroPcdDict
918 # Check whether input string is found from current char position along
919 # If found, the string value is put into self._Token
921 # @param self The object pointer
922 # @param String The string to search
923 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
924 # @retval True Successfully find string, file buffer pointer moved forward
925 # @retval False Not able to find string, file buffer pointer not changed
927 def _IsToken(self
, String
, IgnoreCase
= False):
928 self
._SkipWhiteSpace
()
930 # Only consider the same line, no multi-line token allowed
931 StartPos
= self
.CurrentOffsetWithinLine
934 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
936 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
938 self
.CurrentOffsetWithinLine
+= len(String
)
939 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
943 ## _IsKeyword() method
945 # Check whether input keyword is found from current char position along, whole word only!
946 # If found, the string value is put into self._Token
948 # @param self The object pointer
949 # @param Keyword The string to search
950 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
951 # @retval True Successfully find string, file buffer pointer moved forward
952 # @retval False Not able to find string, file buffer pointer not changed
954 def _IsKeyword(self
, KeyWord
, IgnoreCase
= False):
955 self
._SkipWhiteSpace
()
957 # Only consider the same line, no multi-line token allowed
958 StartPos
= self
.CurrentOffsetWithinLine
961 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(KeyWord
.upper())
963 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(KeyWord
)
965 followingChar
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
+ len(KeyWord
)]
966 if not str(followingChar
).isspace() and followingChar
not in SEPARATORS
:
968 self
.CurrentOffsetWithinLine
+= len(KeyWord
)
969 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
973 def _GetExpression(self
):
974 Line
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
975 Index
= len(Line
) - 1
976 while Line
[Index
] in CR_LB_SET
:
978 ExpressionString
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:Index
+1]
979 self
.CurrentOffsetWithinLine
+= len(ExpressionString
)
980 ExpressionString
= ExpressionString
.strip()
981 return ExpressionString
983 ## _GetNextWord() method
985 # Get next C name from file lines
986 # If found, the string value is put into self._Token
988 # @param self The object pointer
989 # @retval True Successfully find a C name string, file buffer pointer moved forward
990 # @retval False Not able to find a C name string, file buffer pointer not changed
992 def _GetNextWord(self
):
993 self
._SkipWhiteSpace
()
994 if self
._EndOfFile
():
997 TempChar
= self
._CurrentChar
()
998 StartPos
= self
.CurrentOffsetWithinLine
999 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_':
1001 while not self
._EndOfLine
():
1002 TempChar
= self
._CurrentChar
()
1003 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1004 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-':
1010 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1015 def _GetNextPcdWord(self
):
1016 self
._SkipWhiteSpace
()
1017 if self
._EndOfFile
():
1020 TempChar
= self
._CurrentChar
()
1021 StartPos
= self
.CurrentOffsetWithinLine
1022 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_' or TempChar
== TAB_SECTION_START
or TempChar
== TAB_SECTION_END
:
1024 while not self
._EndOfLine
():
1025 TempChar
= self
._CurrentChar
()
1026 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1027 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-' or TempChar
== TAB_SECTION_START
or TempChar
== TAB_SECTION_END
:
1033 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1038 ## _GetNextToken() method
1040 # Get next token unit before a seperator
1041 # If found, the string value is put into self._Token
1043 # @param self The object pointer
1044 # @retval True Successfully find a token unit, file buffer pointer moved forward
1045 # @retval False Not able to find a token unit, file buffer pointer not changed
1047 def _GetNextToken(self
):
1048 # Skip leading spaces, if exist.
1049 self
._SkipWhiteSpace
()
1050 if self
._EndOfFile
():
1052 # Record the token start position, the position of the first non-space char.
1053 StartPos
= self
.CurrentOffsetWithinLine
1054 StartLine
= self
.CurrentLineNumber
1055 while StartLine
== self
.CurrentLineNumber
:
1056 TempChar
= self
._CurrentChar
()
1057 # Try to find the end char that is not a space and not in seperator tuple.
1058 # That is, when we got a space or any char in the tuple, we got the end of token.
1059 if not str(TempChar
).isspace() and TempChar
not in SEPARATORS
:
1061 # if we happen to meet a seperator as the first char, we must proceed to get it.
1062 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1063 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPARATORS
:
1071 EndPos
= self
.CurrentOffsetWithinLine
1072 if self
.CurrentLineNumber
!= StartLine
:
1073 EndPos
= len(self
.Profile
.FileLinesList
[StartLine
-1])
1074 self
._Token
= self
.Profile
.FileLinesList
[StartLine
-1][StartPos
: EndPos
]
1075 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
}:
1076 self
._Token
= self
._Token
.lower()
1077 if StartPos
!= self
.CurrentOffsetWithinLine
:
1082 ## _GetNextGuid() method
1084 # Get next token unit before a seperator
1085 # If found, the GUID string is put into self._Token
1087 # @param self The object pointer
1088 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
1089 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
1091 def _GetNextGuid(self
):
1092 if not self
._GetNextToken
():
1094 if GlobalData
.gGuidPattern
.match(self
._Token
) is not None:
1101 def _Verify(Name
, Value
, Scope
):
1102 # value verification only applies to numeric values.
1103 if Scope
not in TAB_PCD_NUMERIC_TYPES
:
1108 ValueNumber
= int(Value
, 0)
1110 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value is not valid dec or hex number for %s." % Name
)
1112 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value can't be set to negative value for %s." % Name
)
1113 if ValueNumber
> MAX_VAL_TYPE
[Scope
]:
1114 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "Too large value for %s." % Name
)
1117 ## _UndoToken() method
1119 # Go back one token unit in file buffer
1121 # @param self The object pointer
1123 def _UndoToken(self
):
1125 while self
._CurrentChar
().isspace():
1126 if not self
._UndoOneChar
():
1131 StartPos
= self
.CurrentOffsetWithinLine
1132 CurrentLine
= self
.CurrentLineNumber
1133 while CurrentLine
== self
.CurrentLineNumber
:
1135 TempChar
= self
._CurrentChar
()
1136 # Try to find the end char that is not a space and not in seperator tuple.
1137 # That is, when we got a space or any char in the tuple, we got the end of token.
1138 if not str(TempChar
).isspace() and not TempChar
in SEPARATORS
:
1139 if not self
._UndoOneChar
():
1141 # if we happen to meet a seperator as the first char, we must proceed to get it.
1142 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1143 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPARATORS
:
1150 ## _GetNextHexNumber() method
1152 # Get next HEX data before a seperator
1153 # If found, the HEX data is put into self._Token
1155 # @param self The object pointer
1156 # @retval True Successfully find a HEX data, file buffer pointer moved forward
1157 # @retval False Not able to find a HEX data, file buffer pointer not changed
1159 def _GetNextHexNumber(self
):
1160 if not self
._GetNextToken
():
1162 if GlobalData
.gHexPatternAll
.match(self
._Token
):
1168 ## _GetNextDecimalNumber() method
1170 # Get next decimal data before a seperator
1171 # If found, the decimal data is put into self._Token
1173 # @param self The object pointer
1174 # @retval True Successfully find a decimal data, file buffer pointer moved forward
1175 # @retval False Not able to find a decimal data, file buffer pointer not changed
1177 def _GetNextDecimalNumber(self
):
1178 if not self
._GetNextToken
():
1180 if self
._Token
.isdigit():
1186 def _GetNextPcdSettings(self
):
1187 if not self
._GetNextWord
():
1188 raise Warning.Expected("<PcdTokenSpaceCName>", self
.FileName
, self
.CurrentLineNumber
)
1189 pcdTokenSpaceCName
= self
._Token
1191 if not self
._IsToken
(TAB_SPLIT
):
1192 raise Warning.Expected(".", self
.FileName
, self
.CurrentLineNumber
)
1194 if not self
._GetNextWord
():
1195 raise Warning.Expected("<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1196 pcdCName
= self
._Token
1199 while self
._IsToken
(TAB_SPLIT
):
1200 if not self
._GetNextPcdWord
():
1201 raise Warning.Expected("Pcd Fields", self
.FileName
, self
.CurrentLineNumber
)
1202 Fields
.append(self
._Token
)
1204 return (pcdCName
, pcdTokenSpaceCName
,TAB_SPLIT
.join(Fields
))
1206 ## _GetStringData() method
1208 # Get string contents quoted in ""
1209 # If found, the decimal data is put into self._Token
1211 # @param self The object pointer
1212 # @retval True Successfully find a string data, file buffer pointer moved forward
1213 # @retval False Not able to find a string data, file buffer pointer not changed
1215 def _GetStringData(self
):
1217 if self
._Token
.startswith(T_CHAR_DOUBLE_QUOTE
) or self
._Token
.startswith("L\""):
1218 QuoteToUse
= T_CHAR_DOUBLE_QUOTE
1219 elif self
._Token
.startswith(T_CHAR_SINGLE_QUOTE
) or self
._Token
.startswith("L\'"):
1220 QuoteToUse
= T_CHAR_SINGLE_QUOTE
1225 self
._SkipToToken
(QuoteToUse
)
1226 currentLineNumber
= self
.CurrentLineNumber
1228 if not self
._SkipToToken
(QuoteToUse
):
1229 raise Warning(QuoteToUse
, self
.FileName
, self
.CurrentLineNumber
)
1230 if currentLineNumber
!= self
.CurrentLineNumber
:
1231 raise Warning(QuoteToUse
, self
.FileName
, self
.CurrentLineNumber
)
1232 self
._Token
= self
._SkippedChars
.rstrip(QuoteToUse
)
1235 ## _SkipToToken() method
1237 # Search forward in file buffer for the string
1238 # The skipped chars are put into self._SkippedChars
1240 # @param self The object pointer
1241 # @param String The string to search
1242 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1243 # @retval True Successfully find the string, file buffer pointer moved forward
1244 # @retval False Not able to find the string, file buffer pointer not changed
1246 def _SkipToToken(self
, String
, IgnoreCase
= False):
1247 StartPos
= self
.GetFileBufferPos()
1249 self
._SkippedChars
= ""
1250 while not self
._EndOfFile
():
1253 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
1255 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
1257 self
.CurrentOffsetWithinLine
+= len(String
)
1258 self
._SkippedChars
+= String
1260 self
._SkippedChars
+= str(self
._CurrentChar
())
1263 self
.SetFileBufferPos(StartPos
)
1264 self
._SkippedChars
= ""
1267 ## GetFileBufferPos() method
1269 # Return the tuple of current line and offset within the line
1271 # @param self The object pointer
1272 # @retval Tuple Line number and offset pair
1274 def GetFileBufferPos(self
):
1275 return (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
)
1277 ## SetFileBufferPos() method
1279 # Restore the file buffer position
1281 # @param self The object pointer
1282 # @param Pos The new file buffer position
1284 def SetFileBufferPos(self
, Pos
):
1285 (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
) = Pos
1287 ## Preprocess() method
1289 # Preprocess comment, conditional directive, include directive, replace macro.
1290 # Exception will be raised if syntax error found
1292 # @param self The object pointer
1294 def Preprocess(self
):
1295 self
._StringToList
()
1296 self
.PreprocessFile()
1297 self
.PreprocessIncludeFile()
1298 self
._StringToList
()
1299 self
.PreprocessFile()
1300 self
.PreprocessConditionalStatement()
1301 self
._StringToList
()
1302 for Pos
in self
._WipeOffArea
:
1303 self
._ReplaceFragment
(Pos
[0], Pos
[1])
1304 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
1306 while self
._GetDefines
():
1309 ## ParseFile() method
1311 # Parse the file profile buffer to extract fd, fv ... information
1312 # Exception will be raised if syntax error found
1314 # @param self The object pointer
1316 def ParseFile(self
):
1321 # Keep processing sections of the FDF until no new sections or a syntax error is found
1323 while self
._GetFd
() or self
._GetFv
() or self
._GetFmp
() or self
._GetCapsule
() or self
._GetRule
() or self
._GetOptionRom
():
1326 except Warning as X
:
1328 #'\n\tGot Token: \"%s\" from File %s\n' % (self._Token, FileLineTuple[0]) + \
1329 # At this point, the closest parent would be the included file itself
1330 Profile
= GetParentAtLine(X
.OriginalLineNumber
)
1331 if Profile
is not None:
1332 X
.Message
+= ' near line %d, column %d: %s' \
1333 % (X
.LineNumber
, 0, Profile
.FileLinesList
[X
.LineNumber
-1])
1335 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1336 X
.Message
+= ' near line %d, column %d: %s' \
1337 % (FileLineTuple
[1], self
.CurrentOffsetWithinLine
+ 1, self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:].rstrip(TAB_LINE_BREAK
).rstrip(T_CHAR_CR
))
1340 ## SectionParser() method
1342 # Parse the file section info
1343 # Exception will be raised if syntax error found
1345 # @param self The object pointer
1346 # @param section The section string
1348 def SectionParser(self
, section
):
1350 if not S
.startswith("[DEFINES") and not S
.startswith("[FD.") and not S
.startswith("[FV.") and not S
.startswith("[CAPSULE.") \
1351 and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM.") and not S
.startswith('[FMPPAYLOAD.'):
1352 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self
.FileName
, self
.CurrentLineNumber
)
1354 ## _GetDefines() method
1356 # Get Defines section contents and store its data into AllMacrosList
1358 # @param self The object pointer
1359 # @retval True Successfully find a Defines
1360 # @retval False Not able to find a Defines
1362 def _GetDefines(self
):
1363 if not self
._GetNextToken
():
1366 S
= self
._Token
.upper()
1367 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[DEFINES"):
1368 self
.SectionParser(S
)
1373 if not self
._IsToken
("[DEFINES", True):
1374 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1375 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1376 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1377 raise Warning.Expected("[DEFINES", self
.FileName
, self
.CurrentLineNumber
)
1379 if not self
._IsToken
(TAB_SECTION_END
):
1380 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
1382 while self
._GetNextWord
():
1383 # handle the SET statement
1384 if self
._Token
== 'SET':
1386 self
._GetSetStatement
(None)
1391 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1392 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1393 if not self
._GetNextToken
() or self
._Token
.startswith(TAB_SECTION_START
):
1394 raise Warning.Expected("MACRO value", self
.FileName
, self
.CurrentLineNumber
)
1399 ##_GetError() method
1400 def _GetError(self
):
1401 #save the Current information
1402 CurrentLine
= self
.CurrentLineNumber
1403 CurrentOffset
= self
.CurrentOffsetWithinLine
1404 while self
._GetNextToken
():
1405 if self
._Token
== TAB_ERROR
:
1406 EdkLogger
.error('FdfParser', ERROR_STATEMENT
, self
._CurrentLine
().replace(TAB_ERROR
, '', 1), File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
1407 self
.CurrentLineNumber
= CurrentLine
1408 self
.CurrentOffsetWithinLine
= CurrentOffset
1412 # Get FD section contents and store its data into FD dictionary of self.Profile
1414 # @param self The object pointer
1415 # @retval True Successfully find a FD
1416 # @retval False Not able to find a FD
1419 if not self
._GetNextToken
():
1422 S
= self
._Token
.upper()
1423 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FD."):
1424 if not S
.startswith("[FV.") and not S
.startswith('[FMPPAYLOAD.') and not S
.startswith("[CAPSULE.") \
1425 and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM."):
1426 raise Warning("Unknown section", self
.FileName
, self
.CurrentLineNumber
)
1431 if not self
._IsToken
("[FD.", True):
1432 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1433 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1434 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1435 raise Warning.Expected("[FD.]", self
.FileName
, self
.CurrentLineNumber
)
1437 FdName
= self
._GetUiName
()
1439 if len (self
.Profile
.FdDict
) == 0:
1440 FdName
= GenFdsGlobalVariable
.PlatformName
1441 if FdName
== "" and GlobalData
.gActivePlatform
:
1442 FdName
= GlobalData
.gActivePlatform
.PlatformName
1443 self
.Profile
.FdNameNotSet
= True
1445 raise Warning.Expected("FdName in [FD.] section", self
.FileName
, self
.CurrentLineNumber
)
1446 self
.CurrentFdName
= FdName
.upper()
1448 if self
.CurrentFdName
in self
.Profile
.FdDict
:
1449 raise Warning("Unexpected the same FD name", self
.FileName
, self
.CurrentLineNumber
)
1451 if not self
._IsToken
(TAB_SECTION_END
):
1452 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
1455 FdObj
.FdUiName
= self
.CurrentFdName
1456 self
.Profile
.FdDict
[self
.CurrentFdName
] = FdObj
1458 if len (self
.Profile
.FdDict
) > 1 and self
.Profile
.FdNameNotSet
:
1459 raise Warning.Expected("all FDs have their name", self
.FileName
, self
.CurrentLineNumber
)
1461 Status
= self
._GetCreateFile
(FdObj
)
1463 raise Warning("FD name error", self
.FileName
, self
.CurrentLineNumber
)
1465 while self
._GetTokenStatements
(FdObj
):
1467 for Attr
in ("BaseAddress", "Size", "ErasePolarity"):
1468 if getattr(FdObj
, Attr
) is None:
1469 self
._GetNextToken
()
1470 raise Warning("Keyword %s missing" % Attr
, self
.FileName
, self
.CurrentLineNumber
)
1472 if not FdObj
.BlockSizeList
:
1473 FdObj
.BlockSizeList
.append((1, FdObj
.Size
, None))
1475 self
._GetDefineStatements
(FdObj
)
1477 self
._GetSetStatements
(FdObj
)
1479 if not self
._GetRegionLayout
(FdObj
):
1480 raise Warning.Expected("region layout", self
.FileName
, self
.CurrentLineNumber
)
1482 while self
._GetRegionLayout
(FdObj
):
1486 ## _GetUiName() method
1488 # Return the UI name of a section
1490 # @param self The object pointer
1491 # @retval FdName UI name
1493 def _GetUiName(self
):
1495 if self
._GetNextWord
():
1500 ## _GetCreateFile() method
1502 # Return the output file name of object
1504 # @param self The object pointer
1505 # @param Obj object whose data will be stored in file
1506 # @retval FdName UI name
1508 def _GetCreateFile(self
, Obj
):
1509 if self
._IsKeyword
("CREATE_FILE"):
1510 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1511 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1513 if not self
._GetNextToken
():
1514 raise Warning.Expected("file name", self
.FileName
, self
.CurrentLineNumber
)
1516 FileName
= self
._Token
1517 Obj
.CreateFileName
= FileName
1521 def SetPcdLocalation(self
,pcdpair
):
1522 self
.Profile
.PcdLocalDict
[pcdpair
] = (self
.Profile
.FileName
,self
.CurrentLineNumber
)
1524 ## _GetTokenStatements() method
1526 # Get token statements
1528 # @param self The object pointer
1529 # @param Obj for whom token statement is got
1531 def _GetTokenStatements(self
, Obj
):
1532 if self
._IsKeyword
("BaseAddress"):
1533 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1534 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1536 if not self
._GetNextHexNumber
():
1537 raise Warning.Expected("Hex base address", self
.FileName
, self
.CurrentLineNumber
)
1539 Obj
.BaseAddress
= self
._Token
1541 if self
._IsToken
(TAB_VALUE_SPLIT
):
1542 pcdPair
= self
._GetNextPcdSettings
()
1543 Obj
.BaseAddressPcd
= pcdPair
1544 self
.Profile
.PcdDict
[pcdPair
] = Obj
.BaseAddress
1545 self
.SetPcdLocalation(pcdPair
)
1546 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1547 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1550 if self
._IsKeyword
("Size"):
1551 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1552 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1554 if not self
._GetNextHexNumber
():
1555 raise Warning.Expected("Hex size", self
.FileName
, self
.CurrentLineNumber
)
1558 if self
._IsToken
(TAB_VALUE_SPLIT
):
1559 pcdPair
= self
._GetNextPcdSettings
()
1560 Obj
.SizePcd
= pcdPair
1561 self
.Profile
.PcdDict
[pcdPair
] = Size
1562 self
.SetPcdLocalation(pcdPair
)
1563 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1564 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1565 Obj
.Size
= int(Size
, 0)
1568 if self
._IsKeyword
("ErasePolarity"):
1569 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1570 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1572 if not self
._GetNextToken
():
1573 raise Warning.Expected("Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1575 if not self
._Token
in {"1", "0"}:
1576 raise Warning.Expected("1 or 0 Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1578 Obj
.ErasePolarity
= self
._Token
1581 return self
._GetBlockStatements
(Obj
)
1583 ## _GetAddressStatements() method
1585 # Get address statements
1587 # @param self The object pointer
1588 # @param Obj for whom address statement is got
1589 # @retval True Successfully find
1590 # @retval False Not able to find
1592 def _GetAddressStatements(self
, Obj
):
1593 if self
._IsKeyword
("BsBaseAddress"):
1594 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1595 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1597 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1598 raise Warning.Expected("address", self
.FileName
, self
.CurrentLineNumber
)
1600 BsAddress
= int(self
._Token
, 0)
1601 Obj
.BsBaseAddress
= BsAddress
1603 if self
._IsKeyword
("RtBaseAddress"):
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 RtAddress
= int(self
._Token
, 0)
1611 Obj
.RtBaseAddress
= RtAddress
1613 ## _GetBlockStatements() method
1615 # Get block statements
1617 # @param self The object pointer
1618 # @param Obj for whom block statement is got
1620 def _GetBlockStatements(self
, Obj
):
1622 while self
._GetBlockStatement
(Obj
):
1625 Item
= Obj
.BlockSizeList
[-1]
1626 if Item
[0] is None or Item
[1] is None:
1627 raise Warning.Expected("block statement", self
.FileName
, self
.CurrentLineNumber
)
1630 ## _GetBlockStatement() method
1632 # Get block statement
1634 # @param self The object pointer
1635 # @param Obj for whom block statement is got
1636 # @retval True Successfully find
1637 # @retval False Not able to find
1639 def _GetBlockStatement(self
, Obj
):
1640 if not self
._IsKeyword
("BlockSize"):
1643 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1644 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1646 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
1647 raise Warning.Expected("Hex or Integer block size", self
.FileName
, self
.CurrentLineNumber
)
1649 BlockSize
= self
._Token
1651 if self
._IsToken
(TAB_VALUE_SPLIT
):
1652 PcdPair
= self
._GetNextPcdSettings
()
1653 BlockSizePcd
= PcdPair
1654 self
.Profile
.PcdDict
[PcdPair
] = BlockSize
1655 self
.SetPcdLocalation(PcdPair
)
1656 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1657 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1658 BlockSize
= int(BlockSize
, 0)
1661 if self
._IsKeyword
("NumBlocks"):
1662 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1663 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1665 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1666 raise Warning.Expected("block numbers", self
.FileName
, self
.CurrentLineNumber
)
1668 BlockNumber
= int(self
._Token
, 0)
1670 Obj
.BlockSizeList
.append((BlockSize
, BlockNumber
, BlockSizePcd
))
1673 ## _GetDefineStatements() method
1675 # Get define statements
1677 # @param self The object pointer
1678 # @param Obj for whom define statement is got
1679 # @retval True Successfully find
1680 # @retval False Not able to find
1682 def _GetDefineStatements(self
, Obj
):
1683 while self
._GetDefineStatement
(Obj
):
1686 ## _GetDefineStatement() method
1688 # Get define statement
1690 # @param self The object pointer
1691 # @param Obj for whom define statement is got
1692 # @retval True Successfully find
1693 # @retval False Not able to find
1695 def _GetDefineStatement(self
, Obj
):
1696 if self
._IsKeyword
(TAB_DEFINE
):
1697 self
._GetNextToken
()
1699 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1700 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1702 if not self
._GetNextToken
():
1703 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
1706 Macro
= '$(' + Macro
+ ')'
1707 Obj
.DefineVarDict
[Macro
] = Value
1712 ## _GetSetStatements() method
1714 # Get set statements
1716 # @param self The object pointer
1717 # @param Obj for whom set statement is got
1718 # @retval True Successfully find
1719 # @retval False Not able to find
1721 def _GetSetStatements(self
, Obj
):
1722 while self
._GetSetStatement
(Obj
):
1725 ## _GetSetStatement() method
1729 # @param self The object pointer
1730 # @param Obj for whom set statement is got
1731 # @retval True Successfully find
1732 # @retval False Not able to find
1734 def _GetSetStatement(self
, Obj
):
1735 if self
._IsKeyword
("SET"):
1736 PcdPair
= self
._GetNextPcdSettings
()
1738 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1739 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1741 Value
= self
._GetExpression
()
1742 Value
= self
._EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
1745 Obj
.SetVarDict
[PcdPair
] = Value
1746 self
.Profile
.PcdDict
[PcdPair
] = Value
1747 self
.SetPcdLocalation(PcdPair
)
1748 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1749 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1754 ## _CalcRegionExpr(self)
1756 # Calculate expression for offset or size of a region
1758 # @return: None if invalid expression
1759 # Calculated number if successfully
1761 def _CalcRegionExpr(self
):
1762 StartPos
= self
.GetFileBufferPos()
1765 while not self
._EndOfFile
():
1766 CurCh
= self
._CurrentChar
()
1772 if CurCh
in '|\r\n' and PairCount
== 0:
1778 ValueExpression(Expr
,
1779 self
._CollectMacroPcd
()
1782 self
.SetFileBufferPos(StartPos
)
1785 ## _GetRegionLayout() method
1787 # Get region layout for FD
1789 # @param self The object pointer
1790 # @param theFd for whom region is got
1791 # @retval True Successfully find
1792 # @retval False Not able to find
1794 def _GetRegionLayout(self
, theFd
):
1795 Offset
= self
._CalcRegionExpr
()
1799 RegionObj
= Region()
1800 RegionObj
.Offset
= Offset
1801 theFd
.RegionList
.append(RegionObj
)
1803 if not self
._IsToken
(TAB_VALUE_SPLIT
):
1804 raise Warning.Expected("'|'", self
.FileName
, self
.CurrentLineNumber
)
1806 Size
= self
._CalcRegionExpr
()
1808 raise Warning.Expected("Region Size", self
.FileName
, self
.CurrentLineNumber
)
1809 RegionObj
.Size
= Size
1811 if not self
._GetNextWord
():
1814 if not self
._Token
in {"SET", BINARY_FILE_TYPE_FV
, "FILE", "DATA", "CAPSULE", "INF"}:
1816 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1817 # Or it might be next region's offset described by an expression which starts with a PCD.
1818 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1821 IsRegionPcd
= (RegionSizeGuidPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]) or
1822 RegionOffsetPcdPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]))
1824 RegionObj
.PcdOffset
= self
._GetNextPcdSettings
()
1825 self
.Profile
.PcdDict
[RegionObj
.PcdOffset
] = "0x%08X" % (RegionObj
.Offset
+ int(theFd
.BaseAddress
, 0))
1826 self
.SetPcdLocalation(RegionObj
.PcdOffset
)
1827 self
._PcdDict
['%s.%s' % (RegionObj
.PcdOffset
[1], RegionObj
.PcdOffset
[0])] = "0x%x" % RegionObj
.Offset
1828 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1829 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdOffset
] = FileLineTuple
1830 if self
._IsToken
(TAB_VALUE_SPLIT
):
1831 RegionObj
.PcdSize
= self
._GetNextPcdSettings
()
1832 self
.Profile
.PcdDict
[RegionObj
.PcdSize
] = "0x%08X" % RegionObj
.Size
1833 self
.SetPcdLocalation(RegionObj
.PcdSize
)
1834 self
._PcdDict
['%s.%s' % (RegionObj
.PcdSize
[1], RegionObj
.PcdSize
[0])] = "0x%x" % RegionObj
.Size
1835 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1836 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdSize
] = FileLineTuple
1838 if not self
._GetNextWord
():
1841 if self
._Token
== "SET":
1843 self
._GetSetStatements
(RegionObj
)
1844 if not self
._GetNextWord
():
1847 elif self
._Token
== BINARY_FILE_TYPE_FV
:
1849 self
._GetRegionFvType
(RegionObj
)
1851 elif self
._Token
== "CAPSULE":
1853 self
._GetRegionCapType
(RegionObj
)
1855 elif self
._Token
== "FILE":
1857 self
._GetRegionFileType
(RegionObj
)
1859 elif self
._Token
== "INF":
1861 RegionObj
.RegionType
= "INF"
1862 while self
._IsKeyword
("INF"):
1864 ffsInf
= self
._ParseInfStatement
()
1867 RegionObj
.RegionDataList
.append(ffsInf
)
1869 elif self
._Token
== "DATA":
1871 self
._GetRegionDataType
(RegionObj
)
1874 if self
._GetRegionLayout
(theFd
):
1876 raise Warning("A valid region type was not found. "
1877 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
1878 self
.FileName
, self
.CurrentLineNumber
)
1882 ## _GetRegionFvType() method
1884 # Get region fv data for region
1886 # @param self The object pointer
1887 # @param RegionObj for whom region data is got
1889 def _GetRegionFvType(self
, RegionObj
):
1890 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1891 raise Warning.Expected("'FV'", self
.FileName
, self
.CurrentLineNumber
)
1893 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1894 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1896 if not self
._GetNextToken
():
1897 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
1899 RegionObj
.RegionType
= BINARY_FILE_TYPE_FV
1900 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1902 while self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1904 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1905 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1907 if not self
._GetNextToken
():
1908 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
1910 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1912 ## _GetRegionCapType() method
1914 # Get region capsule data for region
1916 # @param self The object pointer
1917 # @param RegionObj for whom region data is got
1919 def _GetRegionCapType(self
, RegionObj
):
1920 if not self
._IsKeyword
("CAPSULE"):
1921 raise Warning.Expected("'CAPSULE'", self
.FileName
, self
.CurrentLineNumber
)
1923 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1924 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1926 if not self
._GetNextToken
():
1927 raise Warning.Expected("CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1929 RegionObj
.RegionType
= "CAPSULE"
1930 RegionObj
.RegionDataList
.append(self
._Token
)
1932 while self
._IsKeyword
("CAPSULE"):
1934 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1935 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1937 if not self
._GetNextToken
():
1938 raise Warning.Expected("CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1940 RegionObj
.RegionDataList
.append(self
._Token
)
1942 ## _GetRegionFileType() method
1944 # Get region file data for region
1946 # @param self The object pointer
1947 # @param RegionObj for whom region data is got
1949 def _GetRegionFileType(self
, RegionObj
):
1950 if not self
._IsKeyword
("FILE"):
1951 raise Warning.Expected("'FILE'", self
.FileName
, self
.CurrentLineNumber
)
1953 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1954 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1956 if not self
._GetNextToken
():
1957 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
1959 RegionObj
.RegionType
= "FILE"
1960 RegionObj
.RegionDataList
.append(self
._Token
)
1962 while self
._IsKeyword
("FILE"):
1964 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1965 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1967 if not self
._GetNextToken
():
1968 raise Warning.Expected("FILE name", self
.FileName
, self
.CurrentLineNumber
)
1970 RegionObj
.RegionDataList
.append(self
._Token
)
1972 ## _GetRegionDataType() method
1974 # Get region array data for region
1976 # @param self The object pointer
1977 # @param RegionObj for whom region data is got
1979 def _GetRegionDataType(self
, RegionObj
):
1980 if not self
._IsKeyword
("DATA"):
1981 raise Warning.Expected("Region Data type", self
.FileName
, self
.CurrentLineNumber
)
1983 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1984 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1986 if not self
._IsToken
("{"):
1987 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
1989 if not self
._GetNextHexNumber
():
1990 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
1992 if len(self
._Token
) > 18:
1993 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
1995 # convert hex string value to byte hex string array
1996 AllString
= self
._Token
1997 AllStrLen
= len (AllString
)
1999 while AllStrLen
> 4:
2000 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
2001 AllStrLen
= AllStrLen
- 2
2002 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
2005 if len (self
._Token
) <= 4:
2006 while self
._IsToken
(TAB_COMMA_SPLIT
):
2007 if not self
._GetNextHexNumber
():
2008 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2009 if len(self
._Token
) > 4:
2010 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2011 DataString
+= self
._Token
2012 DataString
+= TAB_COMMA_SPLIT
2014 if not self
._IsToken
(T_CHAR_BRACE_R
):
2015 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2017 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2018 RegionObj
.RegionType
= "DATA"
2019 RegionObj
.RegionDataList
.append(DataString
)
2021 while self
._IsKeyword
("DATA"):
2023 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2024 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2026 if not self
._IsToken
("{"):
2027 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2029 if not self
._GetNextHexNumber
():
2030 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2032 if len(self
._Token
) > 18:
2033 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2035 # convert hex string value to byte hex string array
2036 AllString
= self
._Token
2037 AllStrLen
= len (AllString
)
2039 while AllStrLen
> 4:
2040 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
2041 AllStrLen
= AllStrLen
- 2
2042 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
2045 if len (self
._Token
) <= 4:
2046 while self
._IsToken
(TAB_COMMA_SPLIT
):
2047 if not self
._GetNextHexNumber
():
2048 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2049 if len(self
._Token
) > 4:
2050 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2051 DataString
+= self
._Token
2052 DataString
+= TAB_COMMA_SPLIT
2054 if not self
._IsToken
(T_CHAR_BRACE_R
):
2055 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2057 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2058 RegionObj
.RegionDataList
.append(DataString
)
2062 # Get FV section contents and store its data into FV dictionary of self.Profile
2064 # @param self The object pointer
2065 # @retval True Successfully find a FV
2066 # @retval False Not able to find a FV
2069 if not self
._GetNextToken
():
2072 S
= self
._Token
.upper()
2073 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FV."):
2074 self
.SectionParser(S
)
2079 if not self
._IsToken
("[FV.", True):
2080 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2081 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2082 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2083 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2085 FvName
= self
._GetUiName
()
2086 self
.CurrentFvName
= FvName
.upper()
2088 if not self
._IsToken
(TAB_SECTION_END
):
2089 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
2091 FvObj
= FV(Name
=self
.CurrentFvName
)
2092 self
.Profile
.FvDict
[self
.CurrentFvName
] = FvObj
2094 Status
= self
._GetCreateFile
(FvObj
)
2096 raise Warning("FV name error", self
.FileName
, self
.CurrentLineNumber
)
2098 self
._GetDefineStatements
(FvObj
)
2100 self
._GetAddressStatements
(FvObj
)
2103 self
._GetSetStatements
(FvObj
)
2105 if not (self
._GetBlockStatement
(FvObj
) or self
._GetFvBaseAddress
(FvObj
) or
2106 self
._GetFvForceRebase
(FvObj
) or self
._GetFvAlignment
(FvObj
) or
2107 self
._GetFvAttributes
(FvObj
) or self
._GetFvNameGuid
(FvObj
) or
2108 self
._GetFvExtEntryStatement
(FvObj
) or self
._GetFvNameString
(FvObj
)):
2111 if FvObj
.FvNameString
== 'TRUE' and not FvObj
.FvNameGuid
:
2112 raise Warning("FvNameString found but FvNameGuid was not found", self
.FileName
, self
.CurrentLineNumber
)
2114 self
._GetAprioriSection
(FvObj
)
2115 self
._GetAprioriSection
(FvObj
)
2118 isInf
= self
._GetInfStatement
(FvObj
)
2119 isFile
= self
._GetFileStatement
(FvObj
)
2120 if not isInf
and not isFile
:
2125 ## _GetFvAlignment() method
2127 # Get alignment for FV
2129 # @param self The object pointer
2130 # @param Obj for whom alignment is got
2131 # @retval True Successfully find a alignment statement
2132 # @retval False Not able to find a alignment statement
2134 def _GetFvAlignment(self
, Obj
):
2135 if not self
._IsKeyword
("FvAlignment"):
2138 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2139 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2141 if not self
._GetNextToken
():
2142 raise Warning.Expected("alignment value", self
.FileName
, self
.CurrentLineNumber
)
2144 if self
._Token
.upper() not in {"1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2145 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2146 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2148 raise Warning("Unknown alignment value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2149 Obj
.FvAlignment
= self
._Token
2152 ## _GetFvBaseAddress() method
2154 # Get BaseAddress for FV
2156 # @param self The object pointer
2157 # @param Obj for whom FvBaseAddress is got
2158 # @retval True Successfully find a FvBaseAddress statement
2159 # @retval False Not able to find a FvBaseAddress statement
2161 def _GetFvBaseAddress(self
, Obj
):
2162 if not self
._IsKeyword
("FvBaseAddress"):
2165 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2166 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2168 if not self
._GetNextToken
():
2169 raise Warning.Expected("FV base address value", self
.FileName
, self
.CurrentLineNumber
)
2171 if not BaseAddrValuePattern
.match(self
._Token
.upper()):
2172 raise Warning("Unknown FV base address value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2173 Obj
.FvBaseAddress
= self
._Token
2176 ## _GetFvForceRebase() method
2178 # Get FvForceRebase for FV
2180 # @param self The object pointer
2181 # @param Obj for whom FvForceRebase is got
2182 # @retval True Successfully find a FvForceRebase statement
2183 # @retval False Not able to find a FvForceRebase statement
2185 def _GetFvForceRebase(self
, Obj
):
2186 if not self
._IsKeyword
("FvForceRebase"):
2189 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2190 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2192 if not self
._GetNextToken
():
2193 raise Warning.Expected("FvForceRebase value", self
.FileName
, self
.CurrentLineNumber
)
2195 if self
._Token
.upper() not in {"TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"}:
2196 raise Warning("Unknown FvForceRebase value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2198 if self
._Token
.upper() in {"TRUE", "1", "0X1", "0X01"}:
2199 Obj
.FvForceRebase
= True
2200 elif self
._Token
.upper() in {"FALSE", "0", "0X0", "0X00"}:
2201 Obj
.FvForceRebase
= False
2203 Obj
.FvForceRebase
= None
2208 ## _GetFvAttributes() method
2210 # Get attributes for FV
2212 # @param self The object pointer
2213 # @param Obj for whom attribute is got
2216 def _GetFvAttributes(self
, FvObj
):
2218 while self
._GetNextWord
():
2221 if name
not in {"ERASE_POLARITY", "MEMORY_MAPPED", \
2222 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2223 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2224 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2225 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2226 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"}:
2230 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2231 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2233 if not self
._GetNextToken
() or self
._Token
.upper() not in {"TRUE", "FALSE", "1", "0"}:
2234 raise Warning.Expected("TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
2236 FvObj
.FvAttributeDict
[name
] = self
._Token
2240 ## _GetFvNameGuid() method
2242 # Get FV GUID for FV
2244 # @param self The object pointer
2245 # @param Obj for whom GUID is got
2248 def _GetFvNameGuid(self
, FvObj
):
2249 if not self
._IsKeyword
("FvNameGuid"):
2252 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2253 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2255 if not self
._GetNextGuid
():
2256 raise Warning.Expected("GUID value", self
.FileName
, self
.CurrentLineNumber
)
2258 FvObj
.FvNameGuid
= self
._Token
2262 def _GetFvNameString(self
, FvObj
):
2263 if not self
._IsKeyword
("FvNameString"):
2266 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2267 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2269 if not self
._GetNextToken
() or self
._Token
.upper() not in {'TRUE', 'FALSE'}:
2270 raise Warning.Expected("TRUE or FALSE for FvNameString", self
.FileName
, self
.CurrentLineNumber
)
2272 FvObj
.FvNameString
= self
._Token
2276 def _GetFvExtEntryStatement(self
, FvObj
):
2277 if not (self
._IsKeyword
("FV_EXT_ENTRY") or self
._IsKeyword
("FV_EXT_ENTRY_TYPE")):
2280 if not self
._IsKeyword
("TYPE"):
2281 raise Warning.Expected("'TYPE'", self
.FileName
, self
.CurrentLineNumber
)
2283 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2284 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2286 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
2287 raise Warning.Expected("Hex FV extension entry type value At Line ", self
.FileName
, self
.CurrentLineNumber
)
2289 FvObj
.FvExtEntryTypeValue
.append(self
._Token
)
2291 if not self
._IsToken
("{"):
2292 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2294 if not self
._IsKeyword
("FILE") and not self
._IsKeyword
("DATA"):
2295 raise Warning.Expected("'FILE' or 'DATA'", self
.FileName
, self
.CurrentLineNumber
)
2297 FvObj
.FvExtEntryType
.append(self
._Token
)
2299 if self
._Token
== 'DATA':
2300 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2301 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2303 if not self
._IsToken
("{"):
2304 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2306 if not self
._GetNextHexNumber
():
2307 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2309 if len(self
._Token
) > 4:
2310 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2312 DataString
= self
._Token
2313 DataString
+= TAB_COMMA_SPLIT
2315 while self
._IsToken
(TAB_COMMA_SPLIT
):
2316 if not self
._GetNextHexNumber
():
2317 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2318 if len(self
._Token
) > 4:
2319 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2320 DataString
+= self
._Token
2321 DataString
+= TAB_COMMA_SPLIT
2323 if not self
._IsToken
(T_CHAR_BRACE_R
):
2324 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2326 if not self
._IsToken
(T_CHAR_BRACE_R
):
2327 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2329 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2330 FvObj
.FvExtEntryData
.append(DataString
)
2332 if self
._Token
== 'FILE':
2333 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2334 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2336 if not self
._GetNextToken
():
2337 raise Warning.Expected("FV Extension Entry file path At Line ", self
.FileName
, self
.CurrentLineNumber
)
2339 FvObj
.FvExtEntryData
.append(self
._Token
)
2341 if not self
._IsToken
(T_CHAR_BRACE_R
):
2342 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2346 ## _GetAprioriSection() method
2348 # Get token statements
2350 # @param self The object pointer
2351 # @param FvObj for whom apriori is got
2352 # @retval True Successfully find apriori statement
2353 # @retval False Not able to find apriori statement
2355 def _GetAprioriSection(self
, FvObj
):
2356 if not self
._IsKeyword
("APRIORI"):
2359 if not self
._IsKeyword
("PEI") and not self
._IsKeyword
("DXE"):
2360 raise Warning.Expected("Apriori file type", self
.FileName
, self
.CurrentLineNumber
)
2361 AprType
= self
._Token
2363 if not self
._IsToken
("{"):
2364 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2366 AprSectionObj
= AprioriSection()
2367 AprSectionObj
.AprioriType
= AprType
2369 self
._GetDefineStatements
(AprSectionObj
)
2372 IsInf
= self
._GetInfStatement
(AprSectionObj
)
2373 IsFile
= self
._GetFileStatement
(AprSectionObj
)
2374 if not IsInf
and not IsFile
:
2377 if not self
._IsToken
(T_CHAR_BRACE_R
):
2378 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2380 FvObj
.AprioriSectionList
.append(AprSectionObj
)
2383 def _ParseInfStatement(self
):
2384 if not self
._IsKeyword
("INF"):
2387 ffsInf
= FfsInfStatement()
2388 self
._GetInfOptions
(ffsInf
)
2390 if not self
._GetNextToken
():
2391 raise Warning.Expected("INF file path", self
.FileName
, self
.CurrentLineNumber
)
2392 ffsInf
.InfFileName
= self
._Token
2393 if not ffsInf
.InfFileName
.endswith('.inf'):
2394 raise Warning.Expected(".inf file path", self
.FileName
, self
.CurrentLineNumber
)
2396 ffsInf
.CurrentLineNum
= self
.CurrentLineNumber
2397 ffsInf
.CurrentLineContent
= self
._CurrentLine
()
2399 #Replace $(SAPCE) with real space
2400 ffsInf
.InfFileName
= ffsInf
.InfFileName
.replace('$(SPACE)', ' ')
2402 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
2403 #do case sensitive check for file path
2404 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2406 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2408 NewFileName
= ffsInf
.InfFileName
2409 if ffsInf
.OverrideGuid
:
2410 NewFileName
= ProcessDuplicatedInf(PathClass(ffsInf
.InfFileName
,GenFdsGlobalVariable
.WorkSpaceDir
), ffsInf
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
).Path
2412 if not NewFileName
in self
.Profile
.InfList
:
2413 self
.Profile
.InfList
.append(NewFileName
)
2414 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2415 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
2417 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
2418 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
2420 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
2422 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
2424 if self
._IsToken
(TAB_VALUE_SPLIT
):
2425 if self
._IsKeyword
('RELOCS_STRIPPED'):
2426 ffsInf
.KeepReloc
= False
2427 elif self
._IsKeyword
('RELOCS_RETAINED'):
2428 ffsInf
.KeepReloc
= True
2430 raise Warning("Unknown reloc strip flag '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2433 ## _GetInfStatement() method
2435 # Get INF statements
2437 # @param self The object pointer
2438 # @param Obj for whom inf statement is got
2439 # @retval True Successfully find inf statement
2440 # @retval False Not able to find inf statement
2442 def _GetInfStatement(self
, Obj
, ForCapsule
=False):
2443 ffsInf
= self
._ParseInfStatement
()
2448 myCapsuleFfs
= CapsuleFfs()
2449 myCapsuleFfs
.Ffs
= ffsInf
2450 Obj
.CapsuleDataList
.append(myCapsuleFfs
)
2452 Obj
.FfsList
.append(ffsInf
)
2455 ## _GetInfOptions() method
2457 # Get options for INF
2459 # @param self The object pointer
2460 # @param FfsInfObj for whom option is got
2462 def _GetInfOptions(self
, FfsInfObj
):
2463 if self
._IsKeyword
("FILE_GUID"):
2464 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2465 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2466 if not self
._GetNextGuid
():
2467 raise Warning.Expected("GUID value", self
.FileName
, self
.CurrentLineNumber
)
2468 FfsInfObj
.OverrideGuid
= self
._Token
2470 if self
._IsKeyword
("RuleOverride"):
2471 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2472 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2473 if not self
._GetNextToken
():
2474 raise Warning.Expected("Rule name", self
.FileName
, self
.CurrentLineNumber
)
2475 FfsInfObj
.Rule
= self
._Token
2477 if self
._IsKeyword
("VERSION"):
2478 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2479 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2480 if not self
._GetNextToken
():
2481 raise Warning.Expected("Version", self
.FileName
, self
.CurrentLineNumber
)
2483 if self
._GetStringData
():
2484 FfsInfObj
.Version
= self
._Token
2486 if self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2487 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2488 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2489 if not self
._GetNextToken
():
2490 raise Warning.Expected("UI name", self
.FileName
, self
.CurrentLineNumber
)
2492 if self
._GetStringData
():
2493 FfsInfObj
.Ui
= self
._Token
2495 if self
._IsKeyword
("USE"):
2496 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2497 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2498 if not self
._GetNextToken
():
2499 raise Warning.Expected("ARCH name", self
.FileName
, self
.CurrentLineNumber
)
2500 FfsInfObj
.UseArch
= self
._Token
2503 if self
._GetNextToken
():
2504 p
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2505 if p
.match(self
._Token
) and p
.match(self
._Token
).span()[1] == len(self
._Token
):
2506 FfsInfObj
.KeyStringList
.append(self
._Token
)
2507 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2513 while self
._GetNextToken
():
2514 if not p
.match(self
._Token
):
2515 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2516 FfsInfObj
.KeyStringList
.append(self
._Token
)
2518 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2521 ## _GetFileStatement() method
2523 # Get FILE statements
2525 # @param self The object pointer
2526 # @param Obj for whom FILE statement is got
2527 # @retval True Successfully find FILE statement
2528 # @retval False Not able to find FILE statement
2530 def _GetFileStatement(self
, Obj
, ForCapsule
= False):
2531 if not self
._IsKeyword
("FILE"):
2534 if not self
._GetNextWord
():
2535 raise Warning.Expected("FFS type", self
.FileName
, self
.CurrentLineNumber
)
2537 if ForCapsule
and self
._Token
== 'DATA':
2542 FfsFileObj
= FileStatement()
2543 FfsFileObj
.FvFileType
= self
._Token
2545 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2546 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2548 if not self
._GetNextGuid
():
2549 if not self
._GetNextWord
():
2550 raise Warning.Expected("File GUID", self
.FileName
, self
.CurrentLineNumber
)
2551 if self
._Token
== 'PCD':
2552 if not self
._IsToken
("("):
2553 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
2554 PcdPair
= self
._GetNextPcdSettings
()
2555 if not self
._IsToken
(")"):
2556 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
2557 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
2559 FfsFileObj
.NameGuid
= self
._Token
2561 self
._GetFilePart
(FfsFileObj
)
2564 capsuleFfs
= CapsuleFfs()
2565 capsuleFfs
.Ffs
= FfsFileObj
2566 Obj
.CapsuleDataList
.append(capsuleFfs
)
2568 Obj
.FfsList
.append(FfsFileObj
)
2572 ## _FileCouldHaveRelocFlag() method
2574 # Check whether reloc strip flag can be set for a file type.
2576 # @param FileType The file type to check with
2577 # @retval True This type could have relocation strip flag
2578 # @retval False No way to have it
2581 def _FileCouldHaveRelocFlag (FileType
):
2582 if FileType
in {SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
, SUP_MODULE_MM_CORE_STANDALONE
, 'PEI_DXE_COMBO'}:
2587 ## _SectionCouldHaveRelocFlag() method
2589 # Check whether reloc strip flag can be set for a section type.
2591 # @param SectionType The section type to check with
2592 # @retval True This type could have relocation strip flag
2593 # @retval False No way to have it
2596 def _SectionCouldHaveRelocFlag (SectionType
):
2597 if SectionType
in {BINARY_FILE_TYPE_TE
, BINARY_FILE_TYPE_PE32
}:
2602 ## _GetFilePart() method
2604 # Get components for FILE statement
2606 # @param self The object pointer
2607 # @param FfsFileObj for whom component is got
2609 def _GetFilePart(self
, FfsFileObj
):
2610 self
._GetFileOpts
(FfsFileObj
)
2612 if not self
._IsToken
("{"):
2613 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2614 if self
._FileCouldHaveRelocFlag
(FfsFileObj
.FvFileType
):
2615 if self
._Token
== 'RELOCS_STRIPPED':
2616 FfsFileObj
.KeepReloc
= False
2618 FfsFileObj
.KeepReloc
= True
2620 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj
.FvFileType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
2622 if not self
._IsToken
("{"):
2623 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2625 if not self
._GetNextToken
():
2626 raise Warning.Expected("File name or section data", self
.FileName
, self
.CurrentLineNumber
)
2628 if self
._Token
== BINARY_FILE_TYPE_FV
:
2629 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2630 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2631 if not self
._GetNextToken
():
2632 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
2633 FfsFileObj
.FvName
= self
._Token
2635 elif self
._Token
== "FD":
2636 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2637 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2638 if not self
._GetNextToken
():
2639 raise Warning.Expected("FD name", self
.FileName
, self
.CurrentLineNumber
)
2640 FfsFileObj
.FdName
= self
._Token
2642 elif self
._Token
in {TAB_DEFINE
, "APRIORI", "SECTION"}:
2644 self
._GetSectionData
(FfsFileObj
)
2646 elif hasattr(FfsFileObj
, 'FvFileType') and FfsFileObj
.FvFileType
== 'RAW':
2648 self
._GetRAWData
(FfsFileObj
)
2651 FfsFileObj
.CurrentLineNum
= self
.CurrentLineNumber
2652 FfsFileObj
.CurrentLineContent
= self
._CurrentLine
()
2653 FfsFileObj
.FileName
= self
._Token
.replace('$(SPACE)', ' ')
2654 self
._VerifyFile
(FfsFileObj
.FileName
)
2656 if not self
._IsToken
(T_CHAR_BRACE_R
):
2657 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2659 ## _GetRAWData() method
2661 # Get RAW data for FILE statement
2663 # @param self The object pointer
2664 # @param FfsFileObj for whom section is got
2666 def _GetRAWData(self
, FfsFileObj
):
2667 FfsFileObj
.FileName
= []
2668 FfsFileObj
.SubAlignment
= []
2671 if self
._GetAlignment
():
2672 if self
._Token
not in ALIGNMENTS
:
2673 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2674 #For FFS, Auto is default option same to ""
2675 if not self
._Token
== "Auto":
2676 AlignValue
= self
._Token
2677 if not self
._GetNextToken
():
2678 raise Warning.Expected("Filename value", self
.FileName
, self
.CurrentLineNumber
)
2680 FileName
= self
._Token
.replace('$(SPACE)', ' ')
2681 if FileName
== T_CHAR_BRACE_R
:
2683 raise Warning.Expected("Filename value", self
.FileName
, self
.CurrentLineNumber
)
2685 self
._VerifyFile
(FileName
)
2686 File
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
)
2687 FfsFileObj
.FileName
.append(File
.Path
)
2688 FfsFileObj
.SubAlignment
.append(AlignValue
)
2690 if self
._IsToken
(T_CHAR_BRACE_R
):
2694 if len(FfsFileObj
.SubAlignment
) == 1:
2695 FfsFileObj
.SubAlignment
= FfsFileObj
.SubAlignment
[0]
2696 if len(FfsFileObj
.FileName
) == 1:
2697 FfsFileObj
.FileName
= FfsFileObj
.FileName
[0]
2699 ## _GetFileOpts() method
2701 # Get options for FILE statement
2703 # @param self The object pointer
2704 # @param FfsFileObj for whom options is got
2706 def _GetFileOpts(self
, FfsFileObj
):
2707 if self
._GetNextToken
():
2708 if TokenFindPattern
.match(self
._Token
):
2709 FfsFileObj
.KeyStringList
.append(self
._Token
)
2710 if self
._IsToken
(TAB_COMMA_SPLIT
):
2711 while self
._GetNextToken
():
2712 if not TokenFindPattern
.match(self
._Token
):
2713 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2714 FfsFileObj
.KeyStringList
.append(self
._Token
)
2716 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2722 if self
._IsKeyword
("FIXED", True):
2723 FfsFileObj
.Fixed
= True
2725 if self
._IsKeyword
("CHECKSUM", True):
2726 FfsFileObj
.CheckSum
= True
2728 if self
._GetAlignment
():
2729 if self
._Token
not in ALIGNMENTS
:
2730 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2731 #For FFS, Auto is default option same to ""
2732 if not self
._Token
== "Auto":
2733 FfsFileObj
.Alignment
= self
._Token
2735 ## _GetAlignment() method
2737 # Return the alignment value
2739 # @param self The object pointer
2740 # @retval True Successfully find alignment
2741 # @retval False Not able to find alignment
2743 def _GetAlignment(self
):
2744 if self
._IsKeyword
("Align", True):
2745 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2746 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2748 if not self
._GetNextToken
():
2749 raise Warning.Expected("alignment value", self
.FileName
, self
.CurrentLineNumber
)
2754 ## _GetSectionData() method
2756 # Get section data for FILE statement
2758 # @param self The object pointer
2759 # @param FfsFileObj for whom section is got
2761 def _GetSectionData(self
, FfsFileObj
):
2762 self
._GetDefineStatements
(FfsFileObj
)
2765 IsLeafSection
= self
._GetLeafSection
(FfsFileObj
)
2766 IsEncapSection
= self
._GetEncapsulationSec
(FfsFileObj
)
2767 if not IsLeafSection
and not IsEncapSection
:
2770 ## _GetLeafSection() method
2772 # Get leaf section for Obj
2774 # @param self The object pointer
2775 # @param Obj for whom leaf section is got
2776 # @retval True Successfully find section statement
2777 # @retval False Not able to find section statement
2779 def _GetLeafSection(self
, Obj
):
2780 OldPos
= self
.GetFileBufferPos()
2782 if not self
._IsKeyword
("SECTION"):
2783 if len(Obj
.SectionList
) == 0:
2784 raise Warning.Expected("SECTION", self
.FileName
, self
.CurrentLineNumber
)
2789 if self
._GetAlignment
():
2790 if self
._Token
not in ALIGNMENTS
:
2791 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2792 AlignValue
= self
._Token
2795 if self
._IsKeyword
("BUILD_NUM"):
2796 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2797 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2799 if not self
._GetNextToken
():
2800 raise Warning.Expected("Build number value", self
.FileName
, self
.CurrentLineNumber
)
2802 BuildNum
= self
._Token
2804 if self
._IsKeyword
("VERSION"):
2805 if AlignValue
== 'Auto':
2806 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2807 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2808 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2809 if not self
._GetNextToken
():
2810 raise Warning.Expected("version", self
.FileName
, self
.CurrentLineNumber
)
2811 VerSectionObj
= VerSection()
2812 VerSectionObj
.Alignment
= AlignValue
2813 VerSectionObj
.BuildNum
= BuildNum
2814 if self
._GetStringData
():
2815 VerSectionObj
.StringData
= self
._Token
2817 VerSectionObj
.FileName
= self
._Token
2818 Obj
.SectionList
.append(VerSectionObj
)
2820 elif self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2821 if AlignValue
== 'Auto':
2822 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2823 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2824 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2825 if not self
._GetNextToken
():
2826 raise Warning.Expected("UI", self
.FileName
, self
.CurrentLineNumber
)
2827 UiSectionObj
= UiSection()
2828 UiSectionObj
.Alignment
= AlignValue
2829 if self
._GetStringData
():
2830 UiSectionObj
.StringData
= self
._Token
2832 UiSectionObj
.FileName
= self
._Token
2833 Obj
.SectionList
.append(UiSectionObj
)
2835 elif self
._IsKeyword
("FV_IMAGE"):
2836 if AlignValue
== 'Auto':
2837 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2838 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2839 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2840 if not self
._GetNextToken
():
2841 raise Warning.Expected("FV name or FV file path", self
.FileName
, self
.CurrentLineNumber
)
2843 FvName
= self
._Token
2846 if self
._IsToken
("{"):
2848 FvObj
.UiFvName
= FvName
.upper()
2849 self
._GetDefineStatements
(FvObj
)
2851 self
._GetBlockStatement
(FvObj
)
2852 self
._GetSetStatements
(FvObj
)
2853 self
._GetFvAlignment
(FvObj
)
2854 self
._GetFvAttributes
(FvObj
)
2857 IsInf
= self
._GetInfStatement
(FvObj
)
2858 IsFile
= self
._GetFileStatement
(FvObj
)
2859 if not IsInf
and not IsFile
:
2862 if not self
._IsToken
(T_CHAR_BRACE_R
):
2863 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2865 FvImageSectionObj
= FvImageSection()
2866 FvImageSectionObj
.Alignment
= AlignValue
2867 if FvObj
is not None:
2868 FvImageSectionObj
.Fv
= FvObj
2869 FvImageSectionObj
.FvName
= None
2871 FvImageSectionObj
.FvName
= FvName
.upper()
2872 FvImageSectionObj
.FvFileName
= FvName
2874 Obj
.SectionList
.append(FvImageSectionObj
)
2876 elif self
._IsKeyword
("PEI_DEPEX_EXP") or self
._IsKeyword
("DXE_DEPEX_EXP") or self
._IsKeyword
("SMM_DEPEX_EXP"):
2877 if AlignValue
== 'Auto':
2878 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2879 DepexSectionObj
= DepexSection()
2880 DepexSectionObj
.Alignment
= AlignValue
2881 DepexSectionObj
.DepexType
= self
._Token
2883 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2884 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2885 if not self
._IsToken
("{"):
2886 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2887 if not self
._SkipToToken
(T_CHAR_BRACE_R
):
2888 raise Warning.Expected("Depex expression ending '}'", self
.FileName
, self
.CurrentLineNumber
)
2890 DepexSectionObj
.Expression
= self
._SkippedChars
.rstrip(T_CHAR_BRACE_R
)
2891 Obj
.SectionList
.append(DepexSectionObj
)
2894 if not self
._GetNextWord
():
2895 raise Warning.Expected("section type", self
.FileName
, self
.CurrentLineNumber
)
2897 # Encapsulation section appear, UndoToken and return
2898 if self
._Token
== "COMPRESS" or self
._Token
== "GUIDED":
2899 self
.SetFileBufferPos(OldPos
)
2902 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
,\
2903 BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX
}:
2904 raise Warning("Unknown section type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2905 if AlignValue
== 'Auto'and (not self
._Token
== BINARY_FILE_TYPE_PE32
) and (not self
._Token
== BINARY_FILE_TYPE_TE
):
2906 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2909 DataSectionObj
= DataSection()
2910 DataSectionObj
.Alignment
= AlignValue
2911 DataSectionObj
.SecType
= self
._Token
2913 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2914 if self
._FileCouldHaveRelocFlag
(Obj
.FvFileType
) and self
._SectionCouldHaveRelocFlag
(DataSectionObj
.SecType
):
2915 if self
._Token
== 'RELOCS_STRIPPED':
2916 DataSectionObj
.KeepReloc
= False
2918 DataSectionObj
.KeepReloc
= True
2920 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
)
2922 if self
._IsToken
(TAB_EQUAL_SPLIT
):
2923 if not self
._GetNextToken
():
2924 raise Warning.Expected("section file path", self
.FileName
, self
.CurrentLineNumber
)
2925 DataSectionObj
.SectFileName
= self
._Token
2926 self
._VerifyFile
(DataSectionObj
.SectFileName
)
2928 if not self
._GetCglSection
(DataSectionObj
):
2931 Obj
.SectionList
.append(DataSectionObj
)
2937 # Check if file exists or not:
2938 # If current phase if GenFds, the file must exist;
2939 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
2940 # @param FileName: File path to be verified.
2942 def _VerifyFile(self
, FileName
):
2943 if FileName
.replace(TAB_WORKSPACE
, '').find('$') != -1:
2945 if not GlobalData
.gAutoGenPhase
or not self
._GetMacroValue
(TAB_DSC_DEFINES_OUTPUT_DIRECTORY
) in FileName
:
2946 ErrorCode
, ErrorInfo
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2948 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2950 ## _GetCglSection() method
2952 # Get compressed or GUIDed section for Obj
2954 # @param self The object pointer
2955 # @param Obj for whom leaf section is got
2956 # @param AlignValue alignment value for complex section
2957 # @retval True Successfully find section statement
2958 # @retval False Not able to find section statement
2960 def _GetCglSection(self
, Obj
, AlignValue
= None):
2962 if self
._IsKeyword
("COMPRESS"):
2964 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
2967 if not self
._IsToken
("{"):
2968 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2970 CompressSectionObj
= CompressSection()
2971 CompressSectionObj
.Alignment
= AlignValue
2972 CompressSectionObj
.CompType
= type
2973 # Recursive sections...
2975 IsLeafSection
= self
._GetLeafSection
(CompressSectionObj
)
2976 IsEncapSection
= self
._GetEncapsulationSec
(CompressSectionObj
)
2977 if not IsLeafSection
and not IsEncapSection
:
2981 if not self
._IsToken
(T_CHAR_BRACE_R
):
2982 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2983 Obj
.SectionList
.append(CompressSectionObj
)
2986 elif self
._IsKeyword
("GUIDED"):
2988 if self
._GetNextGuid
():
2989 GuidValue
= self
._Token
2991 AttribDict
= self
._GetGuidAttrib
()
2992 if not self
._IsToken
("{"):
2993 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2994 GuidSectionObj
= GuidSection()
2995 GuidSectionObj
.Alignment
= AlignValue
2996 GuidSectionObj
.NameGuid
= GuidValue
2997 GuidSectionObj
.SectionType
= "GUIDED"
2998 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
2999 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
3000 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
3001 # Recursive sections...
3003 IsLeafSection
= self
._GetLeafSection
(GuidSectionObj
)
3004 IsEncapSection
= self
._GetEncapsulationSec
(GuidSectionObj
)
3005 if not IsLeafSection
and not IsEncapSection
:
3008 if not self
._IsToken
(T_CHAR_BRACE_R
):
3009 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3010 Obj
.SectionList
.append(GuidSectionObj
)
3016 ## _GetGuidAttri() method
3018 # Get attributes for GUID section
3020 # @param self The object pointer
3021 # @retval AttribDict Dictionary of key-value pair of section attributes
3023 def _GetGuidAttrib(self
):
3025 AttribDict
["PROCESSING_REQUIRED"] = "NONE"
3026 AttribDict
["AUTH_STATUS_VALID"] = "NONE"
3027 AttribDict
["EXTRA_HEADER_SIZE"] = -1
3028 while self
._IsKeyword
("PROCESSING_REQUIRED") or self
._IsKeyword
("AUTH_STATUS_VALID") \
3029 or self
._IsKeyword
("EXTRA_HEADER_SIZE"):
3030 AttribKey
= self
._Token
3032 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3033 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3035 if not self
._GetNextToken
():
3036 raise Warning.Expected("TRUE(1)/FALSE(0)/Number", self
.FileName
, self
.CurrentLineNumber
)
3037 elif AttribKey
== "EXTRA_HEADER_SIZE":
3039 if self
._Token
[0:2].upper() == "0X":
3042 AttribDict
[AttribKey
] = int(self
._Token
, Base
)
3045 raise Warning.Expected("Number", self
.FileName
, self
.CurrentLineNumber
)
3046 elif self
._Token
.upper() not in {"TRUE", "FALSE", "1", "0"}:
3047 raise Warning.Expected("TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
3048 AttribDict
[AttribKey
] = self
._Token
3052 ## _GetEncapsulationSec() method
3054 # Get encapsulation section for FILE
3056 # @param self The object pointer
3057 # @param FfsFile for whom section is got
3058 # @retval True Successfully find section statement
3059 # @retval False Not able to find section statement
3061 def _GetEncapsulationSec(self
, FfsFileObj
):
3062 OldPos
= self
.GetFileBufferPos()
3063 if not self
._IsKeyword
("SECTION"):
3064 if len(FfsFileObj
.SectionList
) == 0:
3065 raise Warning.Expected("SECTION", self
.FileName
, self
.CurrentLineNumber
)
3070 if self
._GetAlignment
():
3071 if self
._Token
not in ALIGNMENT_NOAUTO
:
3072 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3073 AlignValue
= self
._Token
3075 if not self
._GetCglSection
(FfsFileObj
, AlignValue
):
3076 self
.SetFileBufferPos(OldPos
)
3082 if not self
._GetNextToken
():
3084 S
= self
._Token
.upper()
3085 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FMPPAYLOAD."):
3086 self
.SectionParser(S
)
3091 self
._SkipToToken
("[FMPPAYLOAD.", True)
3092 FmpUiName
= self
._GetUiName
().upper()
3093 if FmpUiName
in self
.Profile
.FmpPayloadDict
:
3094 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName
, self
.FileName
, self
.CurrentLineNumber
)
3096 FmpData
= CapsulePayload()
3097 FmpData
.UiName
= FmpUiName
3099 if not self
._IsToken
(TAB_SECTION_END
):
3100 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3102 if not self
._GetNextToken
():
3103 raise Warning("The FMP payload section is empty!", self
.FileName
, self
.CurrentLineNumber
)
3104 FmpKeyList
= ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']
3105 while self
._Token
in FmpKeyList
:
3107 FmpKeyList
.remove(Name
)
3108 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3109 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3110 if Name
== 'IMAGE_TYPE_ID':
3111 if not self
._GetNextGuid
():
3112 raise Warning.Expected("GUID value for IMAGE_TYPE_ID.", self
.FileName
, self
.CurrentLineNumber
)
3113 FmpData
.ImageTypeId
= self
._Token
3114 elif Name
== 'CERTIFICATE_GUID':
3115 if not self
._GetNextGuid
():
3116 raise Warning.Expected("GUID value for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3117 FmpData
.Certificate_Guid
= self
._Token
3118 if UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_RSA2048_SHA256_GUID
and UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_PKCS7_GUID
:
3119 raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3121 if not self
._GetNextToken
():
3122 raise Warning.Expected("value of %s" % Name
, self
.FileName
, self
.CurrentLineNumber
)
3124 if Name
== 'IMAGE_HEADER_INIT_VERSION':
3125 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3126 FmpData
.Version
= Value
3127 elif Name
== 'IMAGE_INDEX':
3128 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3129 FmpData
.ImageIndex
= Value
3130 elif Name
== 'HARDWARE_INSTANCE':
3131 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3132 FmpData
.HardwareInstance
= Value
3133 elif Name
== 'MONOTONIC_COUNT':
3134 if FdfParser
._Verify
(Name
, Value
, 'UINT64'):
3135 FmpData
.MonotonicCount
= Value
3136 if FmpData
.MonotonicCount
.upper().startswith('0X'):
3137 FmpData
.MonotonicCount
= int(FmpData
.MonotonicCount
, 16)
3139 FmpData
.MonotonicCount
= int(FmpData
.MonotonicCount
)
3140 if not self
._GetNextToken
():
3145 if (FmpData
.MonotonicCount
and not FmpData
.Certificate_Guid
) or (not FmpData
.MonotonicCount
and FmpData
.Certificate_Guid
):
3146 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")
3148 # Only the IMAGE_TYPE_ID is required item
3149 if FmpKeyList
and 'IMAGE_TYPE_ID' in FmpKeyList
:
3150 raise Warning("'IMAGE_TYPE_ID' in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3151 # get the Image file and Vendor code file
3152 self
._GetFMPCapsuleData
(FmpData
)
3153 if not FmpData
.ImageFile
:
3154 raise Warning("Missing image file in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3155 # check whether more than one Vendor code file
3156 if len(FmpData
.VendorCodeFile
) > 1:
3157 raise Warning("Vendor code file max of 1 per FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3158 self
.Profile
.FmpPayloadDict
[FmpUiName
] = FmpData
3161 ## _GetCapsule() method
3163 # Get capsule section contents and store its data into capsule list of self.Profile
3165 # @param self The object pointer
3166 # @retval True Successfully find a capsule
3167 # @retval False Not able to find a capsule
3169 def _GetCapsule(self
):
3170 if not self
._GetNextToken
():
3173 S
= self
._Token
.upper()
3174 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[CAPSULE."):
3175 self
.SectionParser(S
)
3180 if not self
._IsToken
("[CAPSULE.", True):
3181 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3182 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3183 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3184 raise Warning.Expected("[Capsule.]", self
.FileName
, self
.CurrentLineNumber
)
3186 CapsuleObj
= Capsule()
3188 CapsuleName
= self
._GetUiName
()
3190 raise Warning.Expected("capsule name", self
.FileName
, self
.CurrentLineNumber
)
3192 CapsuleObj
.UiCapsuleName
= CapsuleName
.upper()
3194 if not self
._IsToken
(TAB_SECTION_END
):
3195 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3197 if self
._IsKeyword
("CREATE_FILE"):
3198 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3199 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3201 if not self
._GetNextToken
():
3202 raise Warning.Expected("file name", self
.FileName
, self
.CurrentLineNumber
)
3204 CapsuleObj
.CreateFile
= self
._Token
3206 self
._GetCapsuleStatements
(CapsuleObj
)
3207 self
.Profile
.CapsuleDict
[CapsuleObj
.UiCapsuleName
] = CapsuleObj
3210 ## _GetCapsuleStatements() method
3212 # Get statements for capsule
3214 # @param self The object pointer
3215 # @param Obj for whom statements are got
3217 def _GetCapsuleStatements(self
, Obj
):
3218 self
._GetCapsuleTokens
(Obj
)
3219 self
._GetDefineStatements
(Obj
)
3220 self
._GetSetStatements
(Obj
)
3221 self
._GetCapsuleData
(Obj
)
3223 ## _GetCapsuleTokens() method
3225 # Get token statements for capsule
3227 # @param self The object pointer
3228 # @param Obj for whom token statements are got
3230 def _GetCapsuleTokens(self
, Obj
):
3231 if not self
._GetNextToken
():
3233 while self
._Token
in {"CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"}:
3234 Name
= self
._Token
.strip()
3235 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3236 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3237 if not self
._GetNextToken
():
3238 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
3239 if Name
== 'CAPSULE_FLAGS':
3240 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3241 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3242 Value
= self
._Token
.strip()
3243 while self
._IsToken
(TAB_COMMA_SPLIT
):
3244 Value
+= TAB_COMMA_SPLIT
3245 if not self
._GetNextToken
():
3246 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
3247 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3248 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3249 Value
+= self
._Token
.strip()
3250 elif Name
== 'OEM_CAPSULE_FLAGS':
3251 Value
= self
._Token
.strip()
3252 if not Value
.upper().startswith('0X'):
3253 raise Warning.Expected("hex value starting with 0x", self
.FileName
, self
.CurrentLineNumber
)
3255 Value
= int(Value
, 0)
3257 raise Warning.Expected("hex string failed to convert to value", self
.FileName
, self
.CurrentLineNumber
)
3258 if not 0x0000 <= Value
<= 0xFFFF:
3259 raise Warning.Expected("hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3260 Value
= self
._Token
.strip()
3262 Value
= self
._Token
.strip()
3263 Obj
.TokensDict
[Name
] = Value
3264 if not self
._GetNextToken
():
3268 ## _GetCapsuleData() method
3270 # Get capsule data for capsule
3272 # @param self The object pointer
3273 # @param Obj for whom capsule data are got
3275 def _GetCapsuleData(self
, Obj
):
3277 IsInf
= self
._GetInfStatement
(Obj
, True)
3278 IsFile
= self
._GetFileStatement
(Obj
, True)
3279 IsFv
= self
._GetFvStatement
(Obj
)
3280 IsFd
= self
._GetFdStatement
(Obj
)
3281 IsAnyFile
= self
._GetAnyFileStatement
(Obj
)
3282 IsAfile
= self
._GetAfileStatement
(Obj
)
3283 IsFmp
= self
._GetFmpStatement
(Obj
)
3284 if not (IsInf
or IsFile
or IsFv
or IsFd
or IsAnyFile
or IsAfile
or IsFmp
):
3287 ## _GetFMPCapsuleData() method
3289 # Get capsule data for FMP capsule
3291 # @param self The object pointer
3292 # @param Obj for whom capsule data are got
3294 def _GetFMPCapsuleData(self
, Obj
):
3296 IsFv
= self
._GetFvStatement
(Obj
, True)
3297 IsFd
= self
._GetFdStatement
(Obj
, True)
3298 IsAnyFile
= self
._GetAnyFileStatement
(Obj
, True)
3299 if not (IsFv
or IsFd
or IsAnyFile
):
3302 ## _GetFvStatement() method
3304 # Get FV for capsule
3306 # @param self The object pointer
3307 # @param CapsuleObj for whom FV is got
3308 # @retval True Successfully find a FV statement
3309 # @retval False Not able to find a FV statement
3311 def _GetFvStatement(self
, CapsuleObj
, FMPCapsule
= False):
3312 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3315 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3316 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3318 if not self
._GetNextToken
():
3319 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
3321 if self
._Token
.upper() not in self
.Profile
.FvDict
:
3322 raise Warning("FV name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3324 myCapsuleFv
= CapsuleFv()
3325 myCapsuleFv
.FvName
= self
._Token
3327 if not CapsuleObj
.ImageFile
:
3328 CapsuleObj
.ImageFile
.append(myCapsuleFv
)
3330 CapsuleObj
.VendorCodeFile
.append(myCapsuleFv
)
3332 CapsuleObj
.CapsuleDataList
.append(myCapsuleFv
)
3335 ## _GetFdStatement() method
3337 # Get FD for capsule
3339 # @param self The object pointer
3340 # @param CapsuleObj for whom FD is got
3341 # @retval True Successfully find a FD statement
3342 # @retval False Not able to find a FD statement
3344 def _GetFdStatement(self
, CapsuleObj
, FMPCapsule
= False):
3345 if not self
._IsKeyword
("FD"):
3348 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3349 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3351 if not self
._GetNextToken
():
3352 raise Warning.Expected("FD name", self
.FileName
, self
.CurrentLineNumber
)
3354 if self
._Token
.upper() not in self
.Profile
.FdDict
:
3355 raise Warning("FD name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3357 myCapsuleFd
= CapsuleFd()
3358 myCapsuleFd
.FdName
= self
._Token
3360 if not CapsuleObj
.ImageFile
:
3361 CapsuleObj
.ImageFile
.append(myCapsuleFd
)
3363 CapsuleObj
.VendorCodeFile
.append(myCapsuleFd
)
3365 CapsuleObj
.CapsuleDataList
.append(myCapsuleFd
)
3368 def _GetFmpStatement(self
, CapsuleObj
):
3369 if not self
._IsKeyword
("FMP_PAYLOAD"):
3370 if not self
._IsKeyword
("FMP"):
3373 if not self
._IsKeyword
("PAYLOAD"):
3377 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3378 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3380 if not self
._GetNextToken
():
3381 raise Warning.Expected("payload name after FMP_PAYLOAD =", self
.FileName
, self
.CurrentLineNumber
)
3382 Payload
= self
._Token
.upper()
3383 if Payload
not in self
.Profile
.FmpPayloadDict
:
3384 raise Warning("This FMP Payload does not exist: %s" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3385 CapsuleObj
.FmpPayloadList
.append(self
.Profile
.FmpPayloadDict
[Payload
])
3388 def _ParseRawFileStatement(self
):
3389 if not self
._IsKeyword
("FILE"):
3392 if not self
._IsKeyword
("DATA"):
3396 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3397 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3399 if not self
._GetNextToken
():
3400 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
3402 AnyFileName
= self
._Token
3403 self
._VerifyFile
(AnyFileName
)
3405 if not os
.path
.isabs(AnyFileName
):
3406 AnyFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, AnyFileName
)
3410 ## _GetAnyFileStatement() method
3412 # Get AnyFile for capsule
3414 # @param self The object pointer
3415 # @param CapsuleObj for whom AnyFile is got
3416 # @retval True Successfully find a Anyfile statement
3417 # @retval False Not able to find a AnyFile statement
3419 def _GetAnyFileStatement(self
, CapsuleObj
, FMPCapsule
= False):
3420 AnyFileName
= self
._ParseRawFileStatement
()
3424 myCapsuleAnyFile
= CapsuleAnyFile()
3425 myCapsuleAnyFile
.FileName
= AnyFileName
3427 if not CapsuleObj
.ImageFile
:
3428 CapsuleObj
.ImageFile
.append(myCapsuleAnyFile
)
3430 CapsuleObj
.VendorCodeFile
.append(myCapsuleAnyFile
)
3432 CapsuleObj
.CapsuleDataList
.append(myCapsuleAnyFile
)
3435 ## _GetAfileStatement() method
3437 # Get Afile for capsule
3439 # @param self The object pointer
3440 # @param CapsuleObj for whom Afile is got
3441 # @retval True Successfully find a Afile statement
3442 # @retval False Not able to find a Afile statement
3444 def _GetAfileStatement(self
, CapsuleObj
):
3445 if not self
._IsKeyword
("APPEND"):
3448 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3449 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3451 if not self
._GetNextToken
():
3452 raise Warning.Expected("Afile name", self
.FileName
, self
.CurrentLineNumber
)
3454 AfileName
= self
._Token
3455 AfileBaseName
= os
.path
.basename(AfileName
)
3457 if os
.path
.splitext(AfileBaseName
)[1] not in {".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"}:
3458 raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \
3459 self
.FileName
, self
.CurrentLineNumber
)
3461 if not os
.path
.isabs(AfileName
):
3462 AfileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(AfileName
)
3463 self
._VerifyFile
(AfileName
)
3465 if not os
.path
.exists(AfileName
):
3466 raise Warning('%s does not exist' % AfileName
, self
.FileName
, self
.CurrentLineNumber
)
3470 myCapsuleAfile
= CapsuleAfile()
3471 myCapsuleAfile
.FileName
= AfileName
3472 CapsuleObj
.CapsuleDataList
.append(myCapsuleAfile
)
3475 ## _GetRule() method
3477 # Get Rule section contents and store its data into rule list of self.Profile
3479 # @param self The object pointer
3480 # @retval True Successfully find a Rule
3481 # @retval False Not able to find a Rule
3484 if not self
._GetNextToken
():
3487 S
= self
._Token
.upper()
3488 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[RULE."):
3489 self
.SectionParser(S
)
3493 if not self
._IsToken
("[Rule.", True):
3494 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3495 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3496 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3497 raise Warning.Expected("[Rule.]", self
.FileName
, self
.CurrentLineNumber
)
3499 if not self
._SkipToToken
(TAB_SPLIT
):
3500 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
3502 Arch
= self
._SkippedChars
.rstrip(TAB_SPLIT
)
3503 if Arch
.upper() not in ARCH_SET_FULL
:
3504 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
3506 ModuleType
= self
._GetModuleType
()
3509 if self
._IsToken
(TAB_SPLIT
):
3510 if not self
._GetNextWord
():
3511 raise Warning.Expected("template name", self
.FileName
, self
.CurrentLineNumber
)
3512 TemplateName
= self
._Token
3514 if not self
._IsToken
(TAB_SECTION_END
):
3515 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3517 RuleObj
= self
._GetRuleFileStatements
()
3518 RuleObj
.Arch
= Arch
.upper()
3519 RuleObj
.ModuleType
= ModuleType
3520 RuleObj
.TemplateName
= TemplateName
3521 if TemplateName
== '':
3522 self
.Profile
.RuleDict
['RULE' + \
3526 ModuleType
.upper() ] = RuleObj
3528 self
.Profile
.RuleDict
['RULE' + \
3532 ModuleType
.upper() + \
3534 TemplateName
.upper() ] = RuleObj
3537 ## _GetModuleType() method
3539 # Return the module type
3541 # @param self The object pointer
3542 # @retval string module type
3544 def _GetModuleType(self
):
3545 if not self
._GetNextWord
():
3546 raise Warning.Expected("Module type", self
.FileName
, self
.CurrentLineNumber
)
3547 if self
._Token
.upper() not in {
3548 SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3549 SUP_MODULE_DXE_CORE
, SUP_MODULE_DXE_DRIVER
,
3550 SUP_MODULE_DXE_SAL_DRIVER
, SUP_MODULE_DXE_SMM_DRIVER
,
3551 SUP_MODULE_DXE_RUNTIME_DRIVER
, SUP_MODULE_UEFI_DRIVER
,
3552 SUP_MODULE_UEFI_APPLICATION
, SUP_MODULE_USER_DEFINED
,
3553 TAB_DEFAULT
, SUP_MODULE_BASE
,
3554 EDK_COMPONENT_TYPE_SECURITY_CORE
,
3555 EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER
,
3556 EDK_COMPONENT_TYPE_PIC_PEIM
,
3557 EDK_COMPONENT_TYPE_RELOCATABLE_PEIM
, "PE32_PEIM",
3558 EDK_COMPONENT_TYPE_BS_DRIVER
, EDK_COMPONENT_TYPE_RT_DRIVER
,
3559 EDK_COMPONENT_TYPE_SAL_RT_DRIVER
,
3560 EDK_COMPONENT_TYPE_APPLICATION
, "ACPITABLE",
3561 SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3562 SUP_MODULE_MM_CORE_STANDALONE
}:
3563 raise Warning("Unknown Module type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3566 ## _GetFileExtension() method
3568 # Return the file extension
3570 # @param self The object pointer
3571 # @retval string file name extension
3573 def _GetFileExtension(self
):
3574 if not self
._IsToken
(TAB_SPLIT
):
3575 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
3578 if self
._GetNextToken
():
3579 if FileExtensionPattern
.match(self
._Token
):
3581 return TAB_SPLIT
+ Ext
3583 raise Warning("Unknown file extension '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3586 raise Warning.Expected("file extension", self
.FileName
, self
.CurrentLineNumber
)
3588 ## _GetRuleFileStatement() method
3592 # @param self The object pointer
3593 # @retval Rule Rule object
3595 def _GetRuleFileStatements(self
):
3596 if not self
._IsKeyword
("FILE"):
3597 raise Warning.Expected("FILE", self
.FileName
, self
.CurrentLineNumber
)
3599 if not self
._GetNextWord
():
3600 raise Warning.Expected("FFS type", self
.FileName
, self
.CurrentLineNumber
)
3602 Type
= self
._Token
.strip().upper()
3603 if Type
not in {"RAW", "FREEFORM", SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3604 "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE
, EDK_COMPONENT_TYPE_APPLICATION
,
3605 "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3606 SUP_MODULE_MM_CORE_STANDALONE
}:
3607 raise Warning("Unknown FV type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3609 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3610 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3612 if not self
._IsKeyword
("$(NAMED_GUID)"):
3613 if not self
._GetNextWord
():
3614 raise Warning.Expected("$(NAMED_GUID)", self
.FileName
, self
.CurrentLineNumber
)
3615 if self
._Token
== 'PCD':
3616 if not self
._IsToken
("("):
3617 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3618 PcdPair
= self
._GetNextPcdSettings
()
3619 if not self
._IsToken
(")"):
3620 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3621 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3623 NameGuid
= self
._Token
3626 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3627 if self
._FileCouldHaveRelocFlag
(Type
):
3628 if self
._Token
== 'RELOCS_STRIPPED':
3633 raise Warning("File type %s could not have reloc strip flag%d" % (Type
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3636 if self
._GetNextToken
():
3637 if TokenFindPattern
.match(self
._Token
):
3638 KeyStringList
.append(self
._Token
)
3639 if self
._IsToken
(TAB_COMMA_SPLIT
):
3640 while self
._GetNextToken
():
3641 if not TokenFindPattern
.match(self
._Token
):
3642 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
3643 KeyStringList
.append(self
._Token
)
3645 if not self
._IsToken
(TAB_COMMA_SPLIT
):
3653 if self
._IsKeyword
("Fixed", True):
3657 if self
._IsKeyword
("CheckSum", True):
3661 if self
._GetAlignment
():
3662 if self
._Token
not in ALIGNMENTS
:
3663 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3664 #For FFS, Auto is default option same to ""
3665 if not self
._Token
== "Auto":
3666 AlignValue
= self
._Token
3668 if self
._IsToken
("{"):
3669 # Complex file rule expected
3670 NewRule
= RuleComplexFile()
3671 NewRule
.FvFileType
= Type
3672 NewRule
.NameGuid
= NameGuid
3673 NewRule
.Alignment
= AlignValue
3674 NewRule
.CheckSum
= CheckSum
3675 NewRule
.Fixed
= Fixed
3676 NewRule
.KeyStringList
= KeyStringList
3677 if KeepReloc
is not None:
3678 NewRule
.KeepReloc
= KeepReloc
3681 IsEncapsulate
= self
._GetRuleEncapsulationSection
(NewRule
)
3682 IsLeaf
= self
._GetEfiSection
(NewRule
)
3683 if not IsEncapsulate
and not IsLeaf
:
3686 if not self
._IsToken
(T_CHAR_BRACE_R
):
3687 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3692 # Simple file rule expected
3693 if not self
._GetNextWord
():
3694 raise Warning.Expected("leaf section type", self
.FileName
, self
.CurrentLineNumber
)
3696 SectionName
= self
._Token
3698 if SectionName
not in {
3699 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3700 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3701 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3702 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3703 BINARY_FILE_TYPE_SMM_DEPEX
}:
3704 raise Warning("Unknown leaf section name '%s'" % SectionName
, self
.FileName
, self
.CurrentLineNumber
)
3707 if self
._IsKeyword
("Fixed", True):
3710 if self
._IsKeyword
("CheckSum", True):
3714 if self
._GetAlignment
():
3715 if self
._Token
not in ALIGNMENTS
:
3716 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3717 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3718 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3719 SectAlignment
= self
._Token
3722 if self
._IsToken
(TAB_VALUE_SPLIT
):
3723 Ext
= self
._GetFileExtension
()
3724 elif not self
._GetNextToken
():
3725 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
3727 NewRule
= RuleSimpleFile()
3728 NewRule
.SectionType
= SectionName
3729 NewRule
.FvFileType
= Type
3730 NewRule
.NameGuid
= NameGuid
3731 NewRule
.Alignment
= AlignValue
3732 NewRule
.SectAlignment
= SectAlignment
3733 NewRule
.CheckSum
= CheckSum
3734 NewRule
.Fixed
= Fixed
3735 NewRule
.KeyStringList
= KeyStringList
3736 if KeepReloc
is not None:
3737 NewRule
.KeepReloc
= KeepReloc
3738 NewRule
.FileExtension
= Ext
3739 NewRule
.FileName
= self
._Token
3742 ## _GetEfiSection() method
3744 # Get section list for Rule
3746 # @param self The object pointer
3747 # @param Obj for whom section is got
3748 # @retval True Successfully find section statement
3749 # @retval False Not able to find section statement
3751 def _GetEfiSection(self
, Obj
):
3752 OldPos
= self
.GetFileBufferPos()
3753 if not self
._GetNextWord
():
3755 SectionName
= self
._Token
3757 if SectionName
not in {
3758 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3759 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3760 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3761 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3762 BINARY_FILE_TYPE_SMM_DEPEX
, BINARY_FILE_TYPE_GUID
}:
3766 if SectionName
== "FV_IMAGE":
3767 FvImageSectionObj
= FvImageSection()
3768 if self
._IsKeyword
("FV_IMAGE"):
3770 if self
._IsToken
("{"):
3772 self
._GetDefineStatements
(FvObj
)
3773 self
._GetBlockStatement
(FvObj
)
3774 self
._GetSetStatements
(FvObj
)
3775 self
._GetFvAlignment
(FvObj
)
3776 self
._GetFvAttributes
(FvObj
)
3777 self
._GetAprioriSection
(FvObj
)
3778 self
._GetAprioriSection
(FvObj
)
3781 IsInf
= self
._GetInfStatement
(FvObj
)
3782 IsFile
= self
._GetFileStatement
(FvObj
)
3783 if not IsInf
and not IsFile
:
3786 if not self
._IsToken
(T_CHAR_BRACE_R
):
3787 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3788 FvImageSectionObj
.Fv
= FvObj
3789 FvImageSectionObj
.FvName
= None
3792 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3793 raise Warning.Expected("'FV'", self
.FileName
, self
.CurrentLineNumber
)
3794 FvImageSectionObj
.FvFileType
= self
._Token
3796 if self
._GetAlignment
():
3797 if self
._Token
not in ALIGNMENT_NOAUTO
:
3798 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3799 FvImageSectionObj
.Alignment
= self
._Token
3801 if self
._IsToken
(TAB_VALUE_SPLIT
):
3802 FvImageSectionObj
.FvFileExtension
= self
._GetFileExtension
()
3803 elif self
._GetNextToken
():
3804 if self
._Token
not in {
3805 T_CHAR_BRACE_R
, "COMPAT16", BINARY_FILE_TYPE_PE32
,
3806 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3807 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3808 BINARY_FILE_TYPE_UI
, "VERSION",
3809 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3810 BINARY_FILE_TYPE_SMM_DEPEX
}:
3811 FvImageSectionObj
.FvFileName
= self
._Token
3815 raise Warning.Expected("FV file name", self
.FileName
, self
.CurrentLineNumber
)
3817 Obj
.SectionList
.append(FvImageSectionObj
)
3820 EfiSectionObj
= EfiSection()
3821 EfiSectionObj
.SectionType
= SectionName
3823 if not self
._GetNextToken
():
3824 raise Warning.Expected("file type", self
.FileName
, self
.CurrentLineNumber
)
3826 if self
._Token
== "STRING":
3827 if not self
._RuleSectionCouldHaveString
(EfiSectionObj
.SectionType
):
3828 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3830 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3831 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3833 if not self
._GetNextToken
():
3834 raise Warning.Expected("Quoted String", self
.FileName
, self
.CurrentLineNumber
)
3836 if self
._GetStringData
():
3837 EfiSectionObj
.StringData
= self
._Token
3839 if self
._IsKeyword
("BUILD_NUM"):
3840 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3841 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3843 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3844 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3845 if not self
._GetNextToken
():
3846 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3847 EfiSectionObj
.BuildNum
= self
._Token
3850 EfiSectionObj
.FileType
= self
._Token
3851 self
._CheckRuleSectionFileType
(EfiSectionObj
.SectionType
, EfiSectionObj
.FileType
)
3853 if self
._IsKeyword
("Optional"):
3854 if not self
._RuleSectionCouldBeOptional
(EfiSectionObj
.SectionType
):
3855 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3856 EfiSectionObj
.Optional
= True
3858 if self
._IsKeyword
("BUILD_NUM"):
3859 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3860 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3862 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3863 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3864 if not self
._GetNextToken
():
3865 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3866 EfiSectionObj
.BuildNum
= self
._Token
3868 if self
._GetAlignment
():
3869 if self
._Token
not in ALIGNMENTS
:
3870 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3871 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3872 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3873 EfiSectionObj
.Alignment
= self
._Token
3875 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3876 if self
._SectionCouldHaveRelocFlag
(EfiSectionObj
.SectionType
):
3877 if self
._Token
== 'RELOCS_STRIPPED':
3878 EfiSectionObj
.KeepReloc
= False
3880 EfiSectionObj
.KeepReloc
= True
3881 if Obj
.KeepReloc
is not None and Obj
.KeepReloc
!= EfiSectionObj
.KeepReloc
:
3882 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3884 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3887 if self
._IsToken
(TAB_VALUE_SPLIT
):
3888 EfiSectionObj
.FileExtension
= self
._GetFileExtension
()
3889 elif self
._GetNextToken
():
3890 if self
._Token
not in {
3891 T_CHAR_BRACE_R
, "COMPAT16", BINARY_FILE_TYPE_PE32
,
3892 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3893 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3894 BINARY_FILE_TYPE_UI
, "VERSION",
3895 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3896 BINARY_FILE_TYPE_SMM_DEPEX
}:
3898 if self
._Token
.startswith('PCD'):
3902 if self
._Token
== 'PCD':
3903 if not self
._IsToken
("("):
3904 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3905 PcdPair
= self
._GetNextPcdSettings
()
3906 if not self
._IsToken
(")"):
3907 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3908 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3910 EfiSectionObj
.FileName
= self
._Token
3915 raise Warning.Expected("section file name", self
.FileName
, self
.CurrentLineNumber
)
3917 Obj
.SectionList
.append(EfiSectionObj
)
3920 ## _RuleSectionCouldBeOptional() method
3922 # Get whether a section could be optional
3924 # @param SectionType The section type to check
3925 # @retval True section could be optional
3926 # @retval False section never optional
3929 def _RuleSectionCouldBeOptional(SectionType
):
3930 if SectionType
in {BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "RAW", BINARY_FILE_TYPE_SMM_DEPEX
}:
3935 ## _RuleSectionCouldHaveBuildNum() method
3937 # Get whether a section could have build number information
3939 # @param SectionType The section type to check
3940 # @retval True section could have build number information
3941 # @retval False section never have build number information
3944 def _RuleSectionCouldHaveBuildNum(SectionType
):
3945 if SectionType
== "VERSION":
3950 ## _RuleSectionCouldHaveString() method
3952 # Get whether a section could have string
3954 # @param SectionType The section type to check
3955 # @retval True section could have string
3956 # @retval False section never have string
3959 def _RuleSectionCouldHaveString(SectionType
):
3960 if SectionType
in {BINARY_FILE_TYPE_UI
, "VERSION"}:
3965 ## _CheckRuleSectionFileType() method
3967 # Get whether a section matches a file type
3969 # @param self The object pointer
3970 # @param SectionType The section type to check
3971 # @param FileType The file type to check
3973 def _CheckRuleSectionFileType(self
, SectionType
, FileType
):
3974 WarningString
= "Incorrect section file type '%s'"
3975 if SectionType
== "COMPAT16":
3976 if FileType
not in {"COMPAT16", "SEC_COMPAT16"}:
3977 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3978 elif SectionType
== BINARY_FILE_TYPE_PE32
:
3979 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_PE32"}:
3980 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3981 elif SectionType
== BINARY_FILE_TYPE_PIC
:
3982 if FileType
not in {BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_PIC
}:
3983 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3984 elif SectionType
== BINARY_FILE_TYPE_TE
:
3985 if FileType
not in {BINARY_FILE_TYPE_TE
, "SEC_TE"}:
3986 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3987 elif SectionType
== "RAW":
3988 if FileType
not in {BINARY_FILE_TYPE_BIN
, "SEC_BIN", "RAW", "ASL", "ACPI"}:
3989 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3990 elif SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
or SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
3991 if FileType
not in {BINARY_FILE_TYPE_DXE_DEPEX
, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX
}:
3992 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3993 elif SectionType
== BINARY_FILE_TYPE_UI
:
3994 if FileType
not in {BINARY_FILE_TYPE_UI
, "SEC_UI"}:
3995 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3996 elif SectionType
== "VERSION":
3997 if FileType
not in {"VERSION", "SEC_VERSION"}:
3998 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3999 elif SectionType
== BINARY_FILE_TYPE_PEI_DEPEX
:
4000 if FileType
not in {BINARY_FILE_TYPE_PEI_DEPEX
, "SEC_PEI_DEPEX"}:
4001 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4002 elif SectionType
== BINARY_FILE_TYPE_GUID
:
4003 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_GUID"}:
4004 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4006 ## _GetRuleEncapsulationSection() method
4008 # Get encapsulation section for Rule
4010 # @param self The object pointer
4011 # @param theRule for whom section is got
4012 # @retval True Successfully find section statement
4013 # @retval False Not able to find section statement
4015 def _GetRuleEncapsulationSection(self
, theRule
):
4016 if self
._IsKeyword
("COMPRESS"):
4018 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
4021 if not self
._IsToken
("{"):
4022 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4024 CompressSectionObj
= CompressSection()
4026 CompressSectionObj
.CompType
= Type
4027 # Recursive sections...
4029 IsEncapsulate
= self
._GetRuleEncapsulationSection
(CompressSectionObj
)
4030 IsLeaf
= self
._GetEfiSection
(CompressSectionObj
)
4031 if not IsEncapsulate
and not IsLeaf
:
4034 if not self
._IsToken
(T_CHAR_BRACE_R
):
4035 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4036 theRule
.SectionList
.append(CompressSectionObj
)
4040 elif self
._IsKeyword
("GUIDED"):
4042 if self
._GetNextGuid
():
4043 GuidValue
= self
._Token
4045 if self
._IsKeyword
("$(NAMED_GUID)"):
4046 GuidValue
= self
._Token
4048 AttribDict
= self
._GetGuidAttrib
()
4050 if not self
._IsToken
("{"):
4051 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4052 GuidSectionObj
= GuidSection()
4053 GuidSectionObj
.NameGuid
= GuidValue
4054 GuidSectionObj
.SectionType
= "GUIDED"
4055 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
4056 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
4057 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
4061 IsEncapsulate
= self
._GetRuleEncapsulationSection
(GuidSectionObj
)
4062 IsLeaf
= self
._GetEfiSection
(GuidSectionObj
)
4063 if not IsEncapsulate
and not IsLeaf
:
4066 if not self
._IsToken
(T_CHAR_BRACE_R
):
4067 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4068 theRule
.SectionList
.append(GuidSectionObj
)
4074 ## _GetOptionRom() method
4076 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
4078 # @param self The object pointer
4079 # @retval True Successfully find a OptionROM
4080 # @retval False Not able to find a OptionROM
4082 def _GetOptionRom(self
):
4083 if not self
._GetNextToken
():
4086 S
= self
._Token
.upper()
4087 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[OPTIONROM."):
4088 self
.SectionParser(S
)
4093 if not self
._IsToken
("[OptionRom.", True):
4094 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4096 OptRomName
= self
._GetUiName
()
4098 if not self
._IsToken
(TAB_SECTION_END
):
4099 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
4101 OptRomObj
= OPTIONROM(OptRomName
)
4102 self
.Profile
.OptRomDict
[OptRomName
] = OptRomObj
4105 isInf
= self
._GetOptRomInfStatement
(OptRomObj
)
4106 isFile
= self
._GetOptRomFileStatement
(OptRomObj
)
4107 if not isInf
and not isFile
:
4112 ## _GetOptRomInfStatement() method
4114 # Get INF statements
4116 # @param self The object pointer
4117 # @param Obj for whom inf statement is got
4118 # @retval True Successfully find inf statement
4119 # @retval False Not able to find inf statement
4121 def _GetOptRomInfStatement(self
, Obj
):
4122 if not self
._IsKeyword
("INF"):
4125 ffsInf
= OptRomInfStatement()
4126 self
._GetInfOptions
(ffsInf
)
4128 if not self
._GetNextToken
():
4129 raise Warning.Expected("INF file path", self
.FileName
, self
.CurrentLineNumber
)
4130 ffsInf
.InfFileName
= self
._Token
4131 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4132 #check for file path
4133 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4135 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4137 NewFileName
= ffsInf
.InfFileName
4138 if ffsInf
.OverrideGuid
:
4139 NewFileName
= ProcessDuplicatedInf(PathClass(ffsInf
.InfFileName
,GenFdsGlobalVariable
.WorkSpaceDir
), ffsInf
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
).Path
4141 if not NewFileName
in self
.Profile
.InfList
:
4142 self
.Profile
.InfList
.append(NewFileName
)
4143 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4144 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
4146 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
4147 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
4149 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
4151 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
4154 self
._GetOptRomOverrides
(ffsInf
)
4156 Obj
.FfsList
.append(ffsInf
)
4159 ## _GetOptRomOverrides() method
4161 # Get overrides for OptROM INF & FILE
4163 # @param self The object pointer
4164 # @param FfsInfObj for whom overrides is got
4166 def _GetOptRomOverrides(self
, Obj
):
4167 if self
._IsToken
('{'):
4168 Overrides
= OverrideAttribs()
4170 if self
._IsKeyword
("PCI_VENDOR_ID"):
4171 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4172 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4173 if not self
._GetNextHexNumber
():
4174 raise Warning.Expected("Hex vendor id", self
.FileName
, self
.CurrentLineNumber
)
4175 Overrides
.PciVendorId
= self
._Token
4178 if self
._IsKeyword
("PCI_CLASS_CODE"):
4179 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4180 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4181 if not self
._GetNextHexNumber
():
4182 raise Warning.Expected("Hex class code", self
.FileName
, self
.CurrentLineNumber
)
4183 Overrides
.PciClassCode
= self
._Token
4186 if self
._IsKeyword
("PCI_DEVICE_ID"):
4187 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4188 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4189 # Get a list of PCI IDs
4190 Overrides
.PciDeviceId
= ""
4191 while (self
._GetNextHexNumber
()):
4192 Overrides
.PciDeviceId
= "{} {}".format(Overrides
.PciDeviceId
, self
._Token
)
4193 if not Overrides
.PciDeviceId
:
4194 raise Warning.Expected("one or more Hex device ids", self
.FileName
, self
.CurrentLineNumber
)
4197 if self
._IsKeyword
("PCI_REVISION"):
4198 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4199 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4200 if not self
._GetNextHexNumber
():
4201 raise Warning.Expected("Hex revision", self
.FileName
, self
.CurrentLineNumber
)
4202 Overrides
.PciRevision
= self
._Token
4205 if self
._IsKeyword
("PCI_COMPRESS"):
4206 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4207 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4208 if not self
._GetNextToken
():
4209 raise Warning.Expected("TRUE/FALSE for compress", self
.FileName
, self
.CurrentLineNumber
)
4210 Overrides
.NeedCompress
= self
._Token
.upper() == 'TRUE'
4213 if self
._IsToken
(T_CHAR_BRACE_R
):
4216 EdkLogger
.error("FdfParser", FORMAT_INVALID
, File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
4218 Obj
.OverrideAttribs
= Overrides
4220 ## _GetOptRomFileStatement() method
4222 # Get FILE statements
4224 # @param self The object pointer
4225 # @param Obj for whom FILE statement is got
4226 # @retval True Successfully find FILE statement
4227 # @retval False Not able to find FILE statement
4229 def _GetOptRomFileStatement(self
, Obj
):
4230 if not self
._IsKeyword
("FILE"):
4233 FfsFileObj
= OptRomFileStatement()
4235 if not self
._IsKeyword
("EFI") and not self
._IsKeyword
(BINARY_FILE_TYPE_BIN
):
4236 raise Warning.Expected("Binary type (EFI/BIN)", self
.FileName
, self
.CurrentLineNumber
)
4237 FfsFileObj
.FileType
= self
._Token
4239 if not self
._GetNextToken
():
4240 raise Warning.Expected("File path", self
.FileName
, self
.CurrentLineNumber
)
4241 FfsFileObj
.FileName
= self
._Token
4242 if FfsFileObj
.FileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4243 #check for file path
4244 ErrorCode
, ErrorInfo
= PathClass(NormPath(FfsFileObj
.FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4246 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4248 if FfsFileObj
.FileType
== 'EFI':
4249 self
._GetOptRomOverrides
(FfsFileObj
)
4251 Obj
.FfsList
.append(FfsFileObj
)
4255 ## _GetCapInFd() method
4257 # Get Cap list contained in FD
4259 # @param self The object pointer
4260 # @param FdName FD name
4261 # @retval CapList List of Capsule in FD
4263 def _GetCapInFd (self
, FdName
):
4265 if FdName
.upper() in self
.Profile
.FdDict
:
4266 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4267 for elementRegion
in FdObj
.RegionList
:
4268 if elementRegion
.RegionType
== 'CAPSULE':
4269 for elementRegionData
in elementRegion
.RegionDataList
:
4270 if elementRegionData
.endswith(".cap"):
4272 if elementRegionData
is not None and elementRegionData
.upper() not in CapList
:
4273 CapList
.append(elementRegionData
.upper())
4276 ## _GetReferencedFdCapTuple() method
4278 # Get FV and FD list referenced by a capsule image
4280 # @param self The object pointer
4281 # @param CapObj Capsule section to be searched
4282 # @param RefFdList referenced FD by section
4283 # @param RefFvList referenced FV by section
4285 def _GetReferencedFdCapTuple(self
, CapObj
, RefFdList
= [], RefFvList
= []):
4286 for CapsuleDataObj
in CapObj
.CapsuleDataList
:
4287 if hasattr(CapsuleDataObj
, 'FvName') and CapsuleDataObj
.FvName
is not None and CapsuleDataObj
.FvName
.upper() not in RefFvList
:
4288 RefFvList
.append (CapsuleDataObj
.FvName
.upper())
4289 elif hasattr(CapsuleDataObj
, 'FdName') and CapsuleDataObj
.FdName
is not None and CapsuleDataObj
.FdName
.upper() not in RefFdList
:
4290 RefFdList
.append (CapsuleDataObj
.FdName
.upper())
4291 elif CapsuleDataObj
.Ffs
is not None:
4292 if isinstance(CapsuleDataObj
.Ffs
, FileStatement
):
4293 if CapsuleDataObj
.Ffs
.FvName
is not None and CapsuleDataObj
.Ffs
.FvName
.upper() not in RefFvList
:
4294 RefFvList
.append(CapsuleDataObj
.Ffs
.FvName
.upper())
4295 elif CapsuleDataObj
.Ffs
.FdName
is not None and CapsuleDataObj
.Ffs
.FdName
.upper() not in RefFdList
:
4296 RefFdList
.append(CapsuleDataObj
.Ffs
.FdName
.upper())
4298 self
._GetReferencedFdFvTupleFromSection
(CapsuleDataObj
.Ffs
, RefFdList
, RefFvList
)
4300 ## _GetFvInFd() method
4302 # Get FV list contained in FD
4304 # @param self The object pointer
4305 # @param FdName FD name
4306 # @retval FvList list of FV in FD
4308 def _GetFvInFd (self
, FdName
):
4310 if FdName
.upper() in self
.Profile
.FdDict
:
4311 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4312 for elementRegion
in FdObj
.RegionList
:
4313 if elementRegion
.RegionType
== BINARY_FILE_TYPE_FV
:
4314 for elementRegionData
in elementRegion
.RegionDataList
:
4315 if elementRegionData
.endswith(".fv"):
4317 if elementRegionData
is not None and elementRegionData
.upper() not in FvList
:
4318 FvList
.append(elementRegionData
.upper())
4321 ## _GetReferencedFdFvTuple() method
4323 # Get FD and FV list referenced by a FFS file
4325 # @param self The object pointer
4326 # @param FfsFile contains sections to be searched
4327 # @param RefFdList referenced FD by section
4328 # @param RefFvList referenced FV by section
4330 def _GetReferencedFdFvTuple(self
, FvObj
, RefFdList
= [], RefFvList
= []):
4331 for FfsObj
in FvObj
.FfsList
:
4332 if isinstance(FfsObj
, FileStatement
):
4333 if FfsObj
.FvName
is not None and FfsObj
.FvName
.upper() not in RefFvList
:
4334 RefFvList
.append(FfsObj
.FvName
.upper())
4335 elif FfsObj
.FdName
is not None and FfsObj
.FdName
.upper() not in RefFdList
:
4336 RefFdList
.append(FfsObj
.FdName
.upper())
4338 self
._GetReferencedFdFvTupleFromSection
(FfsObj
, RefFdList
, RefFvList
)
4340 ## _GetReferencedFdFvTupleFromSection() method
4342 # Get FD and FV list referenced by a FFS section
4344 # @param self The object pointer
4345 # @param FfsFile contains sections to be searched
4346 # @param FdList referenced FD by section
4347 # @param FvList referenced FV by section
4349 def _GetReferencedFdFvTupleFromSection(self
, FfsFile
, FdList
= [], FvList
= []):
4350 SectionStack
= list(FfsFile
.SectionList
)
4351 while SectionStack
!= []:
4352 SectionObj
= SectionStack
.pop()
4353 if isinstance(SectionObj
, FvImageSection
):
4354 if SectionObj
.FvName
is not None and SectionObj
.FvName
.upper() not in FvList
:
4355 FvList
.append(SectionObj
.FvName
.upper())
4356 if SectionObj
.Fv
is not None and SectionObj
.Fv
.UiFvName
is not None and SectionObj
.Fv
.UiFvName
.upper() not in FvList
:
4357 FvList
.append(SectionObj
.Fv
.UiFvName
.upper())
4358 self
._GetReferencedFdFvTuple
(SectionObj
.Fv
, FdList
, FvList
)
4360 if isinstance(SectionObj
, CompressSection
) or isinstance(SectionObj
, GuidSection
):
4361 SectionStack
.extend(SectionObj
.SectionList
)
4363 ## CycleReferenceCheck() method
4365 # Check whether cycle reference exists in FDF
4367 # @param self The object pointer
4368 # @retval True cycle reference exists
4369 # @retval False Not exists cycle reference
4371 def CycleReferenceCheck(self
):
4373 # Check the cycle between FV and FD image
4375 MaxLength
= len (self
.Profile
.FvDict
)
4376 for FvName
in self
.Profile
.FvDict
:
4377 LogStr
= "\nCycle Reference Checking for FV: %s\n" % FvName
4378 RefFvStack
= set(FvName
)
4379 FdAnalyzedList
= set()
4382 while RefFvStack
and Index
< MaxLength
:
4384 FvNameFromStack
= RefFvStack
.pop()
4385 if FvNameFromStack
.upper() in self
.Profile
.FvDict
:
4386 FvObj
= self
.Profile
.FvDict
[FvNameFromStack
.upper()]
4392 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4394 for RefFdName
in RefFdList
:
4395 if RefFdName
in FdAnalyzedList
:
4398 LogStr
+= "FV %s contains FD %s\n" % (FvNameFromStack
, RefFdName
)
4399 FvInFdList
= self
._GetFvInFd
(RefFdName
)
4400 if FvInFdList
!= []:
4401 for FvNameInFd
in FvInFdList
:
4402 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4403 if FvNameInFd
not in RefFvStack
:
4404 RefFvStack
.add(FvNameInFd
)
4406 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4407 EdkLogger
.info(LogStr
)
4409 FdAnalyzedList
.add(RefFdName
)
4411 for RefFvName
in RefFvList
:
4412 LogStr
+= "FV %s contains FV %s\n" % (FvNameFromStack
, RefFvName
)
4413 if RefFvName
not in RefFvStack
:
4414 RefFvStack
.add(RefFvName
)
4416 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4417 EdkLogger
.info(LogStr
)
4421 # Check the cycle between Capsule and FD image
4423 MaxLength
= len (self
.Profile
.CapsuleDict
)
4424 for CapName
in self
.Profile
.CapsuleDict
:
4426 # Capsule image to be checked.
4428 LogStr
= "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4429 RefCapStack
= {CapName}
4430 FdAnalyzedList
= set()
4431 FvAnalyzedList
= set()
4434 while RefCapStack
and Index
< MaxLength
:
4436 CapNameFromStack
= RefCapStack
.pop()
4437 if CapNameFromStack
.upper() in self
.Profile
.CapsuleDict
:
4438 CapObj
= self
.Profile
.CapsuleDict
[CapNameFromStack
.upper()]
4444 self
._GetReferencedFdCapTuple
(CapObj
, RefFdList
, RefFvList
)
4448 while FvListLength
< len (RefFvList
) or FdListLength
< len (RefFdList
):
4449 for RefFdName
in RefFdList
:
4450 if RefFdName
in FdAnalyzedList
:
4453 LogStr
+= "Capsule %s contains FD %s\n" % (CapNameFromStack
, RefFdName
)
4454 for CapNameInFd
in self
._GetCapInFd
(RefFdName
):
4455 LogStr
+= "FD %s contains Capsule %s\n" % (RefFdName
, CapNameInFd
)
4456 if CapNameInFd
not in RefCapStack
:
4457 RefCapStack
.append(CapNameInFd
)
4459 if CapName
in RefCapStack
or CapNameFromStack
in RefCapStack
:
4460 EdkLogger
.info(LogStr
)
4463 for FvNameInFd
in self
._GetFvInFd
(RefFdName
):
4464 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4465 if FvNameInFd
not in RefFvList
:
4466 RefFvList
.append(FvNameInFd
)
4468 FdAnalyzedList
.add(RefFdName
)
4470 # the number of the parsed FV and FD image
4472 FvListLength
= len (RefFvList
)
4473 FdListLength
= len (RefFdList
)
4474 for RefFvName
in RefFvList
:
4475 if RefFvName
in FvAnalyzedList
:
4477 LogStr
+= "Capsule %s contains FV %s\n" % (CapNameFromStack
, RefFvName
)
4478 if RefFvName
.upper() in self
.Profile
.FvDict
:
4479 FvObj
= self
.Profile
.FvDict
[RefFvName
.upper()]
4482 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4483 FvAnalyzedList
.add(RefFvName
)
4487 def GetAllIncludedFile (self
):
4488 global AllIncludeFileList
4489 return AllIncludeFileList
4491 if __name__
== "__main__":
4494 test_file
= sys
.argv
[1]
4495 except IndexError as v
:
4496 print("Usage: %s filename" % sys
.argv
[0])
4499 parser
= FdfParser(test_file
)
4502 parser
.CycleReferenceCheck()
4503 except Warning as X
: