4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 # Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
7 # This program and the accompanying materials
8 # are licensed and made available under the terms and conditions of the BSD License
9 # which accompanies this distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 from __future__
import print_function
20 from __future__
import absolute_import
21 from re
import compile, DOTALL
22 from string
import hexdigits
25 from Common
.BuildToolError
import *
26 from Common
import EdkLogger
27 from Common
.Misc
import PathClass
, tdict
, ProcessDuplicatedInf
28 from Common
.StringUtils
import NormPath
, ReplaceMacro
29 from Common
import GlobalData
30 from Common
.Expression
import *
31 from Common
.DataType
import *
32 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
33 import Common
.LongFilePathOs
as os
34 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
35 from Common
.RangeExpression
import RangeExpression
36 from collections
import OrderedDict
39 from .Region
import Region
41 from .AprioriSection
import AprioriSection
42 from .FfsInfStatement
import FfsInfStatement
43 from .FfsFileStatement
import FileStatement
44 from .VerSection
import VerSection
45 from .UiSection
import UiSection
46 from .FvImageSection
import FvImageSection
47 from .DataSection
import DataSection
48 from .DepexSection
import DepexSection
49 from .CompressSection
import CompressSection
50 from .GuidSection
import GuidSection
51 from .Capsule
import EFI_CERT_TYPE_PKCS7_GUID
, EFI_CERT_TYPE_RSA2048_SHA256_GUID
, Capsule
52 from .CapsuleData
import CapsuleFfs
, CapsulePayload
, CapsuleFv
, CapsuleFd
, CapsuleAnyFile
, CapsuleAfile
53 from .RuleComplexFile
import RuleComplexFile
54 from .RuleSimpleFile
import RuleSimpleFile
55 from .EfiSection
import EfiSection
57 from .ComponentStatement
import ComponentStatement
58 from .OptionRom
import OPTIONROM
59 from .OptRomInfStatement
import OptRomInfStatement
, OverrideAttribs
60 from .OptRomFileStatement
import OptRomFileStatement
61 from .GenFdsGlobalVariable
import GenFdsGlobalVariable
65 T_CHAR_DOUBLE_QUOTE
= '\"'
66 T_CHAR_SINGLE_QUOTE
= '\''
70 SEPARATORS
= {TAB_EQUAL_SPLIT
, TAB_VALUE_SPLIT
, TAB_COMMA_SPLIT
, '{', T_CHAR_BRACE_R
}
71 ALIGNMENTS
= {"Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K", "64K", "128K",
72 "256K", "512K", "1M", "2M", "4M", "8M", "16M"}
73 ALIGNMENT_NOAUTO
= ALIGNMENTS
- {"Auto"}
74 CR_LB_SET
= {T_CHAR_CR
, TAB_LINE_BREAK
}
76 RegionSizePattern
= compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
77 RegionSizeGuidPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*")
78 RegionOffsetPcdPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$")
79 ShortcutPcdPattern
= compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
80 BaseAddrValuePattern
= compile('^0[xX][0-9a-fA-F]+')
81 FileExtensionPattern
= compile(r
'([a-zA-Z][a-zA-Z0-9]*)')
82 TokenFindPattern
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
83 AllIncludeFileList
= []
85 # Get the closest parent
86 def GetParentAtLine (Line
):
87 for Profile
in AllIncludeFileList
:
88 if Profile
.IsLineInFile(Line
):
93 def IsValidInclude (File
, Line
):
94 for Profile
in AllIncludeFileList
:
95 if Profile
.IsLineInFile(Line
) and Profile
.FileName
== File
:
100 def GetRealFileLine (File
, Line
):
102 for Profile
in AllIncludeFileList
:
103 if Profile
.IsLineInFile(Line
):
104 return Profile
.GetLineInFile(Line
)
105 elif Line
>= Profile
.InsertStartLineNumber
and Profile
.Level
== 1:
106 InsertedLines
+= Profile
.GetTotalLines()
108 return (File
, Line
- InsertedLines
)
110 ## The exception class that used to report error messages when parsing FDF
112 # Currently the "ToolName" is set to be "FdfParser".
114 class Warning (Exception):
117 # @param self The object pointer
118 # @param Str The message to record
119 # @param File The FDF name
120 # @param Line The Line number that error occurs
122 def __init__(self
, Str
, File
= None, Line
= None):
123 FileLineTuple
= GetRealFileLine(File
, Line
)
124 self
.FileName
= FileLineTuple
[0]
125 self
.LineNumber
= FileLineTuple
[1]
126 self
.OriginalLineNumber
= Line
128 self
.ToolName
= 'FdfParser'
133 # helper functions to facilitate consistency in warnings
134 # each function is for a different common warning
136 def Expected(Str
, File
, Line
):
137 return Warning("expected {}".format(Str
), File
, Line
)
139 def ExpectedEquals(File
, Line
):
140 return Warning.Expected("'='", File
, Line
)
142 def ExpectedCurlyOpen(File
, Line
):
143 return Warning.Expected("'{'", File
, Line
)
145 def ExpectedCurlyClose(File
, Line
):
146 return Warning.Expected("'}'", File
, Line
)
148 def ExpectedBracketClose(File
, Line
):
149 return Warning.Expected("']'", File
, Line
)
151 ## The Include file content class that used to record file data when parsing include file
153 # May raise Exception when opening file.
155 class IncludeFileProfile
:
158 # @param self The object pointer
159 # @param FileName The file that to be parsed
161 def __init__(self
, FileName
):
162 self
.FileName
= FileName
163 self
.FileLinesList
= []
165 with
open(FileName
, "rb", 0) as fsock
:
166 self
.FileLinesList
= fsock
.readlines()
167 for index
, line
in enumerate(self
.FileLinesList
):
168 if not line
.endswith(TAB_LINE_BREAK
):
169 self
.FileLinesList
[index
] += TAB_LINE_BREAK
171 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
173 self
.InsertStartLineNumber
= None
174 self
.InsertAdjust
= 0
175 self
.IncludeFileList
= []
176 self
.Level
= 1 # first level include file
178 def GetTotalLines(self
):
179 TotalLines
= self
.InsertAdjust
+ len(self
.FileLinesList
)
181 for Profile
in self
.IncludeFileList
:
182 TotalLines
+= Profile
.GetTotalLines()
186 def IsLineInFile(self
, Line
):
187 if Line
>= self
.InsertStartLineNumber
and Line
< self
.InsertStartLineNumber
+ self
.GetTotalLines():
192 def GetLineInFile(self
, Line
):
193 if not self
.IsLineInFile (Line
):
194 return (self
.FileName
, -1)
196 InsertedLines
= self
.InsertStartLineNumber
198 for Profile
in self
.IncludeFileList
:
199 if Profile
.IsLineInFile(Line
):
200 return Profile
.GetLineInFile(Line
)
201 elif Line
>= Profile
.InsertStartLineNumber
:
202 InsertedLines
+= Profile
.GetTotalLines()
204 return (self
.FileName
, Line
- InsertedLines
+ 1)
206 ## The FDF content class that used to record file data when parsing FDF
208 # May raise Exception when opening file.
213 # @param self The object pointer
214 # @param FileName The file that to be parsed
216 def __init__(self
, FileName
):
217 self
.FileLinesList
= []
219 with
open(FileName
, "rb", 0) as fsock
:
220 self
.FileLinesList
= fsock
.readlines()
223 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
225 self
.FileName
= FileName
226 self
.PcdDict
= OrderedDict()
227 self
.PcdLocalDict
= OrderedDict()
229 self
.InfDict
= {'ArchTBD':[]}
230 # ECC will use this Dict and List information
231 self
.PcdFileLineDict
= {}
232 self
.InfFileLineList
= []
235 self
.FdNameNotSet
= False
237 self
.CapsuleDict
= {}
241 self
.FmpPayloadDict
= {}
243 ## The syntax parser for FDF
245 # PreprocessFile method should be called prior to ParseFile
246 # CycleReferenceCheck method can detect cycles in FDF contents
248 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
249 # Get*** procedures mean these procedures will make judgement on current token only.
254 # @param self The object pointer
255 # @param FileName The file that to be parsed
257 def __init__(self
, FileName
):
258 self
.Profile
= FileProfile(FileName
)
259 self
.FileName
= FileName
260 self
.CurrentLineNumber
= 1
261 self
.CurrentOffsetWithinLine
= 0
262 self
.CurrentFdName
= None
263 self
.CurrentFvName
= None
265 self
._SkippedChars
= ""
266 GlobalData
.gFdfParser
= self
268 # Used to section info
269 self
._CurSection
= []
270 # Key: [section name, UI name, arch]
271 # Value: {MACRO_NAME: MACRO_VALUE}
272 self
._MacroDict
= tdict(True, 3)
273 self
._PcdDict
= OrderedDict()
275 self
._WipeOffArea
= []
276 if GenFdsGlobalVariable
.WorkSpaceDir
== '':
277 GenFdsGlobalVariable
.WorkSpaceDir
= os
.getenv("WORKSPACE")
279 ## _SkipWhiteSpace() method
281 # Skip white spaces from current char.
283 # @param self The object pointer
285 def _SkipWhiteSpace(self
):
286 while not self
._EndOfFile
():
287 if self
._CurrentChar
() in {TAB_PRINTCHAR_NUL
, T_CHAR_CR
, TAB_LINE_BREAK
, TAB_SPACE_SPLIT
, T_CHAR_TAB
}:
288 self
._SkippedChars
+= str(self
._CurrentChar
())
294 ## _EndOfFile() method
296 # Judge current buffer pos is at file end
298 # @param self The object pointer
299 # @retval True Current File buffer position is at file end
300 # @retval False Current File buffer position is NOT at file end
302 def _EndOfFile(self
):
303 NumberOfLines
= len(self
.Profile
.FileLinesList
)
304 SizeOfLastLine
= len(self
.Profile
.FileLinesList
[-1])
305 if self
.CurrentLineNumber
== NumberOfLines
and self
.CurrentOffsetWithinLine
>= SizeOfLastLine
- 1:
307 if self
.CurrentLineNumber
> NumberOfLines
:
311 ## _EndOfLine() method
313 # Judge current buffer pos is at line end
315 # @param self The object pointer
316 # @retval True Current File buffer position is at line end
317 # @retval False Current File buffer position is NOT at line end
319 def _EndOfLine(self
):
320 if self
.CurrentLineNumber
> len(self
.Profile
.FileLinesList
):
322 SizeOfCurrentLine
= len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
323 if self
.CurrentOffsetWithinLine
>= SizeOfCurrentLine
:
329 # Reset file data buffer to the initial state
331 # @param self The object pointer
332 # @param DestLine Optional new destination line number.
333 # @param DestOffset Optional new destination offset.
335 def Rewind(self
, DestLine
= 1, DestOffset
= 0):
336 self
.CurrentLineNumber
= DestLine
337 self
.CurrentOffsetWithinLine
= DestOffset
339 ## _UndoOneChar() method
341 # Go back one char in the file buffer
343 # @param self The object pointer
344 # @retval True Successfully go back one char
345 # @retval False Not able to go back one char as file beginning reached
347 def _UndoOneChar(self
):
348 if self
.CurrentLineNumber
== 1 and self
.CurrentOffsetWithinLine
== 0:
350 elif self
.CurrentOffsetWithinLine
== 0:
351 self
.CurrentLineNumber
-= 1
352 self
.CurrentOffsetWithinLine
= len(self
._CurrentLine
()) - 1
354 self
.CurrentOffsetWithinLine
-= 1
357 ## _GetOneChar() method
359 # Move forward one char in the file buffer
361 # @param self The object pointer
363 def _GetOneChar(self
):
364 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
365 self
.CurrentLineNumber
+= 1
366 self
.CurrentOffsetWithinLine
= 0
368 self
.CurrentOffsetWithinLine
+= 1
370 ## _CurrentChar() method
372 # Get the char pointed to by the file buffer pointer
374 # @param self The object pointer
375 # @retval Char Current char
377 def _CurrentChar(self
):
378 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
]
380 ## _NextChar() method
382 # Get the one char pass the char pointed to by the file buffer pointer
384 # @param self The object pointer
385 # @retval Char Next char
388 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
389 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
][0]
390 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
+ 1]
392 ## _SetCurrentCharValue() method
394 # Modify the value of current char
396 # @param self The object pointer
397 # @param Value The new value of current char
399 def _SetCurrentCharValue(self
, Value
):
400 self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
] = Value
402 ## _CurrentLine() method
404 # Get the list that contains current line contents
406 # @param self The object pointer
407 # @retval List current line contents
409 def _CurrentLine(self
):
410 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
412 def _StringToList(self
):
413 self
.Profile
.FileLinesList
= [list(s
) for s
in self
.Profile
.FileLinesList
]
414 if not self
.Profile
.FileLinesList
:
415 EdkLogger
.error('FdfParser', FILE_READ_FAILURE
, 'The file is empty!', File
=self
.FileName
)
416 self
.Profile
.FileLinesList
[-1].append(' ')
418 def _ReplaceFragment(self
, StartPos
, EndPos
, Value
= ' '):
419 if StartPos
[0] == EndPos
[0]:
421 while Offset
<= EndPos
[1]:
422 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
427 while self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] not in CR_LB_SET
:
428 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
432 while Line
< EndPos
[0]:
434 while self
.Profile
.FileLinesList
[Line
][Offset
] not in CR_LB_SET
:
435 self
.Profile
.FileLinesList
[Line
][Offset
] = Value
440 while Offset
<= EndPos
[1]:
441 self
.Profile
.FileLinesList
[EndPos
[0]][Offset
] = Value
444 def _SetMacroValue(self
, Macro
, Value
):
445 if not self
._CurSection
:
449 if not self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]:
450 self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]] = MacroDict
452 MacroDict
= self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]
453 MacroDict
[Macro
] = Value
455 def _GetMacroValue(self
, Macro
):
457 if Macro
in GlobalData
.gCommandLineDefines
:
458 return GlobalData
.gCommandLineDefines
[Macro
]
459 if Macro
in GlobalData
.gGlobalDefines
:
460 return GlobalData
.gGlobalDefines
[Macro
]
463 MacroDict
= self
._MacroDict
[
468 if MacroDict
and Macro
in MacroDict
:
469 return MacroDict
[Macro
]
472 if Macro
in GlobalData
.gPlatformDefines
:
473 return GlobalData
.gPlatformDefines
[Macro
]
476 def _SectionHeaderParser(self
, Section
):
478 # [FD.UiName]: use dummy instead if UI name is optional
481 # [Rule]: don't take rule section into account, macro is not allowed in this section
482 # [VTF.arch.UiName, arch]
483 # [OptionRom.DriverName]
484 self
._CurSection
= []
485 Section
= Section
.strip()[1:-1].upper().replace(' ', '').strip(TAB_SPLIT
)
486 ItemList
= Section
.split(TAB_SPLIT
)
488 if Item
== '' or Item
== 'RULE':
491 if Item
== TAB_COMMON_DEFINES
.upper():
492 self
._CurSection
= [TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
493 elif Item
== 'VTF' and len(ItemList
) == 3:
495 Pos
= UiName
.find(TAB_COMMA_SPLIT
)
497 UiName
= UiName
[:Pos
]
498 self
._CurSection
= ['VTF', UiName
, ItemList
[1]]
499 elif len(ItemList
) > 1:
500 self
._CurSection
= [ItemList
[0], ItemList
[1], TAB_COMMON
]
501 elif len(ItemList
) > 0:
502 self
._CurSection
= [ItemList
[0], 'DUMMY', TAB_COMMON
]
504 ## PreprocessFile() method
506 # Preprocess file contents, replace comments with spaces.
507 # In the end, rewind the file buffer pointer to the beginning
508 # BUGBUG: No !include statement processing contained in this procedure
509 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
511 # @param self The object pointer
513 def PreprocessFile(self
):
516 DoubleSlashComment
= False
518 # HashComment in quoted string " " is ignored.
521 while not self
._EndOfFile
():
523 if self
._CurrentChar
() == T_CHAR_DOUBLE_QUOTE
and not InComment
:
524 InString
= not InString
525 # meet new line, then no longer in a comment for // and '#'
526 if self
._CurrentChar
() == TAB_LINE_BREAK
:
527 self
.CurrentLineNumber
+= 1
528 self
.CurrentOffsetWithinLine
= 0
529 if InComment
and DoubleSlashComment
:
531 DoubleSlashComment
= False
532 if InComment
and HashComment
:
535 # check for */ comment end
536 elif InComment
and not DoubleSlashComment
and not HashComment
and self
._CurrentChar
() == T_CHAR_STAR
and self
._NextChar
() == TAB_BACK_SLASH
:
537 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
539 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
542 # set comments to spaces
544 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
546 # check for // comment
547 elif self
._CurrentChar
() == TAB_BACK_SLASH
and self
._NextChar
() == TAB_BACK_SLASH
and not self
._EndOfLine
():
549 DoubleSlashComment
= True
550 # check for '#' comment
551 elif self
._CurrentChar
() == TAB_COMMENT_SPLIT
and not self
._EndOfLine
() and not InString
:
554 # check for /* comment start
555 elif self
._CurrentChar
() == TAB_BACK_SLASH
and self
._NextChar
() == T_CHAR_STAR
:
556 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
558 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
564 # restore from ListOfList to ListOfString
565 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
568 ## PreprocessIncludeFile() method
570 # Preprocess file contents, replace !include statements with file contents.
571 # In the end, rewind the file buffer pointer to the beginning
573 # @param self The object pointer
575 def PreprocessIncludeFile(self
):
576 # nested include support
579 while self
._GetNextToken
():
581 if self
._Token
== TAB_DEFINE
:
582 if not self
._GetNextToken
():
583 raise Warning.Expected("Macro name", self
.FileName
, self
.CurrentLineNumber
)
585 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
586 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
587 Value
= self
._GetExpression
()
588 MacroDict
[Macro
] = Value
590 elif self
._Token
== TAB_INCLUDE
:
592 IncludeLine
= self
.CurrentLineNumber
593 IncludeOffset
= self
.CurrentOffsetWithinLine
- len(TAB_INCLUDE
)
594 if not self
._GetNextToken
():
595 raise Warning.Expected("include file name", self
.FileName
, self
.CurrentLineNumber
)
596 IncFileName
= self
._Token
598 StartPos
= IncFileName
.find('$(', PreIndex
)
599 EndPos
= IncFileName
.find(')', StartPos
+2)
600 while StartPos
!= -1 and EndPos
!= -1:
601 Macro
= IncFileName
[StartPos
+2: EndPos
]
602 MacroVal
= self
._GetMacroValue
(Macro
)
604 if Macro
in MacroDict
:
605 MacroVal
= MacroDict
[Macro
]
606 if MacroVal
is not None:
607 IncFileName
= IncFileName
.replace('$(' + Macro
+ ')', MacroVal
, 1)
608 if MacroVal
.find('$(') != -1:
611 PreIndex
= StartPos
+ len(MacroVal
)
613 raise Warning("The Macro %s is not defined" %Macro
, self
.FileName
, self
.CurrentLineNumber
)
614 StartPos
= IncFileName
.find('$(', PreIndex
)
615 EndPos
= IncFileName
.find(')', StartPos
+2)
617 IncludedFile
= NormPath(IncFileName
)
619 # First search the include file under the same directory as FDF file
621 IncludedFile1
= PathClass(IncludedFile
, os
.path
.dirname(self
.FileName
))
622 ErrorCode
= IncludedFile1
.Validate()[0]
625 # Then search the include file under the same directory as DSC file
628 if GenFdsGlobalVariable
.ActivePlatform
:
629 PlatformDir
= GenFdsGlobalVariable
.ActivePlatform
.Dir
630 elif GlobalData
.gActivePlatform
:
631 PlatformDir
= GlobalData
.gActivePlatform
.MetaFile
.Dir
632 IncludedFile1
= PathClass(IncludedFile
, PlatformDir
)
633 ErrorCode
= IncludedFile1
.Validate()[0]
636 # Also search file under the WORKSPACE directory
638 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
639 ErrorCode
= IncludedFile1
.Validate()[0]
641 raise Warning("The include file does not exist under below directories: \n%s\n%s\n%s\n"%(os
.path
.dirname(self
.FileName
), PlatformDir
, GlobalData
.gWorkspace
),
642 self
.FileName
, self
.CurrentLineNumber
)
644 if not IsValidInclude (IncludedFile1
.Path
, self
.CurrentLineNumber
):
645 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1
.Path
), self
.FileName
, self
.CurrentLineNumber
)
647 IncFileProfile
= IncludeFileProfile(IncludedFile1
.Path
)
649 CurrentLine
= self
.CurrentLineNumber
650 CurrentOffset
= self
.CurrentOffsetWithinLine
651 # list index of the insertion, note that line number is 'CurrentLine + 1'
652 InsertAtLine
= CurrentLine
653 ParentProfile
= GetParentAtLine (CurrentLine
)
654 if ParentProfile
is not None:
655 ParentProfile
.IncludeFileList
.insert(0, IncFileProfile
)
656 IncFileProfile
.Level
= ParentProfile
.Level
+ 1
657 IncFileProfile
.InsertStartLineNumber
= InsertAtLine
+ 1
658 # deal with remaining portions after "!include filename", if exists.
659 if self
._GetNextToken
():
660 if self
.CurrentLineNumber
== CurrentLine
:
661 RemainingLine
= self
._CurrentLine
()[CurrentOffset
:]
662 self
.Profile
.FileLinesList
.insert(self
.CurrentLineNumber
, RemainingLine
)
663 IncFileProfile
.InsertAdjust
+= 1
664 self
.CurrentLineNumber
+= 1
665 self
.CurrentOffsetWithinLine
= 0
667 for Line
in IncFileProfile
.FileLinesList
:
668 self
.Profile
.FileLinesList
.insert(InsertAtLine
, Line
)
669 self
.CurrentLineNumber
+= 1
672 # reversely sorted to better determine error in file
673 AllIncludeFileList
.insert(0, IncFileProfile
)
675 # comment out the processed include file statement
676 TempList
= list(self
.Profile
.FileLinesList
[IncludeLine
- 1])
677 TempList
.insert(IncludeOffset
, TAB_COMMENT_SPLIT
)
678 self
.Profile
.FileLinesList
[IncludeLine
- 1] = ''.join(TempList
)
679 if Processed
: # Nested and back-to-back support
680 self
.Rewind(DestLine
= IncFileProfile
.InsertStartLineNumber
- 1)
686 def _GetIfListCurrentItemStat(IfList
):
696 ## PreprocessConditionalStatement() method
698 # Preprocess conditional statement.
699 # In the end, rewind the file buffer pointer to the beginning
701 # @param self The object pointer
703 def PreprocessConditionalStatement(self
):
704 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
708 while self
._GetNextToken
():
709 # Determine section name and the location dependent macro
710 if self
._GetIfListCurrentItemStat
(IfList
):
711 if self
._Token
.startswith(TAB_SECTION_START
):
713 if not self
._Token
.endswith(TAB_SECTION_END
):
714 self
._SkipToToken
(TAB_SECTION_END
)
715 Header
+= self
._SkippedChars
716 if Header
.find('$(') != -1:
717 raise Warning("macro cannot be used in section header", self
.FileName
, self
.CurrentLineNumber
)
718 self
._SectionHeaderParser
(Header
)
720 # Replace macros except in RULE section or out of section
721 elif self
._CurSection
and ReplacedLine
!= self
.CurrentLineNumber
:
722 ReplacedLine
= self
.CurrentLineNumber
724 CurLine
= self
.Profile
.FileLinesList
[ReplacedLine
- 1]
726 StartPos
= CurLine
.find('$(', PreIndex
)
727 EndPos
= CurLine
.find(')', StartPos
+2)
728 while StartPos
!= -1 and EndPos
!= -1 and self
._Token
not in {TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_IF
, TAB_ELSE_IF
}:
729 MacroName
= CurLine
[StartPos
+2: EndPos
]
730 MacorValue
= self
._GetMacroValue
(MacroName
)
731 if MacorValue
is not None:
732 CurLine
= CurLine
.replace('$(' + MacroName
+ ')', MacorValue
, 1)
733 if MacorValue
.find('$(') != -1:
736 PreIndex
= StartPos
+ len(MacorValue
)
738 PreIndex
= EndPos
+ 1
739 StartPos
= CurLine
.find('$(', PreIndex
)
740 EndPos
= CurLine
.find(')', StartPos
+2)
741 self
.Profile
.FileLinesList
[ReplacedLine
- 1] = CurLine
744 if self
._Token
== TAB_DEFINE
:
745 if self
._GetIfListCurrentItemStat
(IfList
):
746 if not self
._CurSection
:
747 raise Warning("macro cannot be defined in Rule section or out of section", self
.FileName
, self
.CurrentLineNumber
)
748 DefineLine
= self
.CurrentLineNumber
- 1
749 DefineOffset
= self
.CurrentOffsetWithinLine
- len(TAB_DEFINE
)
750 if not self
._GetNextToken
():
751 raise Warning.Expected("Macro name", self
.FileName
, self
.CurrentLineNumber
)
753 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
754 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
756 Value
= self
._GetExpression
()
757 self
._SetMacroValue
(Macro
, Value
)
758 self
._WipeOffArea
.append(((DefineLine
, DefineOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
759 elif self
._Token
== 'SET':
760 if not self
._GetIfListCurrentItemStat
(IfList
):
762 SetLine
= self
.CurrentLineNumber
- 1
763 SetOffset
= self
.CurrentOffsetWithinLine
- len('SET')
764 PcdPair
= self
._GetNextPcdSettings
()
765 PcdName
= "%s.%s" % (PcdPair
[1], PcdPair
[0])
766 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
767 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
769 Value
= self
._GetExpression
()
770 Value
= self
._EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
772 self
._PcdDict
[PcdName
] = Value
774 self
.Profile
.PcdDict
[PcdPair
] = Value
775 self
.SetPcdLocalation(PcdPair
)
776 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
777 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
779 self
._WipeOffArea
.append(((SetLine
, SetOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
780 elif self
._Token
in {TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_IF
}:
781 IfStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
._Token
))
782 IfList
.append([IfStartPos
, None, None])
784 CondLabel
= self
._Token
785 Expression
= self
._GetExpression
()
787 if CondLabel
== TAB_IF
:
788 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
790 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'in')
791 if CondLabel
== TAB_IF_N_DEF
:
792 ConditionSatisfied
= not ConditionSatisfied
794 BranchDetermined
= ConditionSatisfied
795 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, BranchDetermined
]
796 if ConditionSatisfied
:
797 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
798 elif self
._Token
in {TAB_ELSE_IF
, TAB_ELSE
}:
799 ElseStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
._Token
))
801 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
804 IfList
[-1] = [ElseStartPos
, False, True]
805 self
._WipeOffArea
.append((ElseStartPos
, (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
807 self
._WipeOffArea
.append((IfList
[-1][0], ElseStartPos
))
808 IfList
[-1] = [ElseStartPos
, True, IfList
[-1][2]]
809 if self
._Token
== TAB_ELSE_IF
:
810 Expression
= self
._GetExpression
()
811 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
812 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, IfList
[-1][2]]
816 IfList
[-1][1] = False
819 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
820 elif self
._Token
== '!endif':
822 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
824 self
._WipeOffArea
.append(((self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len('!endif')), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
826 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
829 elif not IfList
: # Don't use PCDs inside conditional directive
830 if self
.CurrentLineNumber
<= RegionLayoutLine
:
831 # Don't try the same line twice
833 SetPcd
= ShortcutPcdPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
835 self
._PcdDict
[SetPcd
.group('name')] = SetPcd
.group('value')
836 RegionLayoutLine
= self
.CurrentLineNumber
838 RegionSize
= RegionSizePattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
840 RegionLayoutLine
= self
.CurrentLineNumber
842 RegionSizeGuid
= RegionSizeGuidPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
])
843 if not RegionSizeGuid
:
844 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
846 self
._PcdDict
[RegionSizeGuid
.group('base')] = RegionSize
.group('base')
847 self
._PcdDict
[RegionSizeGuid
.group('size')] = RegionSize
.group('size')
848 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
851 raise Warning("Missing !endif", self
.FileName
, self
.CurrentLineNumber
)
854 def _CollectMacroPcd(self
):
858 MacroDict
.update(GlobalData
.gPlatformPcds
)
859 MacroDict
.update(self
._PcdDict
)
862 MacroDict
.update(GlobalData
.gPlatformDefines
)
866 ScopeMacro
= self
._MacroDict
[TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
868 MacroDict
.update(ScopeMacro
)
871 ScopeMacro
= self
._MacroDict
[
877 MacroDict
.update(ScopeMacro
)
879 MacroDict
.update(GlobalData
.gGlobalDefines
)
880 MacroDict
.update(GlobalData
.gCommandLineDefines
)
881 for Item
in GlobalData
.BuildOptionPcd
:
882 if isinstance(Item
, tuple):
884 PcdName
, TmpValue
= Item
.split(TAB_EQUAL_SPLIT
)
885 TmpValue
= BuildOptionValue(TmpValue
, {})
886 MacroDict
[PcdName
.strip()] = TmpValue
891 def _EvaluateConditional(self
, Expression
, Line
, Op
= None, Value
= None):
892 MacroPcdDict
= self
._CollectMacroPcd
()
896 return ValueExpression(Expression
, MacroPcdDict
)(True)
898 return ValueExpression(Expression
, MacroPcdDict
)()
899 except WrnExpression
as Excpt
:
901 # Catch expression evaluation warning here. We need to report
902 # the precise number of line and return the evaluation result
904 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
905 File
=self
.FileName
, ExtraData
=self
._CurrentLine
(),
908 except Exception as Excpt
:
909 if hasattr(Excpt
, 'Pcd'):
910 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
911 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
912 raise Warning("Cannot use this PCD (%s) in an expression as"
913 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
914 " of the DSC file (%s), and it is currently defined in this section:"
915 " %s, line #: %d." % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE'], Info
[0], Info
[1]),
918 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE']),
921 raise Warning(str(Excpt
), self
.FileName
, Line
)
923 if Expression
.startswith('$(') and Expression
[-1] == ')':
924 Expression
= Expression
[2:-1]
925 return Expression
in MacroPcdDict
929 # Check whether input string is found from current char position along
930 # If found, the string value is put into self._Token
932 # @param self The object pointer
933 # @param String The string to search
934 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
935 # @retval True Successfully find string, file buffer pointer moved forward
936 # @retval False Not able to find string, file buffer pointer not changed
938 def _IsToken(self
, String
, IgnoreCase
= False):
939 self
._SkipWhiteSpace
()
941 # Only consider the same line, no multi-line token allowed
942 StartPos
= self
.CurrentOffsetWithinLine
945 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
947 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
949 self
.CurrentOffsetWithinLine
+= len(String
)
950 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
954 ## _IsKeyword() method
956 # Check whether input keyword is found from current char position along, whole word only!
957 # If found, the string value is put into self._Token
959 # @param self The object pointer
960 # @param Keyword The string to search
961 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
962 # @retval True Successfully find string, file buffer pointer moved forward
963 # @retval False Not able to find string, file buffer pointer not changed
965 def _IsKeyword(self
, KeyWord
, IgnoreCase
= False):
966 self
._SkipWhiteSpace
()
968 # Only consider the same line, no multi-line token allowed
969 StartPos
= self
.CurrentOffsetWithinLine
972 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(KeyWord
.upper())
974 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(KeyWord
)
976 followingChar
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
+ len(KeyWord
)]
977 if not str(followingChar
).isspace() and followingChar
not in SEPARATORS
:
979 self
.CurrentOffsetWithinLine
+= len(KeyWord
)
980 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
984 def _GetExpression(self
):
985 Line
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
986 Index
= len(Line
) - 1
987 while Line
[Index
] in CR_LB_SET
:
989 ExpressionString
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:Index
+1]
990 self
.CurrentOffsetWithinLine
+= len(ExpressionString
)
991 ExpressionString
= ExpressionString
.strip()
992 return ExpressionString
994 ## _GetNextWord() method
996 # Get next C name from file lines
997 # If found, the string value is put into self._Token
999 # @param self The object pointer
1000 # @retval True Successfully find a C name string, file buffer pointer moved forward
1001 # @retval False Not able to find a C name string, file buffer pointer not changed
1003 def _GetNextWord(self
):
1004 self
._SkipWhiteSpace
()
1005 if self
._EndOfFile
():
1008 TempChar
= self
._CurrentChar
()
1009 StartPos
= self
.CurrentOffsetWithinLine
1010 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_':
1012 while not self
._EndOfLine
():
1013 TempChar
= self
._CurrentChar
()
1014 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1015 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-':
1021 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1026 def _GetNextPcdWord(self
):
1027 self
._SkipWhiteSpace
()
1028 if self
._EndOfFile
():
1031 TempChar
= self
._CurrentChar
()
1032 StartPos
= self
.CurrentOffsetWithinLine
1033 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_' or TempChar
== TAB_SECTION_START
or TempChar
== TAB_SECTION_END
:
1035 while not self
._EndOfLine
():
1036 TempChar
= self
._CurrentChar
()
1037 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1038 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-' or TempChar
== TAB_SECTION_START
or TempChar
== TAB_SECTION_END
:
1044 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1049 ## _GetNextToken() method
1051 # Get next token unit before a seperator
1052 # If found, the string value is put into self._Token
1054 # @param self The object pointer
1055 # @retval True Successfully find a token unit, file buffer pointer moved forward
1056 # @retval False Not able to find a token unit, file buffer pointer not changed
1058 def _GetNextToken(self
):
1059 # Skip leading spaces, if exist.
1060 self
._SkipWhiteSpace
()
1061 if self
._EndOfFile
():
1063 # Record the token start position, the position of the first non-space char.
1064 StartPos
= self
.CurrentOffsetWithinLine
1065 StartLine
= self
.CurrentLineNumber
1066 while StartLine
== self
.CurrentLineNumber
:
1067 TempChar
= self
._CurrentChar
()
1068 # Try to find the end char that is not a space and not in seperator tuple.
1069 # That is, when we got a space or any char in the tuple, we got the end of token.
1070 if not str(TempChar
).isspace() and TempChar
not in SEPARATORS
:
1072 # if we happen to meet a seperator as the first char, we must proceed to get it.
1073 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1074 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPARATORS
:
1082 EndPos
= self
.CurrentOffsetWithinLine
1083 if self
.CurrentLineNumber
!= StartLine
:
1084 EndPos
= len(self
.Profile
.FileLinesList
[StartLine
-1])
1085 self
._Token
= self
.Profile
.FileLinesList
[StartLine
-1][StartPos
: EndPos
]
1086 if self
._Token
.lower() in {TAB_IF
, TAB_END_IF
, TAB_ELSE_IF
, TAB_ELSE
, TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_ERROR
, TAB_INCLUDE
}:
1087 self
._Token
= self
._Token
.lower()
1088 if StartPos
!= self
.CurrentOffsetWithinLine
:
1093 ## _GetNextGuid() method
1095 # Get next token unit before a seperator
1096 # If found, the GUID string is put into self._Token
1098 # @param self The object pointer
1099 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
1100 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
1102 def _GetNextGuid(self
):
1103 if not self
._GetNextToken
():
1105 if gGuidPattern
.match(self
._Token
) is not None:
1112 def _Verify(Name
, Value
, Scope
):
1113 # value verification only applies to numeric values.
1114 if Scope
not in TAB_PCD_NUMERIC_TYPES
:
1119 ValueNumber
= int(Value
, 0)
1121 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value is not valid dec or hex number for %s." % Name
)
1123 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value can't be set to negative value for %s." % Name
)
1124 if ValueNumber
> MAX_VAL_TYPE
[Scope
]:
1125 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "Too large value for %s." % Name
)
1128 ## _UndoToken() method
1130 # Go back one token unit in file buffer
1132 # @param self The object pointer
1134 def _UndoToken(self
):
1136 while self
._CurrentChar
().isspace():
1137 if not self
._UndoOneChar
():
1142 StartPos
= self
.CurrentOffsetWithinLine
1143 CurrentLine
= self
.CurrentLineNumber
1144 while CurrentLine
== self
.CurrentLineNumber
:
1146 TempChar
= self
._CurrentChar
()
1147 # Try to find the end char that is not a space and not in seperator tuple.
1148 # That is, when we got a space or any char in the tuple, we got the end of token.
1149 if not str(TempChar
).isspace() and not TempChar
in SEPARATORS
:
1150 if not self
._UndoOneChar
():
1152 # if we happen to meet a seperator as the first char, we must proceed to get it.
1153 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1154 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPARATORS
:
1161 ## _GetNextHexNumber() method
1163 # Get next HEX data before a seperator
1164 # If found, the HEX data is put into self._Token
1166 # @param self The object pointer
1167 # @retval True Successfully find a HEX data, file buffer pointer moved forward
1168 # @retval False Not able to find a HEX data, file buffer pointer not changed
1170 def _GetNextHexNumber(self
):
1171 if not self
._GetNextToken
():
1173 if gHexPatternAll
.match(self
._Token
):
1179 ## _GetNextDecimalNumber() method
1181 # Get next decimal data before a seperator
1182 # If found, the decimal data is put into self._Token
1184 # @param self The object pointer
1185 # @retval True Successfully find a decimal data, file buffer pointer moved forward
1186 # @retval False Not able to find a decimal data, file buffer pointer not changed
1188 def _GetNextDecimalNumber(self
):
1189 if not self
._GetNextToken
():
1191 if self
._Token
.isdigit():
1197 def _GetNextPcdSettings(self
):
1198 if not self
._GetNextWord
():
1199 raise Warning.Expected("<PcdTokenSpaceCName>", self
.FileName
, self
.CurrentLineNumber
)
1200 pcdTokenSpaceCName
= self
._Token
1202 if not self
._IsToken
(TAB_SPLIT
):
1203 raise Warning.Expected(".", self
.FileName
, self
.CurrentLineNumber
)
1205 if not self
._GetNextWord
():
1206 raise Warning.Expected("<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1207 pcdCName
= self
._Token
1210 while self
._IsToken
(TAB_SPLIT
):
1211 if not self
._GetNextPcdWord
():
1212 raise Warning.Expected("Pcd Fields", self
.FileName
, self
.CurrentLineNumber
)
1213 Fields
.append(self
._Token
)
1215 return (pcdCName
, pcdTokenSpaceCName
,TAB_SPLIT
.join(Fields
))
1217 ## _GetStringData() method
1219 # Get string contents quoted in ""
1220 # If found, the decimal data is put into self._Token
1222 # @param self The object pointer
1223 # @retval True Successfully find a string data, file buffer pointer moved forward
1224 # @retval False Not able to find a string data, file buffer pointer not changed
1226 def _GetStringData(self
):
1228 if self
._Token
.startswith(T_CHAR_DOUBLE_QUOTE
) or self
._Token
.startswith("L\""):
1229 QuoteToUse
= T_CHAR_DOUBLE_QUOTE
1230 elif self
._Token
.startswith(T_CHAR_SINGLE_QUOTE
) or self
._Token
.startswith("L\'"):
1231 QuoteToUse
= T_CHAR_SINGLE_QUOTE
1236 self
._SkipToToken
(QuoteToUse
)
1237 currentLineNumber
= self
.CurrentLineNumber
1239 if not self
._SkipToToken
(QuoteToUse
):
1240 raise Warning(QuoteToUse
, self
.FileName
, self
.CurrentLineNumber
)
1241 if currentLineNumber
!= self
.CurrentLineNumber
:
1242 raise Warning(QuoteToUse
, self
.FileName
, self
.CurrentLineNumber
)
1243 self
._Token
= self
._SkippedChars
.rstrip(QuoteToUse
)
1246 ## _SkipToToken() method
1248 # Search forward in file buffer for the string
1249 # The skipped chars are put into self._SkippedChars
1251 # @param self The object pointer
1252 # @param String The string to search
1253 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1254 # @retval True Successfully find the string, file buffer pointer moved forward
1255 # @retval False Not able to find the string, file buffer pointer not changed
1257 def _SkipToToken(self
, String
, IgnoreCase
= False):
1258 StartPos
= self
.GetFileBufferPos()
1260 self
._SkippedChars
= ""
1261 while not self
._EndOfFile
():
1264 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
1266 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
1268 self
.CurrentOffsetWithinLine
+= len(String
)
1269 self
._SkippedChars
+= String
1271 self
._SkippedChars
+= str(self
._CurrentChar
())
1274 self
.SetFileBufferPos(StartPos
)
1275 self
._SkippedChars
= ""
1278 ## GetFileBufferPos() method
1280 # Return the tuple of current line and offset within the line
1282 # @param self The object pointer
1283 # @retval Tuple Line number and offset pair
1285 def GetFileBufferPos(self
):
1286 return (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
)
1288 ## SetFileBufferPos() method
1290 # Restore the file buffer position
1292 # @param self The object pointer
1293 # @param Pos The new file buffer position
1295 def SetFileBufferPos(self
, Pos
):
1296 (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
) = Pos
1298 ## Preprocess() method
1300 # Preprocess comment, conditional directive, include directive, replace macro.
1301 # Exception will be raised if syntax error found
1303 # @param self The object pointer
1305 def Preprocess(self
):
1306 self
._StringToList
()
1307 self
.PreprocessFile()
1308 self
.PreprocessIncludeFile()
1309 self
._StringToList
()
1310 self
.PreprocessFile()
1311 self
.PreprocessConditionalStatement()
1312 self
._StringToList
()
1313 for Pos
in self
._WipeOffArea
:
1314 self
._ReplaceFragment
(Pos
[0], Pos
[1])
1315 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
1317 while self
._GetDefines
():
1320 ## ParseFile() method
1322 # Parse the file profile buffer to extract fd, fv ... information
1323 # Exception will be raised if syntax error found
1325 # @param self The object pointer
1327 def ParseFile(self
):
1332 # Keep processing sections of the FDF until no new sections or a syntax error is found
1334 while self
._GetFd
() or self
._GetFv
() or self
._GetFmp
() or self
._GetCapsule
() or self
._GetVtf
() or self
._GetRule
() or self
._GetOptionRom
():
1337 except Warning as X
:
1339 #'\n\tGot Token: \"%s\" from File %s\n' % (self._Token, FileLineTuple[0]) + \
1340 # At this point, the closest parent would be the included file itself
1341 Profile
= GetParentAtLine(X
.OriginalLineNumber
)
1342 if Profile
is not None:
1343 X
.Message
+= ' near line %d, column %d: %s' \
1344 % (X
.LineNumber
, 0, Profile
.FileLinesList
[X
.LineNumber
-1])
1346 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1347 X
.Message
+= ' near line %d, column %d: %s' \
1348 % (FileLineTuple
[1], self
.CurrentOffsetWithinLine
+ 1, self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:].rstrip(TAB_LINE_BREAK
).rstrip(T_CHAR_CR
))
1351 ## SectionParser() method
1353 # Parse the file section info
1354 # Exception will be raised if syntax error found
1356 # @param self The object pointer
1357 # @param section The section string
1359 def SectionParser(self
, section
):
1361 if not S
.startswith("[DEFINES") and not S
.startswith("[FD.") and not S
.startswith("[FV.") and not S
.startswith("[CAPSULE.") \
1362 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM.") and not S
.startswith('[FMPPAYLOAD.'):
1363 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [VTF.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self
.FileName
, self
.CurrentLineNumber
)
1365 ## _GetDefines() method
1367 # Get Defines section contents and store its data into AllMacrosList
1369 # @param self The object pointer
1370 # @retval True Successfully find a Defines
1371 # @retval False Not able to find a Defines
1373 def _GetDefines(self
):
1374 if not self
._GetNextToken
():
1377 S
= self
._Token
.upper()
1378 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[DEFINES"):
1379 self
.SectionParser(S
)
1384 if not self
._IsToken
("[DEFINES", True):
1385 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1386 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1387 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1388 raise Warning.Expected("[DEFINES", self
.FileName
, self
.CurrentLineNumber
)
1390 if not self
._IsToken
(TAB_SECTION_END
):
1391 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
1393 while self
._GetNextWord
():
1394 # handle the SET statement
1395 if self
._Token
== 'SET':
1397 self
._GetSetStatement
(None)
1402 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1403 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1404 if not self
._GetNextToken
() or self
._Token
.startswith(TAB_SECTION_START
):
1405 raise Warning.Expected("MACRO value", self
.FileName
, self
.CurrentLineNumber
)
1410 ##_GetError() method
1411 def _GetError(self
):
1412 #save the Current information
1413 CurrentLine
= self
.CurrentLineNumber
1414 CurrentOffset
= self
.CurrentOffsetWithinLine
1415 while self
._GetNextToken
():
1416 if self
._Token
== TAB_ERROR
:
1417 EdkLogger
.error('FdfParser', ERROR_STATEMENT
, self
._CurrentLine
().replace(TAB_ERROR
, '', 1), File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
1418 self
.CurrentLineNumber
= CurrentLine
1419 self
.CurrentOffsetWithinLine
= CurrentOffset
1423 # Get FD section contents and store its data into FD dictionary of self.Profile
1425 # @param self The object pointer
1426 # @retval True Successfully find a FD
1427 # @retval False Not able to find a FD
1430 if not self
._GetNextToken
():
1433 S
= self
._Token
.upper()
1434 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FD."):
1435 if not S
.startswith("[FV.") and not S
.startswith('[FMPPAYLOAD.') and not S
.startswith("[CAPSULE.") \
1436 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM."):
1437 raise Warning("Unknown section", self
.FileName
, self
.CurrentLineNumber
)
1442 if not self
._IsToken
("[FD.", True):
1443 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1444 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1445 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1446 raise Warning.Expected("[FD.]", self
.FileName
, self
.CurrentLineNumber
)
1448 FdName
= self
._GetUiName
()
1450 if len (self
.Profile
.FdDict
) == 0:
1451 FdName
= GenFdsGlobalVariable
.PlatformName
1452 if FdName
== "" and GlobalData
.gActivePlatform
:
1453 FdName
= GlobalData
.gActivePlatform
.PlatformName
1454 self
.Profile
.FdNameNotSet
= True
1456 raise Warning.Expected("FdName in [FD.] section", self
.FileName
, self
.CurrentLineNumber
)
1457 self
.CurrentFdName
= FdName
.upper()
1459 if self
.CurrentFdName
in self
.Profile
.FdDict
:
1460 raise Warning("Unexpected the same FD name", self
.FileName
, self
.CurrentLineNumber
)
1462 if not self
._IsToken
(TAB_SECTION_END
):
1463 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
1466 FdObj
.FdUiName
= self
.CurrentFdName
1467 self
.Profile
.FdDict
[self
.CurrentFdName
] = FdObj
1469 if len (self
.Profile
.FdDict
) > 1 and self
.Profile
.FdNameNotSet
:
1470 raise Warning.Expected("all FDs have their name", self
.FileName
, self
.CurrentLineNumber
)
1472 Status
= self
._GetCreateFile
(FdObj
)
1474 raise Warning("FD name error", self
.FileName
, self
.CurrentLineNumber
)
1476 while self
._GetTokenStatements
(FdObj
):
1478 for Attr
in ("BaseAddress", "Size", "ErasePolarity"):
1479 if getattr(FdObj
, Attr
) is None:
1480 self
._GetNextToken
()
1481 raise Warning("Keyword %s missing" % Attr
, self
.FileName
, self
.CurrentLineNumber
)
1483 if not FdObj
.BlockSizeList
:
1484 FdObj
.BlockSizeList
.append((1, FdObj
.Size
, None))
1486 self
._GetDefineStatements
(FdObj
)
1488 self
._GetSetStatements
(FdObj
)
1490 if not self
._GetRegionLayout
(FdObj
):
1491 raise Warning.Expected("region layout", self
.FileName
, self
.CurrentLineNumber
)
1493 while self
._GetRegionLayout
(FdObj
):
1497 ## _GetUiName() method
1499 # Return the UI name of a section
1501 # @param self The object pointer
1502 # @retval FdName UI name
1504 def _GetUiName(self
):
1506 if self
._GetNextWord
():
1511 ## _GetCreateFile() method
1513 # Return the output file name of object
1515 # @param self The object pointer
1516 # @param Obj object whose data will be stored in file
1517 # @retval FdName UI name
1519 def _GetCreateFile(self
, Obj
):
1520 if self
._IsKeyword
("CREATE_FILE"):
1521 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1522 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1524 if not self
._GetNextToken
():
1525 raise Warning.Expected("file name", self
.FileName
, self
.CurrentLineNumber
)
1527 FileName
= self
._Token
1528 Obj
.CreateFileName
= FileName
1532 def SetPcdLocalation(self
,pcdpair
):
1533 self
.Profile
.PcdLocalDict
[pcdpair
] = (self
.Profile
.FileName
,self
.CurrentLineNumber
)
1535 ## _GetTokenStatements() method
1537 # Get token statements
1539 # @param self The object pointer
1540 # @param Obj for whom token statement is got
1542 def _GetTokenStatements(self
, Obj
):
1543 if self
._IsKeyword
("BaseAddress"):
1544 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1545 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1547 if not self
._GetNextHexNumber
():
1548 raise Warning.Expected("Hex base address", self
.FileName
, self
.CurrentLineNumber
)
1550 Obj
.BaseAddress
= self
._Token
1552 if self
._IsToken
(TAB_VALUE_SPLIT
):
1553 pcdPair
= self
._GetNextPcdSettings
()
1554 Obj
.BaseAddressPcd
= pcdPair
1555 self
.Profile
.PcdDict
[pcdPair
] = Obj
.BaseAddress
1556 self
.SetPcdLocalation(pcdPair
)
1557 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1558 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1561 if self
._IsKeyword
("Size"):
1562 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1563 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1565 if not self
._GetNextHexNumber
():
1566 raise Warning.Expected("Hex size", self
.FileName
, self
.CurrentLineNumber
)
1569 if self
._IsToken
(TAB_VALUE_SPLIT
):
1570 pcdPair
= self
._GetNextPcdSettings
()
1571 Obj
.SizePcd
= pcdPair
1572 self
.Profile
.PcdDict
[pcdPair
] = Size
1573 self
.SetPcdLocalation(pcdPair
)
1574 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1575 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1576 Obj
.Size
= long(Size
, 0)
1579 if self
._IsKeyword
("ErasePolarity"):
1580 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1581 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1583 if not self
._GetNextToken
():
1584 raise Warning.Expected("Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1586 if not self
._Token
in {"1", "0"}:
1587 raise Warning.Expected("1 or 0 Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1589 Obj
.ErasePolarity
= self
._Token
1592 return self
._GetBlockStatements
(Obj
)
1594 ## _GetAddressStatements() method
1596 # Get address statements
1598 # @param self The object pointer
1599 # @param Obj for whom address statement is got
1600 # @retval True Successfully find
1601 # @retval False Not able to find
1603 def _GetAddressStatements(self
, Obj
):
1604 if self
._IsKeyword
("BsBaseAddress"):
1605 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1606 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1608 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1609 raise Warning.Expected("address", self
.FileName
, self
.CurrentLineNumber
)
1611 BsAddress
= long(self
._Token
, 0)
1612 Obj
.BsBaseAddress
= BsAddress
1614 if self
._IsKeyword
("RtBaseAddress"):
1615 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1616 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1618 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1619 raise Warning.Expected("address", self
.FileName
, self
.CurrentLineNumber
)
1621 RtAddress
= long(self
._Token
, 0)
1622 Obj
.RtBaseAddress
= RtAddress
1624 ## _GetBlockStatements() method
1626 # Get block statements
1628 # @param self The object pointer
1629 # @param Obj for whom block statement is got
1631 def _GetBlockStatements(self
, Obj
):
1633 while self
._GetBlockStatement
(Obj
):
1636 Item
= Obj
.BlockSizeList
[-1]
1637 if Item
[0] is None or Item
[1] is None:
1638 raise Warning.Expected("block statement", self
.FileName
, self
.CurrentLineNumber
)
1641 ## _GetBlockStatement() method
1643 # Get block statement
1645 # @param self The object pointer
1646 # @param Obj for whom block statement is got
1647 # @retval True Successfully find
1648 # @retval False Not able to find
1650 def _GetBlockStatement(self
, Obj
):
1651 if not self
._IsKeyword
("BlockSize"):
1654 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1655 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1657 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
1658 raise Warning.Expected("Hex or Integer block size", self
.FileName
, self
.CurrentLineNumber
)
1660 BlockSize
= self
._Token
1662 if self
._IsToken
(TAB_VALUE_SPLIT
):
1663 PcdPair
= self
._GetNextPcdSettings
()
1664 BlockSizePcd
= PcdPair
1665 self
.Profile
.PcdDict
[PcdPair
] = BlockSize
1666 self
.SetPcdLocalation(PcdPair
)
1667 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1668 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1669 BlockSize
= long(BlockSize
, 0)
1672 if self
._IsKeyword
("NumBlocks"):
1673 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1674 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1676 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1677 raise Warning.Expected("block numbers", self
.FileName
, self
.CurrentLineNumber
)
1679 BlockNumber
= long(self
._Token
, 0)
1681 Obj
.BlockSizeList
.append((BlockSize
, BlockNumber
, BlockSizePcd
))
1684 ## _GetDefineStatements() method
1686 # Get define statements
1688 # @param self The object pointer
1689 # @param Obj for whom define statement is got
1690 # @retval True Successfully find
1691 # @retval False Not able to find
1693 def _GetDefineStatements(self
, Obj
):
1694 while self
._GetDefineStatement
(Obj
):
1697 ## _GetDefineStatement() method
1699 # Get define statement
1701 # @param self The object pointer
1702 # @param Obj for whom define statement is got
1703 # @retval True Successfully find
1704 # @retval False Not able to find
1706 def _GetDefineStatement(self
, Obj
):
1707 if self
._IsKeyword
(TAB_DEFINE
):
1708 self
._GetNextToken
()
1710 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1711 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1713 if not self
._GetNextToken
():
1714 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
1717 Macro
= '$(' + Macro
+ ')'
1718 Obj
.DefineVarDict
[Macro
] = Value
1723 ## _GetSetStatements() method
1725 # Get set statements
1727 # @param self The object pointer
1728 # @param Obj for whom set statement is got
1729 # @retval True Successfully find
1730 # @retval False Not able to find
1732 def _GetSetStatements(self
, Obj
):
1733 while self
._GetSetStatement
(Obj
):
1736 ## _GetSetStatement() method
1740 # @param self The object pointer
1741 # @param Obj for whom set statement is got
1742 # @retval True Successfully find
1743 # @retval False Not able to find
1745 def _GetSetStatement(self
, Obj
):
1746 if self
._IsKeyword
("SET"):
1747 PcdPair
= self
._GetNextPcdSettings
()
1749 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1750 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1752 Value
= self
._GetExpression
()
1753 Value
= self
._EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
1756 Obj
.SetVarDict
[PcdPair
] = Value
1757 self
.Profile
.PcdDict
[PcdPair
] = Value
1758 self
.SetPcdLocalation(PcdPair
)
1759 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1760 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1765 ## _CalcRegionExpr(self)
1767 # Calculate expression for offset or size of a region
1769 # @return: None if invalid expression
1770 # Calculated number if successfully
1772 def _CalcRegionExpr(self
):
1773 StartPos
= self
.GetFileBufferPos()
1776 while not self
._EndOfFile
():
1777 CurCh
= self
._CurrentChar
()
1783 if CurCh
in '|\r\n' and PairCount
== 0:
1789 ValueExpression(Expr
,
1790 self
._CollectMacroPcd
()
1793 self
.SetFileBufferPos(StartPos
)
1796 ## _GetRegionLayout() method
1798 # Get region layout for FD
1800 # @param self The object pointer
1801 # @param theFd for whom region is got
1802 # @retval True Successfully find
1803 # @retval False Not able to find
1805 def _GetRegionLayout(self
, theFd
):
1806 Offset
= self
._CalcRegionExpr
()
1810 RegionObj
= Region()
1811 RegionObj
.Offset
= Offset
1812 theFd
.RegionList
.append(RegionObj
)
1814 if not self
._IsToken
(TAB_VALUE_SPLIT
):
1815 raise Warning.Expected("'|'", self
.FileName
, self
.CurrentLineNumber
)
1817 Size
= self
._CalcRegionExpr
()
1819 raise Warning.Expected("Region Size", self
.FileName
, self
.CurrentLineNumber
)
1820 RegionObj
.Size
= Size
1822 if not self
._GetNextWord
():
1825 if not self
._Token
in {"SET", BINARY_FILE_TYPE_FV
, "FILE", "DATA", "CAPSULE", "INF"}:
1827 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1828 # Or it might be next region's offset described by an expression which starts with a PCD.
1829 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1832 IsRegionPcd
= (RegionSizeGuidPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]) or
1833 RegionOffsetPcdPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]))
1835 RegionObj
.PcdOffset
= self
._GetNextPcdSettings
()
1836 self
.Profile
.PcdDict
[RegionObj
.PcdOffset
] = "0x%08X" % (RegionObj
.Offset
+ long(theFd
.BaseAddress
, 0))
1837 self
.SetPcdLocalation(RegionObj
.PcdOffset
)
1838 self
._PcdDict
['%s.%s' % (RegionObj
.PcdOffset
[1], RegionObj
.PcdOffset
[0])] = "0x%x" % RegionObj
.Offset
1839 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1840 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdOffset
] = FileLineTuple
1841 if self
._IsToken
(TAB_VALUE_SPLIT
):
1842 RegionObj
.PcdSize
= self
._GetNextPcdSettings
()
1843 self
.Profile
.PcdDict
[RegionObj
.PcdSize
] = "0x%08X" % RegionObj
.Size
1844 self
.SetPcdLocalation(RegionObj
.PcdSize
)
1845 self
._PcdDict
['%s.%s' % (RegionObj
.PcdSize
[1], RegionObj
.PcdSize
[0])] = "0x%x" % RegionObj
.Size
1846 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1847 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdSize
] = FileLineTuple
1849 if not self
._GetNextWord
():
1852 if self
._Token
== "SET":
1854 self
._GetSetStatements
(RegionObj
)
1855 if not self
._GetNextWord
():
1858 elif self
._Token
== BINARY_FILE_TYPE_FV
:
1860 self
._GetRegionFvType
(RegionObj
)
1862 elif self
._Token
== "CAPSULE":
1864 self
._GetRegionCapType
(RegionObj
)
1866 elif self
._Token
== "FILE":
1868 self
._GetRegionFileType
(RegionObj
)
1870 elif self
._Token
== "INF":
1872 RegionObj
.RegionType
= "INF"
1873 while self
._IsKeyword
("INF"):
1875 ffsInf
= self
._ParseInfStatement
()
1878 RegionObj
.RegionDataList
.append(ffsInf
)
1880 elif self
._Token
== "DATA":
1882 self
._GetRegionDataType
(RegionObj
)
1885 if self
._GetRegionLayout
(theFd
):
1887 raise Warning("A valid region type was not found. "
1888 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
1889 self
.FileName
, self
.CurrentLineNumber
)
1893 ## _GetRegionFvType() method
1895 # Get region fv data for region
1897 # @param self The object pointer
1898 # @param RegionObj for whom region data is got
1900 def _GetRegionFvType(self
, RegionObj
):
1901 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1902 raise Warning.Expected("'FV'", self
.FileName
, self
.CurrentLineNumber
)
1904 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1905 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1907 if not self
._GetNextToken
():
1908 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
1910 RegionObj
.RegionType
= BINARY_FILE_TYPE_FV
1911 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1913 while self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1915 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1916 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1918 if not self
._GetNextToken
():
1919 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
1921 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1923 ## _GetRegionCapType() method
1925 # Get region capsule data for region
1927 # @param self The object pointer
1928 # @param RegionObj for whom region data is got
1930 def _GetRegionCapType(self
, RegionObj
):
1931 if not self
._IsKeyword
("CAPSULE"):
1932 raise Warning.Expected("'CAPSULE'", self
.FileName
, self
.CurrentLineNumber
)
1934 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1935 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1937 if not self
._GetNextToken
():
1938 raise Warning.Expected("CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1940 RegionObj
.RegionType
= "CAPSULE"
1941 RegionObj
.RegionDataList
.append(self
._Token
)
1943 while self
._IsKeyword
("CAPSULE"):
1945 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1946 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1948 if not self
._GetNextToken
():
1949 raise Warning.Expected("CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1951 RegionObj
.RegionDataList
.append(self
._Token
)
1953 ## _GetRegionFileType() method
1955 # Get region file data for region
1957 # @param self The object pointer
1958 # @param RegionObj for whom region data is got
1960 def _GetRegionFileType(self
, RegionObj
):
1961 if not self
._IsKeyword
("FILE"):
1962 raise Warning.Expected("'FILE'", self
.FileName
, self
.CurrentLineNumber
)
1964 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1965 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1967 if not self
._GetNextToken
():
1968 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
1970 RegionObj
.RegionType
= "FILE"
1971 RegionObj
.RegionDataList
.append(self
._Token
)
1973 while self
._IsKeyword
("FILE"):
1975 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1976 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1978 if not self
._GetNextToken
():
1979 raise Warning.Expected("FILE name", self
.FileName
, self
.CurrentLineNumber
)
1981 RegionObj
.RegionDataList
.append(self
._Token
)
1983 ## _GetRegionDataType() method
1985 # Get region array data for region
1987 # @param self The object pointer
1988 # @param RegionObj for whom region data is got
1990 def _GetRegionDataType(self
, RegionObj
):
1991 if not self
._IsKeyword
("DATA"):
1992 raise Warning.Expected("Region Data type", self
.FileName
, self
.CurrentLineNumber
)
1994 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1995 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1997 if not self
._IsToken
("{"):
1998 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2000 if not self
._GetNextHexNumber
():
2001 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2003 if len(self
._Token
) > 18:
2004 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2006 # convert hex string value to byte hex string array
2007 AllString
= self
._Token
2008 AllStrLen
= len (AllString
)
2010 while AllStrLen
> 4:
2011 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
2012 AllStrLen
= AllStrLen
- 2
2013 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
2016 if len (self
._Token
) <= 4:
2017 while self
._IsToken
(TAB_COMMA_SPLIT
):
2018 if not self
._GetNextHexNumber
():
2019 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2020 if len(self
._Token
) > 4:
2021 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2022 DataString
+= self
._Token
2023 DataString
+= TAB_COMMA_SPLIT
2025 if not self
._IsToken
(T_CHAR_BRACE_R
):
2026 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2028 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2029 RegionObj
.RegionType
= "DATA"
2030 RegionObj
.RegionDataList
.append(DataString
)
2032 while self
._IsKeyword
("DATA"):
2034 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2035 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2037 if not self
._IsToken
("{"):
2038 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2040 if not self
._GetNextHexNumber
():
2041 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2043 if len(self
._Token
) > 18:
2044 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2046 # convert hex string value to byte hex string array
2047 AllString
= self
._Token
2048 AllStrLen
= len (AllString
)
2050 while AllStrLen
> 4:
2051 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
2052 AllStrLen
= AllStrLen
- 2
2053 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
2056 if len (self
._Token
) <= 4:
2057 while self
._IsToken
(TAB_COMMA_SPLIT
):
2058 if not self
._GetNextHexNumber
():
2059 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2060 if len(self
._Token
) > 4:
2061 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2062 DataString
+= self
._Token
2063 DataString
+= TAB_COMMA_SPLIT
2065 if not self
._IsToken
(T_CHAR_BRACE_R
):
2066 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2068 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2069 RegionObj
.RegionDataList
.append(DataString
)
2073 # Get FV section contents and store its data into FV dictionary of self.Profile
2075 # @param self The object pointer
2076 # @retval True Successfully find a FV
2077 # @retval False Not able to find a FV
2080 if not self
._GetNextToken
():
2083 S
= self
._Token
.upper()
2084 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FV."):
2085 self
.SectionParser(S
)
2090 if not self
._IsToken
("[FV.", True):
2091 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2092 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2093 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2094 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2096 FvName
= self
._GetUiName
()
2097 self
.CurrentFvName
= FvName
.upper()
2099 if not self
._IsToken
(TAB_SECTION_END
):
2100 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
2102 FvObj
= FV(Name
=self
.CurrentFvName
)
2103 self
.Profile
.FvDict
[self
.CurrentFvName
] = FvObj
2105 Status
= self
._GetCreateFile
(FvObj
)
2107 raise Warning("FV name error", self
.FileName
, self
.CurrentLineNumber
)
2109 self
._GetDefineStatements
(FvObj
)
2111 self
._GetAddressStatements
(FvObj
)
2114 self
._GetSetStatements
(FvObj
)
2116 if not (self
._GetBlockStatement
(FvObj
) or self
._GetFvBaseAddress
(FvObj
) or
2117 self
._GetFvForceRebase
(FvObj
) or self
._GetFvAlignment
(FvObj
) or
2118 self
._GetFvAttributes
(FvObj
) or self
._GetFvNameGuid
(FvObj
) or
2119 self
._GetFvExtEntryStatement
(FvObj
) or self
._GetFvNameString
(FvObj
)):
2122 if FvObj
.FvNameString
== 'TRUE' and not FvObj
.FvNameGuid
:
2123 raise Warning("FvNameString found but FvNameGuid was not found", self
.FileName
, self
.CurrentLineNumber
)
2125 self
._GetAprioriSection
(FvObj
)
2126 self
._GetAprioriSection
(FvObj
)
2129 isInf
= self
._GetInfStatement
(FvObj
)
2130 isFile
= self
._GetFileStatement
(FvObj
)
2131 if not isInf
and not isFile
:
2136 ## _GetFvAlignment() method
2138 # Get alignment for FV
2140 # @param self The object pointer
2141 # @param Obj for whom alignment is got
2142 # @retval True Successfully find a alignment statement
2143 # @retval False Not able to find a alignment statement
2145 def _GetFvAlignment(self
, Obj
):
2146 if not self
._IsKeyword
("FvAlignment"):
2149 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2150 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2152 if not self
._GetNextToken
():
2153 raise Warning.Expected("alignment value", self
.FileName
, self
.CurrentLineNumber
)
2155 if self
._Token
.upper() not in {"1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2156 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2157 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2159 raise Warning("Unknown alignment value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2160 Obj
.FvAlignment
= self
._Token
2163 ## _GetFvBaseAddress() method
2165 # Get BaseAddress for FV
2167 # @param self The object pointer
2168 # @param Obj for whom FvBaseAddress is got
2169 # @retval True Successfully find a FvBaseAddress statement
2170 # @retval False Not able to find a FvBaseAddress statement
2172 def _GetFvBaseAddress(self
, Obj
):
2173 if not self
._IsKeyword
("FvBaseAddress"):
2176 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2177 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2179 if not self
._GetNextToken
():
2180 raise Warning.Expected("FV base address value", self
.FileName
, self
.CurrentLineNumber
)
2182 if not BaseAddrValuePattern
.match(self
._Token
.upper()):
2183 raise Warning("Unknown FV base address value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2184 Obj
.FvBaseAddress
= self
._Token
2187 ## _GetFvForceRebase() method
2189 # Get FvForceRebase for FV
2191 # @param self The object pointer
2192 # @param Obj for whom FvForceRebase is got
2193 # @retval True Successfully find a FvForceRebase statement
2194 # @retval False Not able to find a FvForceRebase statement
2196 def _GetFvForceRebase(self
, Obj
):
2197 if not self
._IsKeyword
("FvForceRebase"):
2200 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2201 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2203 if not self
._GetNextToken
():
2204 raise Warning.Expected("FvForceRebase value", self
.FileName
, self
.CurrentLineNumber
)
2206 if self
._Token
.upper() not in {"TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"}:
2207 raise Warning("Unknown FvForceRebase value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2209 if self
._Token
.upper() in {"TRUE", "1", "0X1", "0X01"}:
2210 Obj
.FvForceRebase
= True
2211 elif self
._Token
.upper() in {"FALSE", "0", "0X0", "0X00"}:
2212 Obj
.FvForceRebase
= False
2214 Obj
.FvForceRebase
= None
2219 ## _GetFvAttributes() method
2221 # Get attributes for FV
2223 # @param self The object pointer
2224 # @param Obj for whom attribute is got
2227 def _GetFvAttributes(self
, FvObj
):
2229 while self
._GetNextWord
():
2232 if name
not in {"ERASE_POLARITY", "MEMORY_MAPPED", \
2233 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2234 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2235 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2236 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2237 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"}:
2241 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2242 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2244 if not self
._GetNextToken
() or self
._Token
.upper() not in {"TRUE", "FALSE", "1", "0"}:
2245 raise Warning.Expected("TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
2247 FvObj
.FvAttributeDict
[name
] = self
._Token
2251 ## _GetFvNameGuid() method
2253 # Get FV GUID for FV
2255 # @param self The object pointer
2256 # @param Obj for whom GUID is got
2259 def _GetFvNameGuid(self
, FvObj
):
2260 if not self
._IsKeyword
("FvNameGuid"):
2263 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2264 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2266 if not self
._GetNextGuid
():
2267 raise Warning.Expected("GUID value", self
.FileName
, self
.CurrentLineNumber
)
2269 FvObj
.FvNameGuid
= self
._Token
2273 def _GetFvNameString(self
, FvObj
):
2274 if not self
._IsKeyword
("FvNameString"):
2277 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2278 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2280 if not self
._GetNextToken
() or self
._Token
.upper() not in {'TRUE', 'FALSE'}:
2281 raise Warning.Expected("TRUE or FALSE for FvNameString", self
.FileName
, self
.CurrentLineNumber
)
2283 FvObj
.FvNameString
= self
._Token
2287 def _GetFvExtEntryStatement(self
, FvObj
):
2288 if not (self
._IsKeyword
("FV_EXT_ENTRY") or self
._IsKeyword
("FV_EXT_ENTRY_TYPE")):
2291 if not self
._IsKeyword
("TYPE"):
2292 raise Warning.Expected("'TYPE'", self
.FileName
, self
.CurrentLineNumber
)
2294 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2295 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2297 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
2298 raise Warning.Expected("Hex FV extension entry type value At Line ", self
.FileName
, self
.CurrentLineNumber
)
2300 FvObj
.FvExtEntryTypeValue
.append(self
._Token
)
2302 if not self
._IsToken
("{"):
2303 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2305 if not self
._IsKeyword
("FILE") and not self
._IsKeyword
("DATA"):
2306 raise Warning.Expected("'FILE' or 'DATA'", self
.FileName
, self
.CurrentLineNumber
)
2308 FvObj
.FvExtEntryType
.append(self
._Token
)
2310 if self
._Token
== 'DATA':
2311 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2312 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2314 if not self
._IsToken
("{"):
2315 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2317 if not self
._GetNextHexNumber
():
2318 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2320 if len(self
._Token
) > 4:
2321 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2323 DataString
= self
._Token
2324 DataString
+= TAB_COMMA_SPLIT
2326 while self
._IsToken
(TAB_COMMA_SPLIT
):
2327 if not self
._GetNextHexNumber
():
2328 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2329 if len(self
._Token
) > 4:
2330 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2331 DataString
+= self
._Token
2332 DataString
+= TAB_COMMA_SPLIT
2334 if not self
._IsToken
(T_CHAR_BRACE_R
):
2335 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2337 if not self
._IsToken
(T_CHAR_BRACE_R
):
2338 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2340 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2341 FvObj
.FvExtEntryData
.append(DataString
)
2343 if self
._Token
== 'FILE':
2344 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2345 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2347 if not self
._GetNextToken
():
2348 raise Warning.Expected("FV Extension Entry file path At Line ", self
.FileName
, self
.CurrentLineNumber
)
2350 FvObj
.FvExtEntryData
.append(self
._Token
)
2352 if not self
._IsToken
(T_CHAR_BRACE_R
):
2353 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2357 ## _GetAprioriSection() method
2359 # Get token statements
2361 # @param self The object pointer
2362 # @param FvObj for whom apriori is got
2363 # @retval True Successfully find apriori statement
2364 # @retval False Not able to find apriori statement
2366 def _GetAprioriSection(self
, FvObj
):
2367 if not self
._IsKeyword
("APRIORI"):
2370 if not self
._IsKeyword
("PEI") and not self
._IsKeyword
("DXE"):
2371 raise Warning.Expected("Apriori file type", self
.FileName
, self
.CurrentLineNumber
)
2372 AprType
= self
._Token
2374 if not self
._IsToken
("{"):
2375 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2377 AprSectionObj
= AprioriSection()
2378 AprSectionObj
.AprioriType
= AprType
2380 self
._GetDefineStatements
(AprSectionObj
)
2383 IsInf
= self
._GetInfStatement
(AprSectionObj
)
2384 IsFile
= self
._GetFileStatement
(AprSectionObj
)
2385 if not IsInf
and not IsFile
:
2388 if not self
._IsToken
(T_CHAR_BRACE_R
):
2389 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2391 FvObj
.AprioriSectionList
.append(AprSectionObj
)
2394 def _ParseInfStatement(self
):
2395 if not self
._IsKeyword
("INF"):
2398 ffsInf
= FfsInfStatement()
2399 self
._GetInfOptions
(ffsInf
)
2401 if not self
._GetNextToken
():
2402 raise Warning.Expected("INF file path", self
.FileName
, self
.CurrentLineNumber
)
2403 ffsInf
.InfFileName
= self
._Token
2404 if not ffsInf
.InfFileName
.endswith('.inf'):
2405 raise Warning.Expected(".inf file path", self
.FileName
, self
.CurrentLineNumber
)
2407 ffsInf
.CurrentLineNum
= self
.CurrentLineNumber
2408 ffsInf
.CurrentLineContent
= self
._CurrentLine
()
2410 #Replace $(SAPCE) with real space
2411 ffsInf
.InfFileName
= ffsInf
.InfFileName
.replace('$(SPACE)', ' ')
2413 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
2414 #do case sensitive check for file path
2415 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2417 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2419 NewFileName
= ffsInf
.InfFileName
2420 if ffsInf
.OverrideGuid
:
2421 NewFileName
= ProcessDuplicatedInf(PathClass(ffsInf
.InfFileName
,GenFdsGlobalVariable
.WorkSpaceDir
), ffsInf
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
).Path
2423 if not NewFileName
in self
.Profile
.InfList
:
2424 self
.Profile
.InfList
.append(NewFileName
)
2425 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2426 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
2428 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
2429 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
2431 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
2433 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
2435 if self
._IsToken
(TAB_VALUE_SPLIT
):
2436 if self
._IsKeyword
('RELOCS_STRIPPED'):
2437 ffsInf
.KeepReloc
= False
2438 elif self
._IsKeyword
('RELOCS_RETAINED'):
2439 ffsInf
.KeepReloc
= True
2441 raise Warning("Unknown reloc strip flag '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2444 ## _GetInfStatement() method
2446 # Get INF statements
2448 # @param self The object pointer
2449 # @param Obj for whom inf statement is got
2450 # @retval True Successfully find inf statement
2451 # @retval False Not able to find inf statement
2453 def _GetInfStatement(self
, Obj
, ForCapsule
=False):
2454 ffsInf
= self
._ParseInfStatement
()
2459 myCapsuleFfs
= CapsuleFfs()
2460 myCapsuleFfs
.Ffs
= ffsInf
2461 Obj
.CapsuleDataList
.append(myCapsuleFfs
)
2463 Obj
.FfsList
.append(ffsInf
)
2466 ## _GetInfOptions() method
2468 # Get options for INF
2470 # @param self The object pointer
2471 # @param FfsInfObj for whom option is got
2473 def _GetInfOptions(self
, FfsInfObj
):
2474 if self
._IsKeyword
("FILE_GUID"):
2475 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2476 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2477 if not self
._GetNextGuid
():
2478 raise Warning.Expected("GUID value", self
.FileName
, self
.CurrentLineNumber
)
2479 FfsInfObj
.OverrideGuid
= self
._Token
2481 if self
._IsKeyword
("RuleOverride"):
2482 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2483 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2484 if not self
._GetNextToken
():
2485 raise Warning.Expected("Rule name", self
.FileName
, self
.CurrentLineNumber
)
2486 FfsInfObj
.Rule
= self
._Token
2488 if self
._IsKeyword
("VERSION"):
2489 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2490 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2491 if not self
._GetNextToken
():
2492 raise Warning.Expected("Version", self
.FileName
, self
.CurrentLineNumber
)
2494 if self
._GetStringData
():
2495 FfsInfObj
.Version
= self
._Token
2497 if self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2498 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2499 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2500 if not self
._GetNextToken
():
2501 raise Warning.Expected("UI name", self
.FileName
, self
.CurrentLineNumber
)
2503 if self
._GetStringData
():
2504 FfsInfObj
.Ui
= self
._Token
2506 if self
._IsKeyword
("USE"):
2507 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2508 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2509 if not self
._GetNextToken
():
2510 raise Warning.Expected("ARCH name", self
.FileName
, self
.CurrentLineNumber
)
2511 FfsInfObj
.UseArch
= self
._Token
2514 if self
._GetNextToken
():
2515 p
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2516 if p
.match(self
._Token
) and p
.match(self
._Token
).span()[1] == len(self
._Token
):
2517 FfsInfObj
.KeyStringList
.append(self
._Token
)
2518 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2524 while self
._GetNextToken
():
2525 if not p
.match(self
._Token
):
2526 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2527 FfsInfObj
.KeyStringList
.append(self
._Token
)
2529 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2532 ## _GetFileStatement() method
2534 # Get FILE statements
2536 # @param self The object pointer
2537 # @param Obj for whom FILE statement is got
2538 # @retval True Successfully find FILE statement
2539 # @retval False Not able to find FILE statement
2541 def _GetFileStatement(self
, Obj
, ForCapsule
= False):
2542 if not self
._IsKeyword
("FILE"):
2545 if not self
._GetNextWord
():
2546 raise Warning.Expected("FFS type", self
.FileName
, self
.CurrentLineNumber
)
2548 if ForCapsule
and self
._Token
== 'DATA':
2553 FfsFileObj
= FileStatement()
2554 FfsFileObj
.FvFileType
= self
._Token
2556 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2557 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2559 if not self
._GetNextGuid
():
2560 if not self
._GetNextWord
():
2561 raise Warning.Expected("File GUID", self
.FileName
, self
.CurrentLineNumber
)
2562 if self
._Token
== 'PCD':
2563 if not self
._IsToken
("("):
2564 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
2565 PcdPair
= self
._GetNextPcdSettings
()
2566 if not self
._IsToken
(")"):
2567 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
2568 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
2570 FfsFileObj
.NameGuid
= self
._Token
2572 self
._GetFilePart
(FfsFileObj
)
2575 capsuleFfs
= CapsuleFfs()
2576 capsuleFfs
.Ffs
= FfsFileObj
2577 Obj
.CapsuleDataList
.append(capsuleFfs
)
2579 Obj
.FfsList
.append(FfsFileObj
)
2583 ## _FileCouldHaveRelocFlag() method
2585 # Check whether reloc strip flag can be set for a file type.
2587 # @param FileType The file type to check with
2588 # @retval True This type could have relocation strip flag
2589 # @retval False No way to have it
2592 def _FileCouldHaveRelocFlag (FileType
):
2593 if FileType
in {SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
, 'PEI_DXE_COMBO'}:
2598 ## _SectionCouldHaveRelocFlag() method
2600 # Check whether reloc strip flag can be set for a section type.
2602 # @param SectionType The section type to check with
2603 # @retval True This type could have relocation strip flag
2604 # @retval False No way to have it
2607 def _SectionCouldHaveRelocFlag (SectionType
):
2608 if SectionType
in {BINARY_FILE_TYPE_TE
, BINARY_FILE_TYPE_PE32
}:
2613 ## _GetFilePart() method
2615 # Get components for FILE statement
2617 # @param self The object pointer
2618 # @param FfsFileObj for whom component is got
2620 def _GetFilePart(self
, FfsFileObj
):
2621 self
._GetFileOpts
(FfsFileObj
)
2623 if not self
._IsToken
("{"):
2624 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2625 if self
._FileCouldHaveRelocFlag
(FfsFileObj
.FvFileType
):
2626 if self
._Token
== 'RELOCS_STRIPPED':
2627 FfsFileObj
.KeepReloc
= False
2629 FfsFileObj
.KeepReloc
= True
2631 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj
.FvFileType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
2633 if not self
._IsToken
("{"):
2634 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2636 if not self
._GetNextToken
():
2637 raise Warning.Expected("File name or section data", self
.FileName
, self
.CurrentLineNumber
)
2639 if self
._Token
== BINARY_FILE_TYPE_FV
:
2640 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2641 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2642 if not self
._GetNextToken
():
2643 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
2644 FfsFileObj
.FvName
= self
._Token
2646 elif self
._Token
== "FD":
2647 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2648 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2649 if not self
._GetNextToken
():
2650 raise Warning.Expected("FD name", self
.FileName
, self
.CurrentLineNumber
)
2651 FfsFileObj
.FdName
= self
._Token
2653 elif self
._Token
in {TAB_DEFINE
, "APRIORI", "SECTION"}:
2655 self
._GetSectionData
(FfsFileObj
)
2657 elif hasattr(FfsFileObj
, 'FvFileType') and FfsFileObj
.FvFileType
== 'RAW':
2659 self
._GetRAWData
(FfsFileObj
)
2662 FfsFileObj
.CurrentLineNum
= self
.CurrentLineNumber
2663 FfsFileObj
.CurrentLineContent
= self
._CurrentLine
()
2664 FfsFileObj
.FileName
= self
._Token
.replace('$(SPACE)', ' ')
2665 self
._VerifyFile
(FfsFileObj
.FileName
)
2667 if not self
._IsToken
(T_CHAR_BRACE_R
):
2668 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2670 ## _GetRAWData() method
2672 # Get RAW data for FILE statement
2674 # @param self The object pointer
2675 # @param FfsFileObj for whom section is got
2677 def _GetRAWData(self
, FfsFileObj
):
2678 FfsFileObj
.FileName
= []
2679 FfsFileObj
.SubAlignment
= []
2682 if self
._GetAlignment
():
2683 if self
._Token
not in ALIGNMENTS
:
2684 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2685 #For FFS, Auto is default option same to ""
2686 if not self
._Token
== "Auto":
2687 AlignValue
= self
._Token
2688 if not self
._GetNextToken
():
2689 raise Warning.Expected("Filename value", self
.FileName
, self
.CurrentLineNumber
)
2691 FileName
= self
._Token
.replace('$(SPACE)', ' ')
2692 if FileName
== T_CHAR_BRACE_R
:
2694 raise Warning.Expected("Filename value", self
.FileName
, self
.CurrentLineNumber
)
2696 self
._VerifyFile
(FileName
)
2697 File
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
)
2698 FfsFileObj
.FileName
.append(File
.Path
)
2699 FfsFileObj
.SubAlignment
.append(AlignValue
)
2701 if self
._IsToken
(T_CHAR_BRACE_R
):
2705 if len(FfsFileObj
.SubAlignment
) == 1:
2706 FfsFileObj
.SubAlignment
= FfsFileObj
.SubAlignment
[0]
2707 if len(FfsFileObj
.FileName
) == 1:
2708 FfsFileObj
.FileName
= FfsFileObj
.FileName
[0]
2710 ## _GetFileOpts() method
2712 # Get options for FILE statement
2714 # @param self The object pointer
2715 # @param FfsFileObj for whom options is got
2717 def _GetFileOpts(self
, FfsFileObj
):
2718 if self
._GetNextToken
():
2719 if TokenFindPattern
.match(self
._Token
):
2720 FfsFileObj
.KeyStringList
.append(self
._Token
)
2721 if self
._IsToken
(TAB_COMMA_SPLIT
):
2722 while self
._GetNextToken
():
2723 if not TokenFindPattern
.match(self
._Token
):
2724 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2725 FfsFileObj
.KeyStringList
.append(self
._Token
)
2727 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2733 if self
._IsKeyword
("FIXED", True):
2734 FfsFileObj
.Fixed
= True
2736 if self
._IsKeyword
("CHECKSUM", True):
2737 FfsFileObj
.CheckSum
= True
2739 if self
._GetAlignment
():
2740 if self
._Token
not in ALIGNMENTS
:
2741 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2742 #For FFS, Auto is default option same to ""
2743 if not self
._Token
== "Auto":
2744 FfsFileObj
.Alignment
= self
._Token
2746 ## _GetAlignment() method
2748 # Return the alignment value
2750 # @param self The object pointer
2751 # @retval True Successfully find alignment
2752 # @retval False Not able to find alignment
2754 def _GetAlignment(self
):
2755 if self
._IsKeyword
("Align", True):
2756 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2757 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2759 if not self
._GetNextToken
():
2760 raise Warning.Expected("alignment value", self
.FileName
, self
.CurrentLineNumber
)
2765 ## _GetSectionData() method
2767 # Get section data for FILE statement
2769 # @param self The object pointer
2770 # @param FfsFileObj for whom section is got
2772 def _GetSectionData(self
, FfsFileObj
):
2773 self
._GetDefineStatements
(FfsFileObj
)
2776 IsLeafSection
= self
._GetLeafSection
(FfsFileObj
)
2777 IsEncapSection
= self
._GetEncapsulationSec
(FfsFileObj
)
2778 if not IsLeafSection
and not IsEncapSection
:
2781 ## _GetLeafSection() method
2783 # Get leaf section for Obj
2785 # @param self The object pointer
2786 # @param Obj for whom leaf section is got
2787 # @retval True Successfully find section statement
2788 # @retval False Not able to find section statement
2790 def _GetLeafSection(self
, Obj
):
2791 OldPos
= self
.GetFileBufferPos()
2793 if not self
._IsKeyword
("SECTION"):
2794 if len(Obj
.SectionList
) == 0:
2795 raise Warning.Expected("SECTION", self
.FileName
, self
.CurrentLineNumber
)
2800 if self
._GetAlignment
():
2801 if self
._Token
not in ALIGNMENTS
:
2802 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2803 AlignValue
= self
._Token
2806 if self
._IsKeyword
("BUILD_NUM"):
2807 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2808 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2810 if not self
._GetNextToken
():
2811 raise Warning.Expected("Build number value", self
.FileName
, self
.CurrentLineNumber
)
2813 BuildNum
= self
._Token
2815 if self
._IsKeyword
("VERSION"):
2816 if AlignValue
== 'Auto':
2817 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2818 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2819 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2820 if not self
._GetNextToken
():
2821 raise Warning.Expected("version", self
.FileName
, self
.CurrentLineNumber
)
2822 VerSectionObj
= VerSection()
2823 VerSectionObj
.Alignment
= AlignValue
2824 VerSectionObj
.BuildNum
= BuildNum
2825 if self
._GetStringData
():
2826 VerSectionObj
.StringData
= self
._Token
2828 VerSectionObj
.FileName
= self
._Token
2829 Obj
.SectionList
.append(VerSectionObj
)
2831 elif self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2832 if AlignValue
== 'Auto':
2833 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2834 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2835 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2836 if not self
._GetNextToken
():
2837 raise Warning.Expected("UI", self
.FileName
, self
.CurrentLineNumber
)
2838 UiSectionObj
= UiSection()
2839 UiSectionObj
.Alignment
= AlignValue
2840 if self
._GetStringData
():
2841 UiSectionObj
.StringData
= self
._Token
2843 UiSectionObj
.FileName
= self
._Token
2844 Obj
.SectionList
.append(UiSectionObj
)
2846 elif self
._IsKeyword
("FV_IMAGE"):
2847 if AlignValue
== 'Auto':
2848 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2849 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2850 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2851 if not self
._GetNextToken
():
2852 raise Warning.Expected("FV name or FV file path", self
.FileName
, self
.CurrentLineNumber
)
2854 FvName
= self
._Token
2857 if self
._IsToken
("{"):
2859 FvObj
.UiFvName
= FvName
.upper()
2860 self
._GetDefineStatements
(FvObj
)
2862 self
._GetBlockStatement
(FvObj
)
2863 self
._GetSetStatements
(FvObj
)
2864 self
._GetFvAlignment
(FvObj
)
2865 self
._GetFvAttributes
(FvObj
)
2868 IsInf
= self
._GetInfStatement
(FvObj
)
2869 IsFile
= self
._GetFileStatement
(FvObj
)
2870 if not IsInf
and not IsFile
:
2873 if not self
._IsToken
(T_CHAR_BRACE_R
):
2874 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2876 FvImageSectionObj
= FvImageSection()
2877 FvImageSectionObj
.Alignment
= AlignValue
2878 if FvObj
is not None:
2879 FvImageSectionObj
.Fv
= FvObj
2880 FvImageSectionObj
.FvName
= None
2882 FvImageSectionObj
.FvName
= FvName
.upper()
2883 FvImageSectionObj
.FvFileName
= FvName
2885 Obj
.SectionList
.append(FvImageSectionObj
)
2887 elif self
._IsKeyword
("PEI_DEPEX_EXP") or self
._IsKeyword
("DXE_DEPEX_EXP") or self
._IsKeyword
("SMM_DEPEX_EXP"):
2888 if AlignValue
== 'Auto':
2889 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2890 DepexSectionObj
= DepexSection()
2891 DepexSectionObj
.Alignment
= AlignValue
2892 DepexSectionObj
.DepexType
= self
._Token
2894 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2895 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2896 if not self
._IsToken
("{"):
2897 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2898 if not self
._SkipToToken
(T_CHAR_BRACE_R
):
2899 raise Warning.Expected("Depex expression ending '}'", self
.FileName
, self
.CurrentLineNumber
)
2901 DepexSectionObj
.Expression
= self
._SkippedChars
.rstrip(T_CHAR_BRACE_R
)
2902 Obj
.SectionList
.append(DepexSectionObj
)
2905 if not self
._GetNextWord
():
2906 raise Warning.Expected("section type", self
.FileName
, self
.CurrentLineNumber
)
2908 # Encapsulation section appear, UndoToken and return
2909 if self
._Token
== "COMPRESS" or self
._Token
== "GUIDED":
2910 self
.SetFileBufferPos(OldPos
)
2913 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
,\
2914 BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX
}:
2915 raise Warning("Unknown section type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2916 if AlignValue
== 'Auto'and (not self
._Token
== BINARY_FILE_TYPE_PE32
) and (not self
._Token
== BINARY_FILE_TYPE_TE
):
2917 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2920 DataSectionObj
= DataSection()
2921 DataSectionObj
.Alignment
= AlignValue
2922 DataSectionObj
.SecType
= self
._Token
2924 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2925 if self
._FileCouldHaveRelocFlag
(Obj
.FvFileType
) and self
._SectionCouldHaveRelocFlag
(DataSectionObj
.SecType
):
2926 if self
._Token
== 'RELOCS_STRIPPED':
2927 DataSectionObj
.KeepReloc
= False
2929 DataSectionObj
.KeepReloc
= True
2931 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
)
2933 if self
._IsToken
(TAB_EQUAL_SPLIT
):
2934 if not self
._GetNextToken
():
2935 raise Warning.Expected("section file path", self
.FileName
, self
.CurrentLineNumber
)
2936 DataSectionObj
.SectFileName
= self
._Token
2937 self
._VerifyFile
(DataSectionObj
.SectFileName
)
2939 if not self
._GetCglSection
(DataSectionObj
):
2942 Obj
.SectionList
.append(DataSectionObj
)
2948 # Check if file exists or not:
2949 # If current phase if GenFds, the file must exist;
2950 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
2951 # @param FileName: File path to be verified.
2953 def _VerifyFile(self
, FileName
):
2954 if FileName
.replace(TAB_WORKSPACE
, '').find('$') != -1:
2956 if not GlobalData
.gAutoGenPhase
or not self
._GetMacroValue
(TAB_DSC_DEFINES_OUTPUT_DIRECTORY
) in FileName
:
2957 ErrorCode
, ErrorInfo
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2959 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2961 ## _GetCglSection() method
2963 # Get compressed or GUIDed section for Obj
2965 # @param self The object pointer
2966 # @param Obj for whom leaf section is got
2967 # @param AlignValue alignment value for complex section
2968 # @retval True Successfully find section statement
2969 # @retval False Not able to find section statement
2971 def _GetCglSection(self
, Obj
, AlignValue
= None):
2973 if self
._IsKeyword
("COMPRESS"):
2975 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
2978 if not self
._IsToken
("{"):
2979 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2981 CompressSectionObj
= CompressSection()
2982 CompressSectionObj
.Alignment
= AlignValue
2983 CompressSectionObj
.CompType
= type
2984 # Recursive sections...
2986 IsLeafSection
= self
._GetLeafSection
(CompressSectionObj
)
2987 IsEncapSection
= self
._GetEncapsulationSec
(CompressSectionObj
)
2988 if not IsLeafSection
and not IsEncapSection
:
2992 if not self
._IsToken
(T_CHAR_BRACE_R
):
2993 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2994 Obj
.SectionList
.append(CompressSectionObj
)
2997 elif self
._IsKeyword
("GUIDED"):
2999 if self
._GetNextGuid
():
3000 GuidValue
= self
._Token
3002 AttribDict
= self
._GetGuidAttrib
()
3003 if not self
._IsToken
("{"):
3004 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
3005 GuidSectionObj
= GuidSection()
3006 GuidSectionObj
.Alignment
= AlignValue
3007 GuidSectionObj
.NameGuid
= GuidValue
3008 GuidSectionObj
.SectionType
= "GUIDED"
3009 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
3010 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
3011 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
3012 # Recursive sections...
3014 IsLeafSection
= self
._GetLeafSection
(GuidSectionObj
)
3015 IsEncapSection
= self
._GetEncapsulationSec
(GuidSectionObj
)
3016 if not IsLeafSection
and not IsEncapSection
:
3019 if not self
._IsToken
(T_CHAR_BRACE_R
):
3020 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3021 Obj
.SectionList
.append(GuidSectionObj
)
3027 ## _GetGuidAttri() method
3029 # Get attributes for GUID section
3031 # @param self The object pointer
3032 # @retval AttribDict Dictionary of key-value pair of section attributes
3034 def _GetGuidAttrib(self
):
3036 AttribDict
["PROCESSING_REQUIRED"] = "NONE"
3037 AttribDict
["AUTH_STATUS_VALID"] = "NONE"
3038 AttribDict
["EXTRA_HEADER_SIZE"] = -1
3039 while self
._IsKeyword
("PROCESSING_REQUIRED") or self
._IsKeyword
("AUTH_STATUS_VALID") \
3040 or self
._IsKeyword
("EXTRA_HEADER_SIZE"):
3041 AttribKey
= self
._Token
3043 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3044 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3046 if not self
._GetNextToken
():
3047 raise Warning.Expected("TRUE(1)/FALSE(0)/Number", self
.FileName
, self
.CurrentLineNumber
)
3048 elif AttribKey
== "EXTRA_HEADER_SIZE":
3050 if self
._Token
[0:2].upper() == "0X":
3053 AttribDict
[AttribKey
] = int(self
._Token
, Base
)
3056 raise Warning.Expected("Number", self
.FileName
, self
.CurrentLineNumber
)
3057 elif self
._Token
.upper() not in {"TRUE", "FALSE", "1", "0"}:
3058 raise Warning.Expected("TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
3059 AttribDict
[AttribKey
] = self
._Token
3063 ## _GetEncapsulationSec() method
3065 # Get encapsulation section for FILE
3067 # @param self The object pointer
3068 # @param FfsFile for whom section is got
3069 # @retval True Successfully find section statement
3070 # @retval False Not able to find section statement
3072 def _GetEncapsulationSec(self
, FfsFileObj
):
3073 OldPos
= self
.GetFileBufferPos()
3074 if not self
._IsKeyword
("SECTION"):
3075 if len(FfsFileObj
.SectionList
) == 0:
3076 raise Warning.Expected("SECTION", self
.FileName
, self
.CurrentLineNumber
)
3081 if self
._GetAlignment
():
3082 if self
._Token
not in ALIGNMENT_NOAUTO
:
3083 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3084 AlignValue
= self
._Token
3086 if not self
._GetCglSection
(FfsFileObj
, AlignValue
):
3087 self
.SetFileBufferPos(OldPos
)
3093 if not self
._GetNextToken
():
3095 S
= self
._Token
.upper()
3096 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FMPPAYLOAD."):
3097 self
.SectionParser(S
)
3102 self
._SkipToToken
("[FMPPAYLOAD.", True)
3103 FmpUiName
= self
._GetUiName
().upper()
3104 if FmpUiName
in self
.Profile
.FmpPayloadDict
:
3105 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName
, self
.FileName
, self
.CurrentLineNumber
)
3107 FmpData
= CapsulePayload()
3108 FmpData
.UiName
= FmpUiName
3110 if not self
._IsToken
(TAB_SECTION_END
):
3111 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3113 if not self
._GetNextToken
():
3114 raise Warning("The FMP payload section is empty!", self
.FileName
, self
.CurrentLineNumber
)
3115 FmpKeyList
= ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']
3116 while self
._Token
in FmpKeyList
:
3118 FmpKeyList
.remove(Name
)
3119 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3120 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3121 if Name
== 'IMAGE_TYPE_ID':
3122 if not self
._GetNextGuid
():
3123 raise Warning.Expected("GUID value for IMAGE_TYPE_ID.", self
.FileName
, self
.CurrentLineNumber
)
3124 FmpData
.ImageTypeId
= self
._Token
3125 elif Name
== 'CERTIFICATE_GUID':
3126 if not self
._GetNextGuid
():
3127 raise Warning.Expected("GUID value for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3128 FmpData
.Certificate_Guid
= self
._Token
3129 if UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_RSA2048_SHA256_GUID
and UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_PKCS7_GUID
:
3130 raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3132 if not self
._GetNextToken
():
3133 raise Warning.Expected("value of %s" % Name
, self
.FileName
, self
.CurrentLineNumber
)
3135 if Name
== 'IMAGE_HEADER_INIT_VERSION':
3136 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3137 FmpData
.Version
= Value
3138 elif Name
== 'IMAGE_INDEX':
3139 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3140 FmpData
.ImageIndex
= Value
3141 elif Name
== 'HARDWARE_INSTANCE':
3142 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3143 FmpData
.HardwareInstance
= Value
3144 elif Name
== 'MONOTONIC_COUNT':
3145 if FdfParser
._Verify
(Name
, Value
, 'UINT64'):
3146 FmpData
.MonotonicCount
= Value
3147 if FmpData
.MonotonicCount
.upper().startswith('0X'):
3148 FmpData
.MonotonicCount
= (long)(FmpData
.MonotonicCount
, 16)
3150 FmpData
.MonotonicCount
= (long)(FmpData
.MonotonicCount
)
3151 if not self
._GetNextToken
():
3156 if (FmpData
.MonotonicCount
and not FmpData
.Certificate_Guid
) or (not FmpData
.MonotonicCount
and FmpData
.Certificate_Guid
):
3157 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")
3159 # Only the IMAGE_TYPE_ID is required item
3160 if FmpKeyList
and 'IMAGE_TYPE_ID' in FmpKeyList
:
3161 raise Warning("'IMAGE_TYPE_ID' in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3162 # get the Image file and Vendor code file
3163 self
._GetFMPCapsuleData
(FmpData
)
3164 if not FmpData
.ImageFile
:
3165 raise Warning("Missing image file in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3166 # check whether more than one Vendor code file
3167 if len(FmpData
.VendorCodeFile
) > 1:
3168 raise Warning("Vendor code file max of 1 per FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3169 self
.Profile
.FmpPayloadDict
[FmpUiName
] = FmpData
3172 ## _GetCapsule() method
3174 # Get capsule section contents and store its data into capsule list of self.Profile
3176 # @param self The object pointer
3177 # @retval True Successfully find a capsule
3178 # @retval False Not able to find a capsule
3180 def _GetCapsule(self
):
3181 if not self
._GetNextToken
():
3184 S
= self
._Token
.upper()
3185 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[CAPSULE."):
3186 self
.SectionParser(S
)
3191 if not self
._IsToken
("[CAPSULE.", True):
3192 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3193 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3194 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3195 raise Warning.Expected("[Capsule.]", self
.FileName
, self
.CurrentLineNumber
)
3197 CapsuleObj
= Capsule()
3199 CapsuleName
= self
._GetUiName
()
3201 raise Warning.Expected("capsule name", self
.FileName
, self
.CurrentLineNumber
)
3203 CapsuleObj
.UiCapsuleName
= CapsuleName
.upper()
3205 if not self
._IsToken
(TAB_SECTION_END
):
3206 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3208 if self
._IsKeyword
("CREATE_FILE"):
3209 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3210 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3212 if not self
._GetNextToken
():
3213 raise Warning.Expected("file name", self
.FileName
, self
.CurrentLineNumber
)
3215 CapsuleObj
.CreateFile
= self
._Token
3217 self
._GetCapsuleStatements
(CapsuleObj
)
3218 self
.Profile
.CapsuleDict
[CapsuleObj
.UiCapsuleName
] = CapsuleObj
3221 ## _GetCapsuleStatements() method
3223 # Get statements for capsule
3225 # @param self The object pointer
3226 # @param Obj for whom statements are got
3228 def _GetCapsuleStatements(self
, Obj
):
3229 self
._GetCapsuleTokens
(Obj
)
3230 self
._GetDefineStatements
(Obj
)
3231 self
._GetSetStatements
(Obj
)
3232 self
._GetCapsuleData
(Obj
)
3234 ## _GetCapsuleTokens() method
3236 # Get token statements for capsule
3238 # @param self The object pointer
3239 # @param Obj for whom token statements are got
3241 def _GetCapsuleTokens(self
, Obj
):
3242 if not self
._GetNextToken
():
3244 while self
._Token
in {"CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"}:
3245 Name
= self
._Token
.strip()
3246 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3247 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3248 if not self
._GetNextToken
():
3249 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
3250 if Name
== 'CAPSULE_FLAGS':
3251 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3252 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3253 Value
= self
._Token
.strip()
3254 while self
._IsToken
(TAB_COMMA_SPLIT
):
3255 Value
+= TAB_COMMA_SPLIT
3256 if not self
._GetNextToken
():
3257 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
3258 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3259 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3260 Value
+= self
._Token
.strip()
3261 elif Name
== 'OEM_CAPSULE_FLAGS':
3262 Value
= self
._Token
.strip()
3263 if not Value
.upper().startswith('0X'):
3264 raise Warning.Expected("hex value starting with 0x", self
.FileName
, self
.CurrentLineNumber
)
3266 Value
= int(Value
, 0)
3268 raise Warning.Expected("hex string failed to convert to value", self
.FileName
, self
.CurrentLineNumber
)
3269 if not 0x0000 <= Value
<= 0xFFFF:
3270 raise Warning.Expected("hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3271 Value
= self
._Token
.strip()
3273 Value
= self
._Token
.strip()
3274 Obj
.TokensDict
[Name
] = Value
3275 if not self
._GetNextToken
():
3279 ## _GetCapsuleData() method
3281 # Get capsule data for capsule
3283 # @param self The object pointer
3284 # @param Obj for whom capsule data are got
3286 def _GetCapsuleData(self
, Obj
):
3288 IsInf
= self
._GetInfStatement
(Obj
, True)
3289 IsFile
= self
._GetFileStatement
(Obj
, True)
3290 IsFv
= self
._GetFvStatement
(Obj
)
3291 IsFd
= self
._GetFdStatement
(Obj
)
3292 IsAnyFile
= self
._GetAnyFileStatement
(Obj
)
3293 IsAfile
= self
._GetAfileStatement
(Obj
)
3294 IsFmp
= self
._GetFmpStatement
(Obj
)
3295 if not (IsInf
or IsFile
or IsFv
or IsFd
or IsAnyFile
or IsAfile
or IsFmp
):
3298 ## _GetFMPCapsuleData() method
3300 # Get capsule data for FMP capsule
3302 # @param self The object pointer
3303 # @param Obj for whom capsule data are got
3305 def _GetFMPCapsuleData(self
, Obj
):
3307 IsFv
= self
._GetFvStatement
(Obj
, True)
3308 IsFd
= self
._GetFdStatement
(Obj
, True)
3309 IsAnyFile
= self
._GetAnyFileStatement
(Obj
, True)
3310 if not (IsFv
or IsFd
or IsAnyFile
):
3313 ## _GetFvStatement() method
3315 # Get FV for capsule
3317 # @param self The object pointer
3318 # @param CapsuleObj for whom FV is got
3319 # @retval True Successfully find a FV statement
3320 # @retval False Not able to find a FV statement
3322 def _GetFvStatement(self
, CapsuleObj
, FMPCapsule
= False):
3323 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3326 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3327 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3329 if not self
._GetNextToken
():
3330 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
3332 if self
._Token
.upper() not in self
.Profile
.FvDict
:
3333 raise Warning("FV name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3335 myCapsuleFv
= CapsuleFv()
3336 myCapsuleFv
.FvName
= self
._Token
3338 if not CapsuleObj
.ImageFile
:
3339 CapsuleObj
.ImageFile
.append(myCapsuleFv
)
3341 CapsuleObj
.VendorCodeFile
.append(myCapsuleFv
)
3343 CapsuleObj
.CapsuleDataList
.append(myCapsuleFv
)
3346 ## _GetFdStatement() method
3348 # Get FD for capsule
3350 # @param self The object pointer
3351 # @param CapsuleObj for whom FD is got
3352 # @retval True Successfully find a FD statement
3353 # @retval False Not able to find a FD statement
3355 def _GetFdStatement(self
, CapsuleObj
, FMPCapsule
= False):
3356 if not self
._IsKeyword
("FD"):
3359 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3360 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3362 if not self
._GetNextToken
():
3363 raise Warning.Expected("FD name", self
.FileName
, self
.CurrentLineNumber
)
3365 if self
._Token
.upper() not in self
.Profile
.FdDict
:
3366 raise Warning("FD name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3368 myCapsuleFd
= CapsuleFd()
3369 myCapsuleFd
.FdName
= self
._Token
3371 if not CapsuleObj
.ImageFile
:
3372 CapsuleObj
.ImageFile
.append(myCapsuleFd
)
3374 CapsuleObj
.VendorCodeFile
.append(myCapsuleFd
)
3376 CapsuleObj
.CapsuleDataList
.append(myCapsuleFd
)
3379 def _GetFmpStatement(self
, CapsuleObj
):
3380 if not self
._IsKeyword
("FMP_PAYLOAD"):
3381 if not self
._IsKeyword
("FMP"):
3384 if not self
._IsKeyword
("PAYLOAD"):
3388 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3389 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3391 if not self
._GetNextToken
():
3392 raise Warning.Expected("payload name after FMP_PAYLOAD =", self
.FileName
, self
.CurrentLineNumber
)
3393 Payload
= self
._Token
.upper()
3394 if Payload
not in self
.Profile
.FmpPayloadDict
:
3395 raise Warning("This FMP Payload does not exist: %s" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3396 CapsuleObj
.FmpPayloadList
.append(self
.Profile
.FmpPayloadDict
[Payload
])
3399 def _ParseRawFileStatement(self
):
3400 if not self
._IsKeyword
("FILE"):
3403 if not self
._IsKeyword
("DATA"):
3407 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3408 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3410 if not self
._GetNextToken
():
3411 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
3413 AnyFileName
= self
._Token
3414 self
._VerifyFile
(AnyFileName
)
3416 if not os
.path
.isabs(AnyFileName
):
3417 AnyFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, AnyFileName
)
3421 ## _GetAnyFileStatement() method
3423 # Get AnyFile for capsule
3425 # @param self The object pointer
3426 # @param CapsuleObj for whom AnyFile is got
3427 # @retval True Successfully find a Anyfile statement
3428 # @retval False Not able to find a AnyFile statement
3430 def _GetAnyFileStatement(self
, CapsuleObj
, FMPCapsule
= False):
3431 AnyFileName
= self
._ParseRawFileStatement
()
3435 myCapsuleAnyFile
= CapsuleAnyFile()
3436 myCapsuleAnyFile
.FileName
= AnyFileName
3438 if not CapsuleObj
.ImageFile
:
3439 CapsuleObj
.ImageFile
.append(myCapsuleAnyFile
)
3441 CapsuleObj
.VendorCodeFile
.append(myCapsuleAnyFile
)
3443 CapsuleObj
.CapsuleDataList
.append(myCapsuleAnyFile
)
3446 ## _GetAfileStatement() method
3448 # Get Afile for capsule
3450 # @param self The object pointer
3451 # @param CapsuleObj for whom Afile is got
3452 # @retval True Successfully find a Afile statement
3453 # @retval False Not able to find a Afile statement
3455 def _GetAfileStatement(self
, CapsuleObj
):
3456 if not self
._IsKeyword
("APPEND"):
3459 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3460 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3462 if not self
._GetNextToken
():
3463 raise Warning.Expected("Afile name", self
.FileName
, self
.CurrentLineNumber
)
3465 AfileName
= self
._Token
3466 AfileBaseName
= os
.path
.basename(AfileName
)
3468 if os
.path
.splitext(AfileBaseName
)[1] not in {".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"}:
3469 raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \
3470 self
.FileName
, self
.CurrentLineNumber
)
3472 if not os
.path
.isabs(AfileName
):
3473 AfileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(AfileName
)
3474 self
._VerifyFile
(AfileName
)
3476 if not os
.path
.exists(AfileName
):
3477 raise Warning('%s does not exist' % AfileName
, self
.FileName
, self
.CurrentLineNumber
)
3481 myCapsuleAfile
= CapsuleAfile()
3482 myCapsuleAfile
.FileName
= AfileName
3483 CapsuleObj
.CapsuleDataList
.append(myCapsuleAfile
)
3486 ## _GetRule() method
3488 # Get Rule section contents and store its data into rule list of self.Profile
3490 # @param self The object pointer
3491 # @retval True Successfully find a Rule
3492 # @retval False Not able to find a Rule
3495 if not self
._GetNextToken
():
3498 S
= self
._Token
.upper()
3499 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[RULE."):
3500 self
.SectionParser(S
)
3504 if not self
._IsToken
("[Rule.", True):
3505 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3506 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3507 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3508 raise Warning.Expected("[Rule.]", self
.FileName
, self
.CurrentLineNumber
)
3510 if not self
._SkipToToken
(TAB_SPLIT
):
3511 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
3513 Arch
= self
._SkippedChars
.rstrip(TAB_SPLIT
)
3514 if Arch
.upper() not in ARCH_SET_FULL
:
3515 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
3517 ModuleType
= self
._GetModuleType
()
3520 if self
._IsToken
(TAB_SPLIT
):
3521 if not self
._GetNextWord
():
3522 raise Warning.Expected("template name", self
.FileName
, self
.CurrentLineNumber
)
3523 TemplateName
= self
._Token
3525 if not self
._IsToken
(TAB_SECTION_END
):
3526 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3528 RuleObj
= self
._GetRuleFileStatements
()
3529 RuleObj
.Arch
= Arch
.upper()
3530 RuleObj
.ModuleType
= ModuleType
3531 RuleObj
.TemplateName
= TemplateName
3532 if TemplateName
== '':
3533 self
.Profile
.RuleDict
['RULE' + \
3537 ModuleType
.upper() ] = RuleObj
3539 self
.Profile
.RuleDict
['RULE' + \
3543 ModuleType
.upper() + \
3545 TemplateName
.upper() ] = RuleObj
3548 ## _GetModuleType() method
3550 # Return the module type
3552 # @param self The object pointer
3553 # @retval string module type
3555 def _GetModuleType(self
):
3556 if not self
._GetNextWord
():
3557 raise Warning.Expected("Module type", self
.FileName
, self
.CurrentLineNumber
)
3558 if self
._Token
.upper() not in {
3559 SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3560 SUP_MODULE_DXE_CORE
, SUP_MODULE_DXE_DRIVER
,
3561 SUP_MODULE_DXE_SAL_DRIVER
, SUP_MODULE_DXE_SMM_DRIVER
,
3562 SUP_MODULE_DXE_RUNTIME_DRIVER
, SUP_MODULE_UEFI_DRIVER
,
3563 SUP_MODULE_UEFI_APPLICATION
, SUP_MODULE_USER_DEFINED
,
3564 TAB_DEFAULT
, SUP_MODULE_BASE
,
3565 EDK_COMPONENT_TYPE_SECURITY_CORE
,
3566 EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER
,
3567 EDK_COMPONENT_TYPE_PIC_PEIM
,
3568 EDK_COMPONENT_TYPE_RELOCATABLE_PEIM
, "PE32_PEIM",
3569 EDK_COMPONENT_TYPE_BS_DRIVER
, EDK_COMPONENT_TYPE_RT_DRIVER
,
3570 EDK_COMPONENT_TYPE_SAL_RT_DRIVER
,
3571 EDK_COMPONENT_TYPE_APPLICATION
, "ACPITABLE",
3572 SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3573 SUP_MODULE_MM_CORE_STANDALONE
}:
3574 raise Warning("Unknown Module type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3577 ## _GetFileExtension() method
3579 # Return the file extension
3581 # @param self The object pointer
3582 # @retval string file name extension
3584 def _GetFileExtension(self
):
3585 if not self
._IsToken
(TAB_SPLIT
):
3586 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
3589 if self
._GetNextToken
():
3590 if FileExtensionPattern
.match(self
._Token
):
3592 return TAB_SPLIT
+ Ext
3594 raise Warning("Unknown file extension '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3597 raise Warning.Expected("file extension", self
.FileName
, self
.CurrentLineNumber
)
3599 ## _GetRuleFileStatement() method
3603 # @param self The object pointer
3604 # @retval Rule Rule object
3606 def _GetRuleFileStatements(self
):
3607 if not self
._IsKeyword
("FILE"):
3608 raise Warning.Expected("FILE", self
.FileName
, self
.CurrentLineNumber
)
3610 if not self
._GetNextWord
():
3611 raise Warning.Expected("FFS type", self
.FileName
, self
.CurrentLineNumber
)
3613 Type
= self
._Token
.strip().upper()
3614 if Type
not in {"RAW", "FREEFORM", SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3615 "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE
, EDK_COMPONENT_TYPE_APPLICATION
,
3616 "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3617 SUP_MODULE_MM_CORE_STANDALONE
}:
3618 raise Warning("Unknown FV type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3620 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3621 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3623 if not self
._IsKeyword
("$(NAMED_GUID)"):
3624 if not self
._GetNextWord
():
3625 raise Warning.Expected("$(NAMED_GUID)", self
.FileName
, self
.CurrentLineNumber
)
3626 if self
._Token
== 'PCD':
3627 if not self
._IsToken
("("):
3628 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3629 PcdPair
= self
._GetNextPcdSettings
()
3630 if not self
._IsToken
(")"):
3631 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3632 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3634 NameGuid
= self
._Token
3637 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3638 if self
._FileCouldHaveRelocFlag
(Type
):
3639 if self
._Token
== 'RELOCS_STRIPPED':
3644 raise Warning("File type %s could not have reloc strip flag%d" % (Type
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3647 if self
._GetNextToken
():
3648 if TokenFindPattern
.match(self
._Token
):
3649 KeyStringList
.append(self
._Token
)
3650 if self
._IsToken
(TAB_COMMA_SPLIT
):
3651 while self
._GetNextToken
():
3652 if not TokenFindPattern
.match(self
._Token
):
3653 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
3654 KeyStringList
.append(self
._Token
)
3656 if not self
._IsToken
(TAB_COMMA_SPLIT
):
3664 if self
._IsKeyword
("Fixed", True):
3668 if self
._IsKeyword
("CheckSum", True):
3672 if self
._GetAlignment
():
3673 if self
._Token
not in ALIGNMENTS
:
3674 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3675 #For FFS, Auto is default option same to ""
3676 if not self
._Token
== "Auto":
3677 AlignValue
= self
._Token
3679 if self
._IsToken
("{"):
3680 # Complex file rule expected
3681 NewRule
= RuleComplexFile()
3682 NewRule
.FvFileType
= Type
3683 NewRule
.NameGuid
= NameGuid
3684 NewRule
.Alignment
= AlignValue
3685 NewRule
.CheckSum
= CheckSum
3686 NewRule
.Fixed
= Fixed
3687 NewRule
.KeyStringList
= KeyStringList
3688 if KeepReloc
is not None:
3689 NewRule
.KeepReloc
= KeepReloc
3692 IsEncapsulate
= self
._GetRuleEncapsulationSection
(NewRule
)
3693 IsLeaf
= self
._GetEfiSection
(NewRule
)
3694 if not IsEncapsulate
and not IsLeaf
:
3697 if not self
._IsToken
(T_CHAR_BRACE_R
):
3698 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3703 # Simple file rule expected
3704 if not self
._GetNextWord
():
3705 raise Warning.Expected("leaf section type", self
.FileName
, self
.CurrentLineNumber
)
3707 SectionName
= self
._Token
3709 if SectionName
not in {
3710 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3711 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3712 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3713 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3714 BINARY_FILE_TYPE_SMM_DEPEX
}:
3715 raise Warning("Unknown leaf section name '%s'" % SectionName
, self
.FileName
, self
.CurrentLineNumber
)
3718 if self
._IsKeyword
("Fixed", True):
3721 if self
._IsKeyword
("CheckSum", True):
3725 if self
._GetAlignment
():
3726 if self
._Token
not in ALIGNMENTS
:
3727 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3728 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3729 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3730 SectAlignment
= self
._Token
3733 if self
._IsToken
(TAB_VALUE_SPLIT
):
3734 Ext
= self
._GetFileExtension
()
3735 elif not self
._GetNextToken
():
3736 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
3738 NewRule
= RuleSimpleFile()
3739 NewRule
.SectionType
= SectionName
3740 NewRule
.FvFileType
= Type
3741 NewRule
.NameGuid
= NameGuid
3742 NewRule
.Alignment
= AlignValue
3743 NewRule
.SectAlignment
= SectAlignment
3744 NewRule
.CheckSum
= CheckSum
3745 NewRule
.Fixed
= Fixed
3746 NewRule
.KeyStringList
= KeyStringList
3747 if KeepReloc
is not None:
3748 NewRule
.KeepReloc
= KeepReloc
3749 NewRule
.FileExtension
= Ext
3750 NewRule
.FileName
= self
._Token
3753 ## _GetEfiSection() method
3755 # Get section list for Rule
3757 # @param self The object pointer
3758 # @param Obj for whom section is got
3759 # @retval True Successfully find section statement
3760 # @retval False Not able to find section statement
3762 def _GetEfiSection(self
, Obj
):
3763 OldPos
= self
.GetFileBufferPos()
3764 if not self
._GetNextWord
():
3766 SectionName
= self
._Token
3768 if SectionName
not in {
3769 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3770 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3771 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3772 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3773 BINARY_FILE_TYPE_SMM_DEPEX
, BINARY_FILE_TYPE_GUID
}:
3777 if SectionName
== "FV_IMAGE":
3778 FvImageSectionObj
= FvImageSection()
3779 if self
._IsKeyword
("FV_IMAGE"):
3781 if self
._IsToken
("{"):
3783 self
._GetDefineStatements
(FvObj
)
3784 self
._GetBlockStatement
(FvObj
)
3785 self
._GetSetStatements
(FvObj
)
3786 self
._GetFvAlignment
(FvObj
)
3787 self
._GetFvAttributes
(FvObj
)
3788 self
._GetAprioriSection
(FvObj
)
3789 self
._GetAprioriSection
(FvObj
)
3792 IsInf
= self
._GetInfStatement
(FvObj
)
3793 IsFile
= self
._GetFileStatement
(FvObj
)
3794 if not IsInf
and not IsFile
:
3797 if not self
._IsToken
(T_CHAR_BRACE_R
):
3798 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3799 FvImageSectionObj
.Fv
= FvObj
3800 FvImageSectionObj
.FvName
= None
3803 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3804 raise Warning.Expected("'FV'", self
.FileName
, self
.CurrentLineNumber
)
3805 FvImageSectionObj
.FvFileType
= self
._Token
3807 if self
._GetAlignment
():
3808 if self
._Token
not in ALIGNMENT_NOAUTO
:
3809 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3810 FvImageSectionObj
.Alignment
= self
._Token
3812 if self
._IsToken
(TAB_VALUE_SPLIT
):
3813 FvImageSectionObj
.FvFileExtension
= self
._GetFileExtension
()
3814 elif self
._GetNextToken
():
3815 if self
._Token
not in {
3816 T_CHAR_BRACE_R
, "COMPAT16", BINARY_FILE_TYPE_PE32
,
3817 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3818 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3819 BINARY_FILE_TYPE_UI
, "VERSION",
3820 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3821 BINARY_FILE_TYPE_SMM_DEPEX
}:
3822 FvImageSectionObj
.FvFileName
= self
._Token
3826 raise Warning.Expected("FV file name", self
.FileName
, self
.CurrentLineNumber
)
3828 Obj
.SectionList
.append(FvImageSectionObj
)
3831 EfiSectionObj
= EfiSection()
3832 EfiSectionObj
.SectionType
= SectionName
3834 if not self
._GetNextToken
():
3835 raise Warning.Expected("file type", self
.FileName
, self
.CurrentLineNumber
)
3837 if self
._Token
== "STRING":
3838 if not self
._RuleSectionCouldHaveString
(EfiSectionObj
.SectionType
):
3839 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3841 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3842 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3844 if not self
._GetNextToken
():
3845 raise Warning.Expected("Quoted String", self
.FileName
, self
.CurrentLineNumber
)
3847 if self
._GetStringData
():
3848 EfiSectionObj
.StringData
= self
._Token
3850 if self
._IsKeyword
("BUILD_NUM"):
3851 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3852 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3854 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3855 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3856 if not self
._GetNextToken
():
3857 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3858 EfiSectionObj
.BuildNum
= self
._Token
3861 EfiSectionObj
.FileType
= self
._Token
3862 self
._CheckRuleSectionFileType
(EfiSectionObj
.SectionType
, EfiSectionObj
.FileType
)
3864 if self
._IsKeyword
("Optional"):
3865 if not self
._RuleSectionCouldBeOptional
(EfiSectionObj
.SectionType
):
3866 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3867 EfiSectionObj
.Optional
= True
3869 if self
._IsKeyword
("BUILD_NUM"):
3870 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3871 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3873 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3874 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3875 if not self
._GetNextToken
():
3876 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3877 EfiSectionObj
.BuildNum
= self
._Token
3879 if self
._GetAlignment
():
3880 if self
._Token
not in ALIGNMENTS
:
3881 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3882 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3883 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3884 EfiSectionObj
.Alignment
= self
._Token
3886 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3887 if self
._SectionCouldHaveRelocFlag
(EfiSectionObj
.SectionType
):
3888 if self
._Token
== 'RELOCS_STRIPPED':
3889 EfiSectionObj
.KeepReloc
= False
3891 EfiSectionObj
.KeepReloc
= True
3892 if Obj
.KeepReloc
is not None and Obj
.KeepReloc
!= EfiSectionObj
.KeepReloc
:
3893 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3895 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3898 if self
._IsToken
(TAB_VALUE_SPLIT
):
3899 EfiSectionObj
.FileExtension
= self
._GetFileExtension
()
3900 elif self
._GetNextToken
():
3901 if self
._Token
not in {
3902 T_CHAR_BRACE_R
, "COMPAT16", BINARY_FILE_TYPE_PE32
,
3903 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3904 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3905 BINARY_FILE_TYPE_UI
, "VERSION",
3906 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3907 BINARY_FILE_TYPE_SMM_DEPEX
}:
3909 if self
._Token
.startswith('PCD'):
3913 if self
._Token
== 'PCD':
3914 if not self
._IsToken
("("):
3915 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3916 PcdPair
= self
._GetNextPcdSettings
()
3917 if not self
._IsToken
(")"):
3918 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3919 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3921 EfiSectionObj
.FileName
= self
._Token
3926 raise Warning.Expected("section file name", self
.FileName
, self
.CurrentLineNumber
)
3928 Obj
.SectionList
.append(EfiSectionObj
)
3931 ## _RuleSectionCouldBeOptional() method
3933 # Get whether a section could be optional
3935 # @param SectionType The section type to check
3936 # @retval True section could be optional
3937 # @retval False section never optional
3940 def _RuleSectionCouldBeOptional(SectionType
):
3941 if SectionType
in {BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "RAW", BINARY_FILE_TYPE_SMM_DEPEX
}:
3946 ## _RuleSectionCouldHaveBuildNum() method
3948 # Get whether a section could have build number information
3950 # @param SectionType The section type to check
3951 # @retval True section could have build number information
3952 # @retval False section never have build number information
3955 def _RuleSectionCouldHaveBuildNum(SectionType
):
3956 if SectionType
== "VERSION":
3961 ## _RuleSectionCouldHaveString() method
3963 # Get whether a section could have string
3965 # @param SectionType The section type to check
3966 # @retval True section could have string
3967 # @retval False section never have string
3970 def _RuleSectionCouldHaveString(SectionType
):
3971 if SectionType
in {BINARY_FILE_TYPE_UI
, "VERSION"}:
3976 ## _CheckRuleSectionFileType() method
3978 # Get whether a section matches a file type
3980 # @param self The object pointer
3981 # @param SectionType The section type to check
3982 # @param FileType The file type to check
3984 def _CheckRuleSectionFileType(self
, SectionType
, FileType
):
3985 WarningString
= "Incorrect section file type '%s'"
3986 if SectionType
== "COMPAT16":
3987 if FileType
not in {"COMPAT16", "SEC_COMPAT16"}:
3988 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3989 elif SectionType
== BINARY_FILE_TYPE_PE32
:
3990 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_PE32"}:
3991 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3992 elif SectionType
== BINARY_FILE_TYPE_PIC
:
3993 if FileType
not in {BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_PIC
}:
3994 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3995 elif SectionType
== BINARY_FILE_TYPE_TE
:
3996 if FileType
not in {BINARY_FILE_TYPE_TE
, "SEC_TE"}:
3997 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
3998 elif SectionType
== "RAW":
3999 if FileType
not in {BINARY_FILE_TYPE_BIN
, "SEC_BIN", "RAW", "ASL", "ACPI"}:
4000 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4001 elif SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
or SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
4002 if FileType
not in {BINARY_FILE_TYPE_DXE_DEPEX
, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX
}:
4003 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4004 elif SectionType
== BINARY_FILE_TYPE_UI
:
4005 if FileType
not in {BINARY_FILE_TYPE_UI
, "SEC_UI"}:
4006 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4007 elif SectionType
== "VERSION":
4008 if FileType
not in {"VERSION", "SEC_VERSION"}:
4009 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4010 elif SectionType
== BINARY_FILE_TYPE_PEI_DEPEX
:
4011 if FileType
not in {BINARY_FILE_TYPE_PEI_DEPEX
, "SEC_PEI_DEPEX"}:
4012 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4013 elif SectionType
== BINARY_FILE_TYPE_GUID
:
4014 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_GUID"}:
4015 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4017 ## _GetRuleEncapsulationSection() method
4019 # Get encapsulation section for Rule
4021 # @param self The object pointer
4022 # @param theRule for whom section is got
4023 # @retval True Successfully find section statement
4024 # @retval False Not able to find section statement
4026 def _GetRuleEncapsulationSection(self
, theRule
):
4027 if self
._IsKeyword
("COMPRESS"):
4029 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
4032 if not self
._IsToken
("{"):
4033 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4035 CompressSectionObj
= CompressSection()
4037 CompressSectionObj
.CompType
= Type
4038 # Recursive sections...
4040 IsEncapsulate
= self
._GetRuleEncapsulationSection
(CompressSectionObj
)
4041 IsLeaf
= self
._GetEfiSection
(CompressSectionObj
)
4042 if not IsEncapsulate
and not IsLeaf
:
4045 if not self
._IsToken
(T_CHAR_BRACE_R
):
4046 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4047 theRule
.SectionList
.append(CompressSectionObj
)
4051 elif self
._IsKeyword
("GUIDED"):
4053 if self
._GetNextGuid
():
4054 GuidValue
= self
._Token
4056 if self
._IsKeyword
("$(NAMED_GUID)"):
4057 GuidValue
= self
._Token
4059 AttribDict
= self
._GetGuidAttrib
()
4061 if not self
._IsToken
("{"):
4062 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4063 GuidSectionObj
= GuidSection()
4064 GuidSectionObj
.NameGuid
= GuidValue
4065 GuidSectionObj
.SectionType
= "GUIDED"
4066 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
4067 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
4068 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
4072 IsEncapsulate
= self
._GetRuleEncapsulationSection
(GuidSectionObj
)
4073 IsLeaf
= self
._GetEfiSection
(GuidSectionObj
)
4074 if not IsEncapsulate
and not IsLeaf
:
4077 if not self
._IsToken
(T_CHAR_BRACE_R
):
4078 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4079 theRule
.SectionList
.append(GuidSectionObj
)
4087 # Get VTF section contents and store its data into VTF list of self.Profile
4089 # @param self The object pointer
4090 # @retval True Successfully find a VTF
4091 # @retval False Not able to find a VTF
4094 HW_ARCH_SET
= {TAB_ARCH_IA32
, TAB_ARCH_X64
, TAB_ARCH_IPF
, TAB_ARCH_ARM
, TAB_ARCH_AARCH64
}
4095 if not self
._GetNextToken
():
4098 S
= self
._Token
.upper()
4099 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[VTF."):
4100 self
.SectionParser(S
)
4105 if not self
._IsToken
("[VTF.", True):
4106 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4107 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
4108 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
4109 raise Warning.Expected("[VTF.]", self
.FileName
, self
.CurrentLineNumber
)
4111 if not self
._SkipToToken
(TAB_SPLIT
):
4112 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
4114 Arch
= self
._SkippedChars
.rstrip(TAB_SPLIT
).upper()
4115 if Arch
not in HW_ARCH_SET
:
4116 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
4118 if not self
._GetNextWord
():
4119 raise Warning.Expected("VTF name", self
.FileName
, self
.CurrentLineNumber
)
4120 Name
= self
._Token
.upper()
4123 VtfObj
.UiName
= Name
4124 VtfObj
.KeyArch
= Arch
4126 if self
._IsToken
(TAB_COMMA_SPLIT
):
4127 if not self
._GetNextWord
():
4128 raise Warning.Expected("Arch list", self
.FileName
, self
.CurrentLineNumber
)
4129 if self
._Token
.upper() not in HW_ARCH_SET
:
4130 raise Warning("Unknown Arch '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4131 VtfObj
.ArchList
= self
._Token
.upper()
4133 if not self
._IsToken
(TAB_SECTION_END
):
4134 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
4136 if self
._IsKeyword
("IA32_RST_BIN"):
4137 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4138 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4140 if not self
._GetNextToken
():
4141 raise Warning.Expected("Reset file", self
.FileName
, self
.CurrentLineNumber
)
4143 VtfObj
.ResetBin
= self
._Token
4144 if VtfObj
.ResetBin
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4145 #check for file path
4146 ErrorCode
, ErrorInfo
= PathClass(NormPath(VtfObj
.ResetBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4148 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4150 while self
._GetComponentStatement
(VtfObj
):
4153 self
.Profile
.VtfList
.append(VtfObj
)
4156 ## _GetComponentStatement() method
4158 # Get components in VTF
4160 # @param self The object pointer
4161 # @param VtfObj for whom component is got
4162 # @retval True Successfully find a component
4163 # @retval False Not able to find a component
4165 def _GetComponentStatement(self
, VtfObj
):
4166 if not self
._IsKeyword
("COMP_NAME"):
4169 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4170 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4172 if not self
._GetNextWord
():
4173 raise Warning.Expected("Component Name", self
.FileName
, self
.CurrentLineNumber
)
4175 CompStatementObj
= ComponentStatement()
4176 CompStatementObj
.CompName
= self
._Token
4178 if not self
._IsKeyword
("COMP_LOC"):
4179 raise Warning.Expected("COMP_LOC", self
.FileName
, self
.CurrentLineNumber
)
4181 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4182 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4184 CompStatementObj
.CompLoc
= ""
4185 if self
._GetNextWord
():
4186 CompStatementObj
.CompLoc
= self
._Token
4187 if self
._IsToken
(TAB_VALUE_SPLIT
):
4188 if not self
._GetNextWord
():
4189 raise Warning.Expected("Region Name", self
.FileName
, self
.CurrentLineNumber
)
4191 if self
._Token
not in {"F", "N", "S"}: #, "H", "L", "PH", "PL"): not support
4192 raise Warning("Unknown location type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4194 CompStatementObj
.FilePos
= self
._Token
4196 self
.CurrentLineNumber
+= 1
4197 self
.CurrentOffsetWithinLine
= 0
4199 if not self
._IsKeyword
("COMP_TYPE"):
4200 raise Warning.Expected("COMP_TYPE", self
.FileName
, self
.CurrentLineNumber
)
4202 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4203 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4205 if not self
._GetNextToken
():
4206 raise Warning.Expected("Component type", self
.FileName
, self
.CurrentLineNumber
)
4207 if self
._Token
not in {"FIT", "PAL_B", "PAL_A", "OEM"}:
4208 if not self
._Token
.startswith("0x") or len(self
._Token
) < 3 or len(self
._Token
) > 4 or \
4209 not self
._Token
[2] in hexdigits
or not self
._Token
[-1] in hexdigits
:
4210 raise Warning("Unknown location type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4211 CompStatementObj
.CompType
= self
._Token
4213 if not self
._IsKeyword
("COMP_VER"):
4214 raise Warning.Expected("COMP_VER", self
.FileName
, self
.CurrentLineNumber
)
4216 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4217 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4219 if not self
._GetNextToken
():
4220 raise Warning.Expected("Component version", self
.FileName
, self
.CurrentLineNumber
)
4222 Pattern
= compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', DOTALL
)
4223 if Pattern
.match(self
._Token
) is None:
4224 raise Warning("Unknown version format '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4225 CompStatementObj
.CompVer
= self
._Token
4227 if not self
._IsKeyword
("COMP_CS"):
4228 raise Warning.Expected("COMP_CS", self
.FileName
, self
.CurrentLineNumber
)
4230 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4231 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4233 if not self
._GetNextToken
():
4234 raise Warning.Expected("Component CS", self
.FileName
, self
.CurrentLineNumber
)
4235 if self
._Token
not in {"1", "0"}:
4236 raise Warning("Unknown Component CS '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4237 CompStatementObj
.CompCs
= self
._Token
4240 if not self
._IsKeyword
("COMP_BIN"):
4241 raise Warning.Expected("COMP_BIN", self
.FileName
, self
.CurrentLineNumber
)
4243 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4244 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4246 if not self
._GetNextToken
():
4247 raise Warning.Expected("Component file", self
.FileName
, self
.CurrentLineNumber
)
4249 CompStatementObj
.CompBin
= self
._Token
4250 if CompStatementObj
.CompBin
!= '-' and CompStatementObj
.CompBin
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4251 #check for file path
4252 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4254 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4256 if not self
._IsKeyword
("COMP_SYM"):
4257 raise Warning.Expected("COMP_SYM", self
.FileName
, self
.CurrentLineNumber
)
4259 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4260 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4262 if not self
._GetNextToken
():
4263 raise Warning.Expected("Component symbol file", self
.FileName
, self
.CurrentLineNumber
)
4265 CompStatementObj
.CompSym
= self
._Token
4266 if CompStatementObj
.CompSym
!= '-' and CompStatementObj
.CompSym
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4267 #check for file path
4268 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompSym
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4270 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4272 if not self
._IsKeyword
("COMP_SIZE"):
4273 raise Warning.Expected("COMP_SIZE", self
.FileName
, self
.CurrentLineNumber
)
4275 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4276 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4278 if self
._IsToken
("-"):
4279 CompStatementObj
.CompSize
= self
._Token
4280 elif self
._GetNextDecimalNumber
():
4281 CompStatementObj
.CompSize
= self
._Token
4282 elif self
._GetNextHexNumber
():
4283 CompStatementObj
.CompSize
= self
._Token
4285 raise Warning("Unknown size '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4287 VtfObj
.ComponentStatementList
.append(CompStatementObj
)
4290 ## _GetOptionRom() method
4292 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
4294 # @param self The object pointer
4295 # @retval True Successfully find a OptionROM
4296 # @retval False Not able to find a OptionROM
4298 def _GetOptionRom(self
):
4299 if not self
._GetNextToken
():
4302 S
= self
._Token
.upper()
4303 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[OPTIONROM."):
4304 self
.SectionParser(S
)
4309 if not self
._IsToken
("[OptionRom.", True):
4310 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4312 OptRomName
= self
._GetUiName
()
4314 if not self
._IsToken
(TAB_SECTION_END
):
4315 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
4317 OptRomObj
= OPTIONROM(OptRomName
)
4318 self
.Profile
.OptRomDict
[OptRomName
] = OptRomObj
4321 isInf
= self
._GetOptRomInfStatement
(OptRomObj
)
4322 isFile
= self
._GetOptRomFileStatement
(OptRomObj
)
4323 if not isInf
and not isFile
:
4328 ## _GetOptRomInfStatement() method
4330 # Get INF statements
4332 # @param self The object pointer
4333 # @param Obj for whom inf statement is got
4334 # @retval True Successfully find inf statement
4335 # @retval False Not able to find inf statement
4337 def _GetOptRomInfStatement(self
, Obj
):
4338 if not self
._IsKeyword
("INF"):
4341 ffsInf
= OptRomInfStatement()
4342 self
._GetInfOptions
(ffsInf
)
4344 if not self
._GetNextToken
():
4345 raise Warning.Expected("INF file path", self
.FileName
, self
.CurrentLineNumber
)
4346 ffsInf
.InfFileName
= self
._Token
4347 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4348 #check for file path
4349 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4351 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4353 NewFileName
= ffsInf
.InfFileName
4354 if ffsInf
.OverrideGuid
:
4355 NewFileName
= ProcessDuplicatedInf(PathClass(ffsInf
.InfFileName
,GenFdsGlobalVariable
.WorkSpaceDir
), ffsInf
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
).Path
4357 if not NewFileName
in self
.Profile
.InfList
:
4358 self
.Profile
.InfList
.append(NewFileName
)
4359 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4360 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
4362 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
4363 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
4365 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
4367 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
4370 self
._GetOptRomOverrides
(ffsInf
)
4372 Obj
.FfsList
.append(ffsInf
)
4375 ## _GetOptRomOverrides() method
4377 # Get overrides for OptROM INF & FILE
4379 # @param self The object pointer
4380 # @param FfsInfObj for whom overrides is got
4382 def _GetOptRomOverrides(self
, Obj
):
4383 if self
._IsToken
('{'):
4384 Overrides
= OverrideAttribs()
4386 if self
._IsKeyword
("PCI_VENDOR_ID"):
4387 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4388 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4389 if not self
._GetNextHexNumber
():
4390 raise Warning.Expected("Hex vendor id", self
.FileName
, self
.CurrentLineNumber
)
4391 Overrides
.PciVendorId
= self
._Token
4394 if self
._IsKeyword
("PCI_CLASS_CODE"):
4395 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4396 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4397 if not self
._GetNextHexNumber
():
4398 raise Warning.Expected("Hex class code", self
.FileName
, self
.CurrentLineNumber
)
4399 Overrides
.PciClassCode
= self
._Token
4402 if self
._IsKeyword
("PCI_DEVICE_ID"):
4403 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4404 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4405 # Get a list of PCI IDs
4406 Overrides
.PciDeviceId
= ""
4407 while (self
._GetNextHexNumber
()):
4408 Overrides
.PciDeviceId
= "{} {}".format(Overrides
.PciDeviceId
, self
._Token
)
4409 if not Overrides
.PciDeviceId
:
4410 raise Warning.Expected("one or more Hex device ids", self
.FileName
, self
.CurrentLineNumber
)
4413 if self
._IsKeyword
("PCI_REVISION"):
4414 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4415 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4416 if not self
._GetNextHexNumber
():
4417 raise Warning.Expected("Hex revision", self
.FileName
, self
.CurrentLineNumber
)
4418 Overrides
.PciRevision
= self
._Token
4421 if self
._IsKeyword
("PCI_COMPRESS"):
4422 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4423 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4424 if not self
._GetNextToken
():
4425 raise Warning.Expected("TRUE/FALSE for compress", self
.FileName
, self
.CurrentLineNumber
)
4426 Overrides
.NeedCompress
= self
._Token
.upper() == 'TRUE'
4429 if self
._IsToken
(T_CHAR_BRACE_R
):
4432 EdkLogger
.error("FdfParser", FORMAT_INVALID
, File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
4434 Obj
.OverrideAttribs
= Overrides
4436 ## _GetOptRomFileStatement() method
4438 # Get FILE statements
4440 # @param self The object pointer
4441 # @param Obj for whom FILE statement is got
4442 # @retval True Successfully find FILE statement
4443 # @retval False Not able to find FILE statement
4445 def _GetOptRomFileStatement(self
, Obj
):
4446 if not self
._IsKeyword
("FILE"):
4449 FfsFileObj
= OptRomFileStatement()
4451 if not self
._IsKeyword
("EFI") and not self
._IsKeyword
(BINARY_FILE_TYPE_BIN
):
4452 raise Warning.Expected("Binary type (EFI/BIN)", self
.FileName
, self
.CurrentLineNumber
)
4453 FfsFileObj
.FileType
= self
._Token
4455 if not self
._GetNextToken
():
4456 raise Warning.Expected("File path", self
.FileName
, self
.CurrentLineNumber
)
4457 FfsFileObj
.FileName
= self
._Token
4458 if FfsFileObj
.FileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4459 #check for file path
4460 ErrorCode
, ErrorInfo
= PathClass(NormPath(FfsFileObj
.FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4462 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4464 if FfsFileObj
.FileType
== 'EFI':
4465 self
._GetOptRomOverrides
(FfsFileObj
)
4467 Obj
.FfsList
.append(FfsFileObj
)
4471 ## _GetCapInFd() method
4473 # Get Cap list contained in FD
4475 # @param self The object pointer
4476 # @param FdName FD name
4477 # @retval CapList List of Capsule in FD
4479 def _GetCapInFd (self
, FdName
):
4481 if FdName
.upper() in self
.Profile
.FdDict
:
4482 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4483 for elementRegion
in FdObj
.RegionList
:
4484 if elementRegion
.RegionType
== 'CAPSULE':
4485 for elementRegionData
in elementRegion
.RegionDataList
:
4486 if elementRegionData
.endswith(".cap"):
4488 if elementRegionData
is not None and elementRegionData
.upper() not in CapList
:
4489 CapList
.append(elementRegionData
.upper())
4492 ## _GetReferencedFdCapTuple() method
4494 # Get FV and FD list referenced by a capsule image
4496 # @param self The object pointer
4497 # @param CapObj Capsule section to be searched
4498 # @param RefFdList referenced FD by section
4499 # @param RefFvList referenced FV by section
4501 def _GetReferencedFdCapTuple(self
, CapObj
, RefFdList
= [], RefFvList
= []):
4502 for CapsuleDataObj
in CapObj
.CapsuleDataList
:
4503 if hasattr(CapsuleDataObj
, 'FvName') and CapsuleDataObj
.FvName
is not None and CapsuleDataObj
.FvName
.upper() not in RefFvList
:
4504 RefFvList
.append (CapsuleDataObj
.FvName
.upper())
4505 elif hasattr(CapsuleDataObj
, 'FdName') and CapsuleDataObj
.FdName
is not None and CapsuleDataObj
.FdName
.upper() not in RefFdList
:
4506 RefFdList
.append (CapsuleDataObj
.FdName
.upper())
4507 elif CapsuleDataObj
.Ffs
is not None:
4508 if isinstance(CapsuleDataObj
.Ffs
, FileStatement
):
4509 if CapsuleDataObj
.Ffs
.FvName
is not None and CapsuleDataObj
.Ffs
.FvName
.upper() not in RefFvList
:
4510 RefFvList
.append(CapsuleDataObj
.Ffs
.FvName
.upper())
4511 elif CapsuleDataObj
.Ffs
.FdName
is not None and CapsuleDataObj
.Ffs
.FdName
.upper() not in RefFdList
:
4512 RefFdList
.append(CapsuleDataObj
.Ffs
.FdName
.upper())
4514 self
._GetReferencedFdFvTupleFromSection
(CapsuleDataObj
.Ffs
, RefFdList
, RefFvList
)
4516 ## _GetFvInFd() method
4518 # Get FV list contained in FD
4520 # @param self The object pointer
4521 # @param FdName FD name
4522 # @retval FvList list of FV in FD
4524 def _GetFvInFd (self
, FdName
):
4526 if FdName
.upper() in self
.Profile
.FdDict
:
4527 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4528 for elementRegion
in FdObj
.RegionList
:
4529 if elementRegion
.RegionType
== BINARY_FILE_TYPE_FV
:
4530 for elementRegionData
in elementRegion
.RegionDataList
:
4531 if elementRegionData
.endswith(".fv"):
4533 if elementRegionData
is not None and elementRegionData
.upper() not in FvList
:
4534 FvList
.append(elementRegionData
.upper())
4537 ## _GetReferencedFdFvTuple() method
4539 # Get FD and FV list referenced by a FFS file
4541 # @param self The object pointer
4542 # @param FfsFile contains sections to be searched
4543 # @param RefFdList referenced FD by section
4544 # @param RefFvList referenced FV by section
4546 def _GetReferencedFdFvTuple(self
, FvObj
, RefFdList
= [], RefFvList
= []):
4547 for FfsObj
in FvObj
.FfsList
:
4548 if isinstance(FfsObj
, FileStatement
):
4549 if FfsObj
.FvName
is not None and FfsObj
.FvName
.upper() not in RefFvList
:
4550 RefFvList
.append(FfsObj
.FvName
.upper())
4551 elif FfsObj
.FdName
is not None and FfsObj
.FdName
.upper() not in RefFdList
:
4552 RefFdList
.append(FfsObj
.FdName
.upper())
4554 self
._GetReferencedFdFvTupleFromSection
(FfsObj
, RefFdList
, RefFvList
)
4556 ## _GetReferencedFdFvTupleFromSection() method
4558 # Get FD and FV list referenced by a FFS section
4560 # @param self The object pointer
4561 # @param FfsFile contains sections to be searched
4562 # @param FdList referenced FD by section
4563 # @param FvList referenced FV by section
4565 def _GetReferencedFdFvTupleFromSection(self
, FfsFile
, FdList
= [], FvList
= []):
4566 SectionStack
= list(FfsFile
.SectionList
)
4567 while SectionStack
!= []:
4568 SectionObj
= SectionStack
.pop()
4569 if isinstance(SectionObj
, FvImageSection
):
4570 if SectionObj
.FvName
is not None and SectionObj
.FvName
.upper() not in FvList
:
4571 FvList
.append(SectionObj
.FvName
.upper())
4572 if SectionObj
.Fv
is not None and SectionObj
.Fv
.UiFvName
is not None and SectionObj
.Fv
.UiFvName
.upper() not in FvList
:
4573 FvList
.append(SectionObj
.Fv
.UiFvName
.upper())
4574 self
._GetReferencedFdFvTuple
(SectionObj
.Fv
, FdList
, FvList
)
4576 if isinstance(SectionObj
, CompressSection
) or isinstance(SectionObj
, GuidSection
):
4577 SectionStack
.extend(SectionObj
.SectionList
)
4579 ## CycleReferenceCheck() method
4581 # Check whether cycle reference exists in FDF
4583 # @param self The object pointer
4584 # @retval True cycle reference exists
4585 # @retval False Not exists cycle reference
4587 def CycleReferenceCheck(self
):
4589 # Check the cycle between FV and FD image
4591 MaxLength
= len (self
.Profile
.FvDict
)
4592 for FvName
in self
.Profile
.FvDict
:
4593 LogStr
= "\nCycle Reference Checking for FV: %s\n" % FvName
4594 RefFvStack
= set(FvName
)
4595 FdAnalyzedList
= set()
4598 while RefFvStack
and Index
< MaxLength
:
4600 FvNameFromStack
= RefFvStack
.pop()
4601 if FvNameFromStack
.upper() in self
.Profile
.FvDict
:
4602 FvObj
= self
.Profile
.FvDict
[FvNameFromStack
.upper()]
4608 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4610 for RefFdName
in RefFdList
:
4611 if RefFdName
in FdAnalyzedList
:
4614 LogStr
+= "FV %s contains FD %s\n" % (FvNameFromStack
, RefFdName
)
4615 FvInFdList
= self
._GetFvInFd
(RefFdName
)
4616 if FvInFdList
!= []:
4617 for FvNameInFd
in FvInFdList
:
4618 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4619 if FvNameInFd
not in RefFvStack
:
4620 RefFvStack
.add(FvNameInFd
)
4622 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4623 EdkLogger
.info(LogStr
)
4625 FdAnalyzedList
.add(RefFdName
)
4627 for RefFvName
in RefFvList
:
4628 LogStr
+= "FV %s contains FV %s\n" % (FvNameFromStack
, RefFvName
)
4629 if RefFvName
not in RefFvStack
:
4630 RefFvStack
.add(RefFvName
)
4632 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4633 EdkLogger
.info(LogStr
)
4637 # Check the cycle between Capsule and FD image
4639 MaxLength
= len (self
.Profile
.CapsuleDict
)
4640 for CapName
in self
.Profile
.CapsuleDict
:
4642 # Capsule image to be checked.
4644 LogStr
= "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4645 RefCapStack
= {CapName}
4646 FdAnalyzedList
= set()
4647 FvAnalyzedList
= set()
4650 while RefCapStack
and Index
< MaxLength
:
4652 CapNameFromStack
= RefCapStack
.pop()
4653 if CapNameFromStack
.upper() in self
.Profile
.CapsuleDict
:
4654 CapObj
= self
.Profile
.CapsuleDict
[CapNameFromStack
.upper()]
4660 self
._GetReferencedFdCapTuple
(CapObj
, RefFdList
, RefFvList
)
4664 while FvListLength
< len (RefFvList
) or FdListLength
< len (RefFdList
):
4665 for RefFdName
in RefFdList
:
4666 if RefFdName
in FdAnalyzedList
:
4669 LogStr
+= "Capsule %s contains FD %s\n" % (CapNameFromStack
, RefFdName
)
4670 for CapNameInFd
in self
._GetCapInFd
(RefFdName
):
4671 LogStr
+= "FD %s contains Capsule %s\n" % (RefFdName
, CapNameInFd
)
4672 if CapNameInFd
not in RefCapStack
:
4673 RefCapStack
.append(CapNameInFd
)
4675 if CapName
in RefCapStack
or CapNameFromStack
in RefCapStack
:
4676 EdkLogger
.info(LogStr
)
4679 for FvNameInFd
in self
._GetFvInFd
(RefFdName
):
4680 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4681 if FvNameInFd
not in RefFvList
:
4682 RefFvList
.append(FvNameInFd
)
4684 FdAnalyzedList
.add(RefFdName
)
4686 # the number of the parsed FV and FD image
4688 FvListLength
= len (RefFvList
)
4689 FdListLength
= len (RefFdList
)
4690 for RefFvName
in RefFvList
:
4691 if RefFvName
in FvAnalyzedList
:
4693 LogStr
+= "Capsule %s contains FV %s\n" % (CapNameFromStack
, RefFvName
)
4694 if RefFvName
.upper() in self
.Profile
.FvDict
:
4695 FvObj
= self
.Profile
.FvDict
[RefFvName
.upper()]
4698 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4699 FvAnalyzedList
.add(RefFvName
)
4703 def GetAllIncludedFile (self
):
4704 global AllIncludeFileList
4705 return AllIncludeFileList
4707 if __name__
== "__main__":
4710 test_file
= sys
.argv
[1]
4711 except IndexError as v
:
4712 print("Usage: %s filename" % sys
.argv
[0])
4715 parser
= FdfParser(test_file
)
4718 parser
.CycleReferenceCheck()
4719 except Warning as X
: