4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 # Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
7 # This program and the accompanying materials
8 # are licensed and made available under the terms and conditions of the BSD License
9 # which accompanies this distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 from __future__
import print_function
20 from __future__
import absolute_import
21 from re
import compile, DOTALL
22 from string
import hexdigits
25 from Common
.BuildToolError
import *
26 from Common
import EdkLogger
27 from Common
.Misc
import PathClass
, tdict
28 from Common
.StringUtils
import NormPath
, ReplaceMacro
29 from Common
import GlobalData
30 from Common
.Expression
import *
31 from Common
.DataType
import *
32 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
33 import Common
.LongFilePathOs
as os
34 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
35 from Common
.RangeExpression
import RangeExpression
36 from collections
import OrderedDict
39 from .Region
import Region
41 from .AprioriSection
import AprioriSection
42 from .FfsInfStatement
import FfsInfStatement
43 from .FfsFileStatement
import FileStatement
44 from .VerSection
import VerSection
45 from .UiSection
import UiSection
46 from .FvImageSection
import FvImageSection
47 from .DataSection
import DataSection
48 from .DepexSection
import DepexSection
49 from .CompressSection
import CompressSection
50 from .GuidSection
import GuidSection
51 from .Capsule
import EFI_CERT_TYPE_PKCS7_GUID
, EFI_CERT_TYPE_RSA2048_SHA256_GUID
, Capsule
52 from .CapsuleData
import CapsuleFfs
, CapsulePayload
, CapsuleFv
, CapsuleFd
, CapsuleAnyFile
, CapsuleAfile
53 from .RuleComplexFile
import RuleComplexFile
54 from .RuleSimpleFile
import RuleSimpleFile
55 from .EfiSection
import EfiSection
57 from .ComponentStatement
import ComponentStatement
58 from .OptionRom
import OPTIONROM
59 from .OptRomInfStatement
import OptRomInfStatement
, OverrideAttribs
60 from .OptRomFileStatement
import OptRomFileStatement
61 from .GenFdsGlobalVariable
import GenFdsGlobalVariable
65 T_CHAR_DOUBLE_QUOTE
= '\"'
66 T_CHAR_SINGLE_QUOTE
= '\''
69 SEPARATORS
= {TAB_EQUAL_SPLIT
, TAB_VALUE_SPLIT
, TAB_COMMA_SPLIT
, '{', '}'}
70 ALIGNMENTS
= {"Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K", "64K", "128K",
71 "256K", "512K", "1M", "2M", "4M", "8M", "16M"}
72 ALIGNMENT_NOAUTO
= ALIGNMENTS
- {"Auto"}
74 RegionSizePattern
= compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
75 RegionSizeGuidPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*")
76 RegionOffsetPcdPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$")
77 ShortcutPcdPattern
= compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
78 BaseAddrValuePattern
= compile('^0[xX][0-9a-fA-F]+')
79 FileExtensionPattern
= compile(r
'([a-zA-Z][a-zA-Z0-9]*)')
80 TokenFindPattern
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
81 AllIncludeFileList
= []
83 # Get the closest parent
84 def GetParentAtLine (Line
):
85 for Profile
in AllIncludeFileList
:
86 if Profile
.IsLineInFile(Line
):
91 def IsValidInclude (File
, Line
):
92 for Profile
in AllIncludeFileList
:
93 if Profile
.IsLineInFile(Line
) and Profile
.FileName
== File
:
98 def GetRealFileLine (File
, Line
):
100 for Profile
in AllIncludeFileList
:
101 if Profile
.IsLineInFile(Line
):
102 return Profile
.GetLineInFile(Line
)
103 elif Line
>= Profile
.InsertStartLineNumber
and Profile
.Level
== 1:
104 InsertedLines
+= Profile
.GetTotalLines()
106 return (File
, Line
- InsertedLines
)
108 ## The exception class that used to report error messages when parsing FDF
110 # Currently the "ToolName" is set to be "FdfParser".
112 class Warning (Exception):
115 # @param self The object pointer
116 # @param Str The message to record
117 # @param File The FDF name
118 # @param Line The Line number that error occurs
120 def __init__(self
, Str
, File
= None, Line
= None):
121 FileLineTuple
= GetRealFileLine(File
, Line
)
122 self
.FileName
= FileLineTuple
[0]
123 self
.LineNumber
= FileLineTuple
[1]
124 self
.OriginalLineNumber
= Line
126 self
.ToolName
= 'FdfParser'
131 ## The Include file content class that used to record file data when parsing include file
133 # May raise Exception when opening file.
135 class IncludeFileProfile
:
138 # @param self The object pointer
139 # @param FileName The file that to be parsed
141 def __init__(self
, FileName
):
142 self
.FileName
= FileName
143 self
.FileLinesList
= []
145 with
open(FileName
, "rb", 0) as fsock
:
146 self
.FileLinesList
= fsock
.readlines()
147 for index
, line
in enumerate(self
.FileLinesList
):
148 if not line
.endswith(TAB_LINE_BREAK
):
149 self
.FileLinesList
[index
] += TAB_LINE_BREAK
151 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
153 self
.InsertStartLineNumber
= None
154 self
.InsertAdjust
= 0
155 self
.IncludeFileList
= []
156 self
.Level
= 1 # first level include file
158 def GetTotalLines(self
):
159 TotalLines
= self
.InsertAdjust
+ len(self
.FileLinesList
)
161 for Profile
in self
.IncludeFileList
:
162 TotalLines
+= Profile
.GetTotalLines()
166 def IsLineInFile(self
, Line
):
167 if Line
>= self
.InsertStartLineNumber
and Line
< self
.InsertStartLineNumber
+ self
.GetTotalLines():
172 def GetLineInFile(self
, Line
):
173 if not self
.IsLineInFile (Line
):
174 return (self
.FileName
, -1)
176 InsertedLines
= self
.InsertStartLineNumber
178 for Profile
in self
.IncludeFileList
:
179 if Profile
.IsLineInFile(Line
):
180 return Profile
.GetLineInFile(Line
)
181 elif Line
>= Profile
.InsertStartLineNumber
:
182 InsertedLines
+= Profile
.GetTotalLines()
184 return (self
.FileName
, Line
- InsertedLines
+ 1)
188 ## The FDF content class that used to record file data when parsing FDF
190 # May raise Exception when opening file.
195 # @param self The object pointer
196 # @param FileName The file that to be parsed
198 def __init__(self
, FileName
):
199 self
.FileLinesList
= []
201 with
open(FileName
, "rb", 0) as fsock
:
202 self
.FileLinesList
= fsock
.readlines()
205 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
207 self
.FileName
= FileName
208 self
.PcdDict
= OrderedDict()
209 self
.PcdLocalDict
= OrderedDict()
211 self
.InfDict
= {'ArchTBD':[]}
212 # ECC will use this Dict and List information
213 self
.PcdFileLineDict
= {}
214 self
.InfFileLineList
= []
217 self
.FdNameNotSet
= False
219 self
.CapsuleDict
= {}
223 self
.FmpPayloadDict
= {}
225 ## The syntax parser for FDF
227 # PreprocessFile method should be called prior to ParseFile
228 # CycleReferenceCheck method can detect cycles in FDF contents
230 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
231 # Get*** procedures mean these procedures will make judgement on current token only.
236 # @param self The object pointer
237 # @param FileName The file that to be parsed
239 def __init__(self
, FileName
):
240 self
.Profile
= FileProfile(FileName
)
241 self
.FileName
= FileName
242 self
.CurrentLineNumber
= 1
243 self
.CurrentOffsetWithinLine
= 0
244 self
.CurrentFdName
= None
245 self
.CurrentFvName
= None
247 self
._SkippedChars
= ""
248 GlobalData
.gFdfParser
= self
250 # Used to section info
251 self
._CurSection
= []
252 # Key: [section name, UI name, arch]
253 # Value: {MACRO_NAME: MACRO_VALUE}
254 self
._MacroDict
= tdict(True, 3)
255 self
._PcdDict
= OrderedDict()
257 self
._WipeOffArea
= []
258 if GenFdsGlobalVariable
.WorkSpaceDir
== '':
259 GenFdsGlobalVariable
.WorkSpaceDir
= os
.getenv("WORKSPACE")
261 ## _SkipWhiteSpace() method
263 # Skip white spaces from current char.
265 # @param self The object pointer
267 def _SkipWhiteSpace(self
):
268 while not self
._EndOfFile
():
269 if self
._CurrentChar
() in (TAB_PRINTCHAR_NUL
, T_CHAR_CR
, TAB_LINE_BREAK
, TAB_SPACE_SPLIT
, T_CHAR_TAB
):
270 self
._SkippedChars
+= str(self
._CurrentChar
())
276 ## _EndOfFile() method
278 # Judge current buffer pos is at file end
280 # @param self The object pointer
281 # @retval True Current File buffer position is at file end
282 # @retval False Current File buffer position is NOT at file end
284 def _EndOfFile(self
):
285 NumberOfLines
= len(self
.Profile
.FileLinesList
)
286 SizeOfLastLine
= len(self
.Profile
.FileLinesList
[-1])
287 if self
.CurrentLineNumber
== NumberOfLines
and self
.CurrentOffsetWithinLine
>= SizeOfLastLine
- 1:
289 if self
.CurrentLineNumber
> NumberOfLines
:
293 ## _EndOfLine() method
295 # Judge current buffer pos is at line end
297 # @param self The object pointer
298 # @retval True Current File buffer position is at line end
299 # @retval False Current File buffer position is NOT at line end
301 def _EndOfLine(self
):
302 if self
.CurrentLineNumber
> len(self
.Profile
.FileLinesList
):
304 SizeOfCurrentLine
= len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
305 if self
.CurrentOffsetWithinLine
>= SizeOfCurrentLine
:
311 # Reset file data buffer to the initial state
313 # @param self The object pointer
314 # @param DestLine Optional new destination line number.
315 # @param DestOffset Optional new destination offset.
317 def Rewind(self
, DestLine
= 1, DestOffset
= 0):
318 self
.CurrentLineNumber
= DestLine
319 self
.CurrentOffsetWithinLine
= DestOffset
321 ## _UndoOneChar() method
323 # Go back one char in the file buffer
325 # @param self The object pointer
326 # @retval True Successfully go back one char
327 # @retval False Not able to go back one char as file beginning reached
329 def _UndoOneChar(self
):
330 if self
.CurrentLineNumber
== 1 and self
.CurrentOffsetWithinLine
== 0:
332 elif self
.CurrentOffsetWithinLine
== 0:
333 self
.CurrentLineNumber
-= 1
334 self
.CurrentOffsetWithinLine
= len(self
._CurrentLine
()) - 1
336 self
.CurrentOffsetWithinLine
-= 1
339 ## _GetOneChar() method
341 # Move forward one char in the file buffer
343 # @param self The object pointer
345 def _GetOneChar(self
):
346 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
347 self
.CurrentLineNumber
+= 1
348 self
.CurrentOffsetWithinLine
= 0
350 self
.CurrentOffsetWithinLine
+= 1
352 ## _CurrentChar() method
354 # Get the char pointed to by the file buffer pointer
356 # @param self The object pointer
357 # @retval Char Current char
359 def _CurrentChar(self
):
360 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
]
362 ## _NextChar() method
364 # Get the one char pass the char pointed to by the file buffer pointer
366 # @param self The object pointer
367 # @retval Char Next char
370 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
371 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
][0]
372 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
+ 1]
374 ## _SetCurrentCharValue() method
376 # Modify the value of current char
378 # @param self The object pointer
379 # @param Value The new value of current char
381 def _SetCurrentCharValue(self
, Value
):
382 self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
] = Value
384 ## _CurrentLine() method
386 # Get the list that contains current line contents
388 # @param self The object pointer
389 # @retval List current line contents
391 def _CurrentLine(self
):
392 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
394 def _StringToList(self
):
395 self
.Profile
.FileLinesList
= [list(s
) for s
in self
.Profile
.FileLinesList
]
396 if not self
.Profile
.FileLinesList
:
397 EdkLogger
.error('FdfParser', FILE_READ_FAILURE
, 'The file is empty!', File
=self
.FileName
)
398 self
.Profile
.FileLinesList
[-1].append(' ')
400 def _ReplaceFragment(self
, StartPos
, EndPos
, Value
= ' '):
401 if StartPos
[0] == EndPos
[0]:
403 while Offset
<= EndPos
[1]:
404 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
409 while self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] not in (T_CHAR_CR
, TAB_LINE_BREAK
):
410 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
414 while Line
< EndPos
[0]:
416 while self
.Profile
.FileLinesList
[Line
][Offset
] not in (T_CHAR_CR
, TAB_LINE_BREAK
):
417 self
.Profile
.FileLinesList
[Line
][Offset
] = Value
422 while Offset
<= EndPos
[1]:
423 self
.Profile
.FileLinesList
[EndPos
[0]][Offset
] = Value
426 def _SetMacroValue(self
, Macro
, Value
):
427 if not self
._CurSection
:
431 if not self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]:
432 self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]] = MacroDict
434 MacroDict
= self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]
435 MacroDict
[Macro
] = Value
437 def _GetMacroValue(self
, Macro
):
439 if Macro
in GlobalData
.gCommandLineDefines
:
440 return GlobalData
.gCommandLineDefines
[Macro
]
441 if Macro
in GlobalData
.gGlobalDefines
:
442 return GlobalData
.gGlobalDefines
[Macro
]
445 MacroDict
= self
._MacroDict
[
450 if MacroDict
and Macro
in MacroDict
:
451 return MacroDict
[Macro
]
454 if Macro
in GlobalData
.gPlatformDefines
:
455 return GlobalData
.gPlatformDefines
[Macro
]
458 def _SectionHeaderParser(self
, Section
):
460 # [FD.UiName]: use dummy instead if UI name is optional
463 # [Rule]: don't take rule section into account, macro is not allowed in this section
464 # [VTF.arch.UiName, arch]
465 # [OptionRom.DriverName]
466 self
._CurSection
= []
467 Section
= Section
.strip()[1:-1].upper().replace(' ', '').strip(TAB_SPLIT
)
468 ItemList
= Section
.split(TAB_SPLIT
)
470 if Item
== '' or Item
== 'RULE':
473 if Item
== TAB_COMMON_DEFINES
.upper():
474 self
._CurSection
= [TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
475 elif Item
== 'VTF' and len(ItemList
) == 3:
477 Pos
= UiName
.find(TAB_COMMA_SPLIT
)
479 UiName
= UiName
[:Pos
]
480 self
._CurSection
= ['VTF', UiName
, ItemList
[1]]
481 elif len(ItemList
) > 1:
482 self
._CurSection
= [ItemList
[0], ItemList
[1], TAB_COMMON
]
483 elif len(ItemList
) > 0:
484 self
._CurSection
= [ItemList
[0], 'DUMMY', TAB_COMMON
]
486 ## PreprocessFile() method
488 # Preprocess file contents, replace comments with spaces.
489 # In the end, rewind the file buffer pointer to the beginning
490 # BUGBUG: No !include statement processing contained in this procedure
491 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
493 # @param self The object pointer
495 def PreprocessFile(self
):
498 DoubleSlashComment
= False
500 # HashComment in quoted string " " is ignored.
503 while not self
._EndOfFile
():
505 if self
._CurrentChar
() == T_CHAR_DOUBLE_QUOTE
and not InComment
:
506 InString
= not InString
507 # meet new line, then no longer in a comment for // and '#'
508 if self
._CurrentChar
() == TAB_LINE_BREAK
:
509 self
.CurrentLineNumber
+= 1
510 self
.CurrentOffsetWithinLine
= 0
511 if InComment
and DoubleSlashComment
:
513 DoubleSlashComment
= False
514 if InComment
and HashComment
:
517 # check for */ comment end
518 elif InComment
and not DoubleSlashComment
and not HashComment
and self
._CurrentChar
() == T_CHAR_STAR
and self
._NextChar
() == TAB_BACK_SLASH
:
519 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
521 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
524 # set comments to spaces
526 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
528 # check for // comment
529 elif self
._CurrentChar
() == TAB_BACK_SLASH
and self
._NextChar
() == TAB_BACK_SLASH
and not self
._EndOfLine
():
531 DoubleSlashComment
= True
532 # check for '#' comment
533 elif self
._CurrentChar
() == TAB_COMMENT_SPLIT
and not self
._EndOfLine
() and not InString
:
536 # check for /* comment start
537 elif self
._CurrentChar
() == TAB_BACK_SLASH
and self
._NextChar
() == T_CHAR_STAR
:
538 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
540 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
546 # restore from ListOfList to ListOfString
547 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
550 ## PreprocessIncludeFile() method
552 # Preprocess file contents, replace !include statements with file contents.
553 # In the end, rewind the file buffer pointer to the beginning
555 # @param self The object pointer
557 def PreprocessIncludeFile(self
):
558 # nested include support
561 while self
._GetNextToken
():
563 if self
._Token
== TAB_DEFINE
:
564 if not self
._GetNextToken
():
565 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
567 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
568 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
569 Value
= self
._GetExpression
()
570 MacroDict
[Macro
] = Value
572 elif self
._Token
== TAB_INCLUDE
:
574 IncludeLine
= self
.CurrentLineNumber
575 IncludeOffset
= self
.CurrentOffsetWithinLine
- len(TAB_INCLUDE
)
576 if not self
._GetNextToken
():
577 raise Warning("expected include file name", self
.FileName
, self
.CurrentLineNumber
)
578 IncFileName
= self
._Token
580 StartPos
= IncFileName
.find('$(', PreIndex
)
581 EndPos
= IncFileName
.find(')', StartPos
+2)
582 while StartPos
!= -1 and EndPos
!= -1:
583 Macro
= IncFileName
[StartPos
+2: EndPos
]
584 MacroVal
= self
._GetMacroValue
(Macro
)
586 if Macro
in MacroDict
:
587 MacroVal
= MacroDict
[Macro
]
588 if MacroVal
is not None:
589 IncFileName
= IncFileName
.replace('$(' + Macro
+ ')', MacroVal
, 1)
590 if MacroVal
.find('$(') != -1:
593 PreIndex
= StartPos
+ len(MacroVal
)
595 raise Warning("The Macro %s is not defined" %Macro
, self
.FileName
, self
.CurrentLineNumber
)
596 StartPos
= IncFileName
.find('$(', PreIndex
)
597 EndPos
= IncFileName
.find(')', StartPos
+2)
599 IncludedFile
= NormPath(IncFileName
)
601 # First search the include file under the same directory as FDF file
603 IncludedFile1
= PathClass(IncludedFile
, os
.path
.dirname(self
.FileName
))
604 ErrorCode
= IncludedFile1
.Validate()[0]
607 # Then search the include file under the same directory as DSC file
610 if GenFdsGlobalVariable
.ActivePlatform
:
611 PlatformDir
= GenFdsGlobalVariable
.ActivePlatform
.Dir
612 elif GlobalData
.gActivePlatform
:
613 PlatformDir
= GlobalData
.gActivePlatform
.MetaFile
.Dir
614 IncludedFile1
= PathClass(IncludedFile
, PlatformDir
)
615 ErrorCode
= IncludedFile1
.Validate()[0]
618 # Also search file under the WORKSPACE directory
620 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
621 ErrorCode
= IncludedFile1
.Validate()[0]
623 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
),
624 self
.FileName
, self
.CurrentLineNumber
)
626 if not IsValidInclude (IncludedFile1
.Path
, self
.CurrentLineNumber
):
627 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1
.Path
), self
.FileName
, self
.CurrentLineNumber
)
629 IncFileProfile
= IncludeFileProfile(IncludedFile1
.Path
)
631 CurrentLine
= self
.CurrentLineNumber
632 CurrentOffset
= self
.CurrentOffsetWithinLine
633 # list index of the insertion, note that line number is 'CurrentLine + 1'
634 InsertAtLine
= CurrentLine
635 ParentProfile
= GetParentAtLine (CurrentLine
)
636 if ParentProfile
is not None:
637 ParentProfile
.IncludeFileList
.insert(0, IncFileProfile
)
638 IncFileProfile
.Level
= ParentProfile
.Level
+ 1
639 IncFileProfile
.InsertStartLineNumber
= InsertAtLine
+ 1
640 # deal with remaining portions after "!include filename", if exists.
641 if self
._GetNextToken
():
642 if self
.CurrentLineNumber
== CurrentLine
:
643 RemainingLine
= self
._CurrentLine
()[CurrentOffset
:]
644 self
.Profile
.FileLinesList
.insert(self
.CurrentLineNumber
, RemainingLine
)
645 IncFileProfile
.InsertAdjust
+= 1
646 self
.CurrentLineNumber
+= 1
647 self
.CurrentOffsetWithinLine
= 0
649 for Line
in IncFileProfile
.FileLinesList
:
650 self
.Profile
.FileLinesList
.insert(InsertAtLine
, Line
)
651 self
.CurrentLineNumber
+= 1
654 # reversely sorted to better determine error in file
655 AllIncludeFileList
.insert(0, IncFileProfile
)
657 # comment out the processed include file statement
658 TempList
= list(self
.Profile
.FileLinesList
[IncludeLine
- 1])
659 TempList
.insert(IncludeOffset
, TAB_COMMENT_SPLIT
)
660 self
.Profile
.FileLinesList
[IncludeLine
- 1] = ''.join(TempList
)
661 if Processed
: # Nested and back-to-back support
662 self
.Rewind(DestLine
= IncFileProfile
.InsertStartLineNumber
- 1)
668 def _GetIfListCurrentItemStat(IfList
):
678 ## PreprocessConditionalStatement() method
680 # Preprocess conditional statement.
681 # In the end, rewind the file buffer pointer to the beginning
683 # @param self The object pointer
685 def PreprocessConditionalStatement(self
):
686 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
690 while self
._GetNextToken
():
691 # Determine section name and the location dependent macro
692 if self
._GetIfListCurrentItemStat
(IfList
):
693 if self
._Token
.startswith(TAB_SECTION_START
):
695 if not self
._Token
.endswith(TAB_SECTION_END
):
696 self
._SkipToToken
(TAB_SECTION_END
)
697 Header
+= self
._SkippedChars
698 if Header
.find('$(') != -1:
699 raise Warning("macro cannot be used in section header", self
.FileName
, self
.CurrentLineNumber
)
700 self
._SectionHeaderParser
(Header
)
702 # Replace macros except in RULE section or out of section
703 elif self
._CurSection
and ReplacedLine
!= self
.CurrentLineNumber
:
704 ReplacedLine
= self
.CurrentLineNumber
706 CurLine
= self
.Profile
.FileLinesList
[ReplacedLine
- 1]
708 StartPos
= CurLine
.find('$(', PreIndex
)
709 EndPos
= CurLine
.find(')', StartPos
+2)
710 while StartPos
!= -1 and EndPos
!= -1 and self
._Token
not in [TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_IF
, TAB_ELSE_IF
]:
711 MacroName
= CurLine
[StartPos
+2: EndPos
]
712 MacorValue
= self
._GetMacroValue
(MacroName
)
713 if MacorValue
is not None:
714 CurLine
= CurLine
.replace('$(' + MacroName
+ ')', MacorValue
, 1)
715 if MacorValue
.find('$(') != -1:
718 PreIndex
= StartPos
+ len(MacorValue
)
720 PreIndex
= EndPos
+ 1
721 StartPos
= CurLine
.find('$(', PreIndex
)
722 EndPos
= CurLine
.find(')', StartPos
+2)
723 self
.Profile
.FileLinesList
[ReplacedLine
- 1] = CurLine
726 if self
._Token
== TAB_DEFINE
:
727 if self
._GetIfListCurrentItemStat
(IfList
):
728 if not self
._CurSection
:
729 raise Warning("macro cannot be defined in Rule section or out of section", self
.FileName
, self
.CurrentLineNumber
)
730 DefineLine
= self
.CurrentLineNumber
- 1
731 DefineOffset
= self
.CurrentOffsetWithinLine
- len(TAB_DEFINE
)
732 if not self
._GetNextToken
():
733 raise Warning("expected Macro name", self
.FileName
, self
.CurrentLineNumber
)
735 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
736 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
738 Value
= self
._GetExpression
()
739 self
._SetMacroValue
(Macro
, Value
)
740 self
._WipeOffArea
.append(((DefineLine
, DefineOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
741 elif self
._Token
== 'SET':
742 if not self
._GetIfListCurrentItemStat
(IfList
):
744 SetLine
= self
.CurrentLineNumber
- 1
745 SetOffset
= self
.CurrentOffsetWithinLine
- len('SET')
746 PcdPair
= self
._GetNextPcdSettings
()
747 PcdName
= "%s.%s" % (PcdPair
[1], PcdPair
[0])
748 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
749 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
751 Value
= self
._GetExpression
()
752 Value
= self
._EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
754 self
._PcdDict
[PcdName
] = Value
756 self
.Profile
.PcdDict
[PcdPair
] = Value
757 self
.SetPcdLocalation(PcdPair
)
758 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
759 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
761 self
._WipeOffArea
.append(((SetLine
, SetOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
762 elif self
._Token
in (TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_IF
):
763 IfStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
._Token
))
764 IfList
.append([IfStartPos
, None, None])
766 CondLabel
= self
._Token
767 Expression
= self
._GetExpression
()
769 if CondLabel
== TAB_IF
:
770 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
772 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'in')
773 if CondLabel
== TAB_IF_N_DEF
:
774 ConditionSatisfied
= not ConditionSatisfied
776 BranchDetermined
= ConditionSatisfied
777 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, BranchDetermined
]
778 if ConditionSatisfied
:
779 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
780 elif self
._Token
in (TAB_ELSE_IF
, '!else'):
781 ElseStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
._Token
))
783 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
786 IfList
[-1] = [ElseStartPos
, False, True]
787 self
._WipeOffArea
.append((ElseStartPos
, (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
789 self
._WipeOffArea
.append((IfList
[-1][0], ElseStartPos
))
790 IfList
[-1] = [ElseStartPos
, True, IfList
[-1][2]]
791 if self
._Token
== TAB_ELSE_IF
:
792 Expression
= self
._GetExpression
()
793 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
794 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, IfList
[-1][2]]
798 IfList
[-1][1] = False
801 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
802 elif self
._Token
== '!endif':
804 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
806 self
._WipeOffArea
.append(((self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len('!endif')), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
808 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
811 elif not IfList
: # Don't use PCDs inside conditional directive
812 if self
.CurrentLineNumber
<= RegionLayoutLine
:
813 # Don't try the same line twice
815 SetPcd
= ShortcutPcdPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
817 self
._PcdDict
[SetPcd
.group('name')] = SetPcd
.group('value')
818 RegionLayoutLine
= self
.CurrentLineNumber
820 RegionSize
= RegionSizePattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
822 RegionLayoutLine
= self
.CurrentLineNumber
824 RegionSizeGuid
= RegionSizeGuidPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
])
825 if not RegionSizeGuid
:
826 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
828 self
._PcdDict
[RegionSizeGuid
.group('base')] = RegionSize
.group('base')
829 self
._PcdDict
[RegionSizeGuid
.group('size')] = RegionSize
.group('size')
830 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
833 raise Warning("Missing !endif", self
.FileName
, self
.CurrentLineNumber
)
836 def _CollectMacroPcd(self
):
840 MacroDict
.update(GlobalData
.gPlatformPcds
)
841 MacroDict
.update(self
._PcdDict
)
844 MacroDict
.update(GlobalData
.gPlatformDefines
)
848 ScopeMacro
= self
._MacroDict
[TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
850 MacroDict
.update(ScopeMacro
)
853 ScopeMacro
= self
._MacroDict
[
859 MacroDict
.update(ScopeMacro
)
861 MacroDict
.update(GlobalData
.gGlobalDefines
)
862 MacroDict
.update(GlobalData
.gCommandLineDefines
)
863 if GlobalData
.BuildOptionPcd
:
864 for Item
in GlobalData
.BuildOptionPcd
:
865 if isinstance(Item
, tuple):
867 PcdName
, TmpValue
= Item
.split(TAB_EQUAL_SPLIT
)
868 TmpValue
= BuildOptionValue(TmpValue
, {})
869 MacroDict
[PcdName
.strip()] = TmpValue
874 def _EvaluateConditional(self
, Expression
, Line
, Op
= None, Value
= None):
875 MacroPcdDict
= self
._CollectMacroPcd
()
879 return ValueExpression(Expression
, MacroPcdDict
)(True)
881 return ValueExpression(Expression
, MacroPcdDict
)()
882 except WrnExpression
as Excpt
:
884 # Catch expression evaluation warning here. We need to report
885 # the precise number of line and return the evaluation result
887 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
888 File
=self
.FileName
, ExtraData
=self
._CurrentLine
(),
891 except Exception as Excpt
:
892 if hasattr(Excpt
, 'Pcd'):
893 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
894 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
895 raise Warning("Cannot use this PCD (%s) in an expression as"
896 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
897 " of the DSC file (%s), and it is currently defined in this section:"
898 " %s, line #: %d." % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE'], Info
[0], Info
[1]),
901 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE']),
904 raise Warning(str(Excpt
), self
.FileName
, Line
)
906 if Expression
.startswith('$(') and Expression
[-1] == ')':
907 Expression
= Expression
[2:-1]
908 return Expression
in MacroPcdDict
912 # Check whether input string is found from current char position along
913 # If found, the string value is put into self._Token
915 # @param self The object pointer
916 # @param String The string to search
917 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
918 # @retval True Successfully find string, file buffer pointer moved forward
919 # @retval False Not able to find string, file buffer pointer not changed
921 def _IsToken(self
, String
, IgnoreCase
= False):
922 self
._SkipWhiteSpace
()
924 # Only consider the same line, no multi-line token allowed
925 StartPos
= self
.CurrentOffsetWithinLine
928 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
930 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
932 self
.CurrentOffsetWithinLine
+= len(String
)
933 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
937 ## _IsKeyword() method
939 # Check whether input keyword is found from current char position along, whole word only!
940 # If found, the string value is put into self._Token
942 # @param self The object pointer
943 # @param Keyword The string to search
944 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
945 # @retval True Successfully find string, file buffer pointer moved forward
946 # @retval False Not able to find string, file buffer pointer not changed
948 def _IsKeyword(self
, KeyWord
, IgnoreCase
= False):
949 self
._SkipWhiteSpace
()
951 # Only consider the same line, no multi-line token allowed
952 StartPos
= self
.CurrentOffsetWithinLine
955 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(KeyWord
.upper())
957 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(KeyWord
)
959 followingChar
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
+ len(KeyWord
)]
960 if not str(followingChar
).isspace() and followingChar
not in SEPARATORS
:
962 self
.CurrentOffsetWithinLine
+= len(KeyWord
)
963 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
967 def _GetExpression(self
):
968 Line
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
969 Index
= len(Line
) - 1
970 while Line
[Index
] in [T_CHAR_CR
, TAB_LINE_BREAK
]:
972 ExpressionString
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:Index
+1]
973 self
.CurrentOffsetWithinLine
+= len(ExpressionString
)
974 ExpressionString
= ExpressionString
.strip()
975 return ExpressionString
977 ## _GetNextWord() method
979 # Get next C name from file lines
980 # If found, the string value is put into self._Token
982 # @param self The object pointer
983 # @retval True Successfully find a C name string, file buffer pointer moved forward
984 # @retval False Not able to find a C name string, file buffer pointer not changed
986 def _GetNextWord(self
):
987 self
._SkipWhiteSpace
()
988 if self
._EndOfFile
():
991 TempChar
= self
._CurrentChar
()
992 StartPos
= self
.CurrentOffsetWithinLine
993 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_':
995 while not self
._EndOfLine
():
996 TempChar
= self
._CurrentChar
()
997 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
998 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-':
1004 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1009 def _GetNextPcdWord(self
):
1010 self
._SkipWhiteSpace
()
1011 if self
._EndOfFile
():
1014 TempChar
= self
._CurrentChar
()
1015 StartPos
= self
.CurrentOffsetWithinLine
1016 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_' or TempChar
== TAB_SECTION_START
or TempChar
== TAB_SECTION_END
:
1018 while not self
._EndOfLine
():
1019 TempChar
= self
._CurrentChar
()
1020 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1021 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-' or TempChar
== TAB_SECTION_START
or TempChar
== TAB_SECTION_END
:
1027 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1032 ## _GetNextToken() method
1034 # Get next token unit before a seperator
1035 # If found, the string value is put into self._Token
1037 # @param self The object pointer
1038 # @retval True Successfully find a token unit, file buffer pointer moved forward
1039 # @retval False Not able to find a token unit, file buffer pointer not changed
1041 def _GetNextToken(self
):
1042 # Skip leading spaces, if exist.
1043 self
._SkipWhiteSpace
()
1044 if self
._EndOfFile
():
1046 # Record the token start position, the position of the first non-space char.
1047 StartPos
= self
.CurrentOffsetWithinLine
1048 StartLine
= self
.CurrentLineNumber
1049 while StartLine
== self
.CurrentLineNumber
:
1050 TempChar
= self
._CurrentChar
()
1051 # Try to find the end char that is not a space and not in seperator tuple.
1052 # That is, when we got a space or any char in the tuple, we got the end of token.
1053 if not str(TempChar
).isspace() and TempChar
not in SEPARATORS
:
1055 # if we happen to meet a seperator as the first char, we must proceed to get it.
1056 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1057 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPARATORS
:
1065 EndPos
= self
.CurrentOffsetWithinLine
1066 if self
.CurrentLineNumber
!= StartLine
:
1067 EndPos
= len(self
.Profile
.FileLinesList
[StartLine
-1])
1068 self
._Token
= self
.Profile
.FileLinesList
[StartLine
-1][StartPos
: EndPos
]
1069 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
]:
1070 self
._Token
= self
._Token
.lower()
1071 if StartPos
!= self
.CurrentOffsetWithinLine
:
1076 ## _GetNextGuid() method
1078 # Get next token unit before a seperator
1079 # If found, the GUID string is put into self._Token
1081 # @param self The object pointer
1082 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
1083 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
1085 def _GetNextGuid(self
):
1086 if not self
._GetNextToken
():
1088 if gGuidPattern
.match(self
._Token
) is not None:
1095 def _Verify(Name
, Value
, Scope
):
1096 # value verification only applies to numeric values.
1097 if Scope
not in TAB_PCD_NUMERIC_TYPES
:
1102 ValueNumber
= int(Value
, 0)
1104 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value is not valid dec or hex number for %s." % Name
)
1106 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value can't be set to negative value for %s." % Name
)
1107 if ValueNumber
> MAX_VAL_TYPE
[Scope
]:
1108 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "Too large value for %s." % Name
)
1111 ## _UndoToken() method
1113 # Go back one token unit in file buffer
1115 # @param self The object pointer
1117 def _UndoToken(self
):
1119 while self
._CurrentChar
().isspace():
1120 if not self
._UndoOneChar
():
1125 StartPos
= self
.CurrentOffsetWithinLine
1126 CurrentLine
= self
.CurrentLineNumber
1127 while CurrentLine
== self
.CurrentLineNumber
:
1129 TempChar
= self
._CurrentChar
()
1130 # Try to find the end char that is not a space and not in seperator tuple.
1131 # That is, when we got a space or any char in the tuple, we got the end of token.
1132 if not str(TempChar
).isspace() and not TempChar
in SEPARATORS
:
1133 if not self
._UndoOneChar
():
1135 # if we happen to meet a seperator as the first char, we must proceed to get it.
1136 # That is, we get a token that is a seperator char. nomally it is the boundary of other tokens.
1137 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPARATORS
:
1144 ## _GetNextHexNumber() method
1146 # Get next HEX data before a seperator
1147 # If found, the HEX data is put into self._Token
1149 # @param self The object pointer
1150 # @retval True Successfully find a HEX data, file buffer pointer moved forward
1151 # @retval False Not able to find a HEX data, file buffer pointer not changed
1153 def _GetNextHexNumber(self
):
1154 if not self
._GetNextToken
():
1156 if gHexPatternAll
.match(self
._Token
):
1162 ## _GetNextDecimalNumber() method
1164 # Get next decimal data before a seperator
1165 # If found, the decimal data is put into self._Token
1167 # @param self The object pointer
1168 # @retval True Successfully find a decimal data, file buffer pointer moved forward
1169 # @retval False Not able to find a decimal data, file buffer pointer not changed
1171 def _GetNextDecimalNumber(self
):
1172 if not self
._GetNextToken
():
1174 if self
._Token
.isdigit():
1180 def _GetNextPcdSettings(self
):
1181 if not self
._GetNextWord
():
1182 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1183 pcdTokenSpaceCName
= self
._Token
1185 if not self
._IsToken
(TAB_SPLIT
):
1186 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1188 if not self
._GetNextWord
():
1189 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1190 pcdCName
= self
._Token
1193 while self
._IsToken
(TAB_SPLIT
):
1194 if not self
._GetNextPcdWord
():
1195 raise Warning("expected format of <PcdTokenSpaceCName>.<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1196 Fields
.append(self
._Token
)
1198 return (pcdCName
, pcdTokenSpaceCName
,TAB_SPLIT
.join(Fields
))
1200 ## _GetStringData() method
1202 # Get string contents quoted in ""
1203 # If found, the decimal data is put into self._Token
1205 # @param self The object pointer
1206 # @retval True Successfully find a string data, file buffer pointer moved forward
1207 # @retval False Not able to find a string data, file buffer pointer not changed
1209 def _GetStringData(self
):
1210 if self
._Token
.startswith(T_CHAR_DOUBLE_QUOTE
) or self
._Token
.startswith("L\""):
1212 self
._SkipToToken
(T_CHAR_DOUBLE_QUOTE
)
1213 currentLineNumber
= self
.CurrentLineNumber
1215 if not self
._SkipToToken
(T_CHAR_DOUBLE_QUOTE
):
1216 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1217 if currentLineNumber
!= self
.CurrentLineNumber
:
1218 raise Warning("Missing Quote \" for String", self
.FileName
, self
.CurrentLineNumber
)
1219 self
._Token
= self
._SkippedChars
.rstrip(T_CHAR_DOUBLE_QUOTE
)
1222 elif self
._Token
.startswith(T_CHAR_SINGLE_QUOTE
) or self
._Token
.startswith("L\'"):
1224 self
._SkipToToken
(T_CHAR_SINGLE_QUOTE
)
1225 currentLineNumber
= self
.CurrentLineNumber
1227 if not self
._SkipToToken
(T_CHAR_SINGLE_QUOTE
):
1228 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1229 if currentLineNumber
!= self
.CurrentLineNumber
:
1230 raise Warning("Missing Quote \' for String", self
.FileName
, self
.CurrentLineNumber
)
1231 self
._Token
= self
._SkippedChars
.rstrip(T_CHAR_SINGLE_QUOTE
)
1237 ## _SkipToToken() method
1239 # Search forward in file buffer for the string
1240 # The skipped chars are put into self._SkippedChars
1242 # @param self The object pointer
1243 # @param String The string to search
1244 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1245 # @retval True Successfully find the string, file buffer pointer moved forward
1246 # @retval False Not able to find the string, file buffer pointer not changed
1248 def _SkipToToken(self
, String
, IgnoreCase
= False):
1249 StartPos
= self
.GetFileBufferPos()
1251 self
._SkippedChars
= ""
1252 while not self
._EndOfFile
():
1255 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
1257 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
1259 self
.CurrentOffsetWithinLine
+= len(String
)
1260 self
._SkippedChars
+= String
1262 self
._SkippedChars
+= str(self
._CurrentChar
())
1265 self
.SetFileBufferPos(StartPos
)
1266 self
._SkippedChars
= ""
1269 ## GetFileBufferPos() method
1271 # Return the tuple of current line and offset within the line
1273 # @param self The object pointer
1274 # @retval Tuple Line number and offset pair
1276 def GetFileBufferPos(self
):
1277 return (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
)
1279 ## SetFileBufferPos() method
1281 # Restore the file buffer position
1283 # @param self The object pointer
1284 # @param Pos The new file buffer position
1286 def SetFileBufferPos(self
, Pos
):
1287 (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
) = Pos
1289 ## Preprocess() method
1291 # Preprocess comment, conditional directive, include directive, replace macro.
1292 # Exception will be raised if syntax error found
1294 # @param self The object pointer
1296 def Preprocess(self
):
1297 self
._StringToList
()
1298 self
.PreprocessFile()
1299 self
.PreprocessIncludeFile()
1300 self
._StringToList
()
1301 self
.PreprocessFile()
1302 self
.PreprocessConditionalStatement()
1303 self
._StringToList
()
1304 for Pos
in self
._WipeOffArea
:
1305 self
._ReplaceFragment
(Pos
[0], Pos
[1])
1306 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
1308 while self
._GetDefines
():
1311 ## ParseFile() method
1313 # Parse the file profile buffer to extract fd, fv ... information
1314 # Exception will be raised if syntax error found
1316 # @param self The object pointer
1318 def ParseFile(self
):
1323 # Keep processing sections of the FDF until no new sections or a syntax error is found
1325 while self
._GetFd
() or self
._GetFv
() or self
._GetFmp
() or self
._GetCapsule
() or self
._GetVtf
() or self
._GetRule
() or self
._GetOptionRom
():
1328 except Warning as X
:
1330 #'\n\tGot Token: \"%s\" from File %s\n' % (self._Token, FileLineTuple[0]) + \
1331 # At this point, the closest parent would be the included file itself
1332 Profile
= GetParentAtLine(X
.OriginalLineNumber
)
1333 if Profile
is not None:
1334 X
.Message
+= ' near line %d, column %d: %s' \
1335 % (X
.LineNumber
, 0, Profile
.FileLinesList
[X
.LineNumber
-1])
1337 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1338 X
.Message
+= ' near line %d, column %d: %s' \
1339 % (FileLineTuple
[1], self
.CurrentOffsetWithinLine
+ 1, self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:].rstrip(TAB_LINE_BREAK
).rstrip(T_CHAR_CR
))
1342 ## SectionParser() method
1344 # Parse the file section info
1345 # Exception will be raised if syntax error found
1347 # @param self The object pointer
1348 # @param section The section string
1350 def SectionParser(self
, section
):
1352 if not S
.startswith("[DEFINES") and not S
.startswith("[FD.") and not S
.startswith("[FV.") and not S
.startswith("[CAPSULE.") \
1353 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM.") and not S
.startswith('[FMPPAYLOAD.'):
1354 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
)
1356 ## _GetDefines() method
1358 # Get Defines section contents and store its data into AllMacrosList
1360 # @param self The object pointer
1361 # @retval True Successfully find a Defines
1362 # @retval False Not able to find a Defines
1364 def _GetDefines(self
):
1365 if not self
._GetNextToken
():
1368 S
= self
._Token
.upper()
1369 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[DEFINES"):
1370 self
.SectionParser(S
)
1375 if not self
._IsToken
("[DEFINES", True):
1376 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1377 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1378 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1379 raise Warning("expected [DEFINES", self
.FileName
, self
.CurrentLineNumber
)
1381 if not self
._IsToken
(TAB_SECTION_END
):
1382 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1384 while self
._GetNextWord
():
1385 # handle the SET statement
1386 if self
._Token
== 'SET':
1388 self
._GetSetStatement
(None)
1393 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1394 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1395 if not self
._GetNextToken
() or self
._Token
.startswith(TAB_SECTION_START
):
1396 raise Warning("expected MACRO value", self
.FileName
, self
.CurrentLineNumber
)
1401 ##_GetError() method
1402 def _GetError(self
):
1403 #save the Current information
1404 CurrentLine
= self
.CurrentLineNumber
1405 CurrentOffset
= self
.CurrentOffsetWithinLine
1406 while self
._GetNextToken
():
1407 if self
._Token
== TAB_ERROR
:
1408 EdkLogger
.error('FdfParser', ERROR_STATEMENT
, self
._CurrentLine
().replace(TAB_ERROR
, '', 1), File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
1409 self
.CurrentLineNumber
= CurrentLine
1410 self
.CurrentOffsetWithinLine
= CurrentOffset
1414 # Get FD section contents and store its data into FD dictionary of self.Profile
1416 # @param self The object pointer
1417 # @retval True Successfully find a FD
1418 # @retval False Not able to find a FD
1421 if not self
._GetNextToken
():
1424 S
= self
._Token
.upper()
1425 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FD."):
1426 if not S
.startswith("[FV.") and not S
.startswith('[FMPPAYLOAD.') and not S
.startswith("[CAPSULE.") \
1427 and not S
.startswith("[VTF.") and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM."):
1428 raise Warning("Unknown section", self
.FileName
, self
.CurrentLineNumber
)
1433 if not self
._IsToken
("[FD.", True):
1434 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1435 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1436 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1437 raise Warning("expected [FD.]", self
.FileName
, self
.CurrentLineNumber
)
1439 FdName
= self
._GetUiName
()
1441 if len (self
.Profile
.FdDict
) == 0:
1442 FdName
= GenFdsGlobalVariable
.PlatformName
1443 if FdName
== "" and GlobalData
.gActivePlatform
:
1444 FdName
= GlobalData
.gActivePlatform
.PlatformName
1445 self
.Profile
.FdNameNotSet
= True
1447 raise Warning("expected FdName in [FD.] section", self
.FileName
, self
.CurrentLineNumber
)
1448 self
.CurrentFdName
= FdName
.upper()
1450 if self
.CurrentFdName
in self
.Profile
.FdDict
:
1451 raise Warning("Unexpected the same FD name", self
.FileName
, self
.CurrentLineNumber
)
1453 if not self
._IsToken
(TAB_SECTION_END
):
1454 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
1457 FdObj
.FdUiName
= self
.CurrentFdName
1458 self
.Profile
.FdDict
[self
.CurrentFdName
] = FdObj
1460 if len (self
.Profile
.FdDict
) > 1 and self
.Profile
.FdNameNotSet
:
1461 raise Warning("expected all FDs have their name", self
.FileName
, self
.CurrentLineNumber
)
1463 Status
= self
._GetCreateFile
(FdObj
)
1465 raise Warning("FD name error", self
.FileName
, self
.CurrentLineNumber
)
1467 while self
._GetTokenStatements
(FdObj
):
1469 for Attr
in ("BaseAddress", "Size", "ErasePolarity"):
1470 if getattr(FdObj
, Attr
) is None:
1471 self
._GetNextToken
()
1472 raise Warning("Keyword %s missing" % Attr
, self
.FileName
, self
.CurrentLineNumber
)
1474 if not FdObj
.BlockSizeList
:
1475 FdObj
.BlockSizeList
.append((1, FdObj
.Size
, None))
1477 self
._GetDefineStatements
(FdObj
)
1479 self
._GetSetStatements
(FdObj
)
1481 if not self
._GetRegionLayout
(FdObj
):
1482 raise Warning("expected region layout", self
.FileName
, self
.CurrentLineNumber
)
1484 while self
._GetRegionLayout
(FdObj
):
1488 ## _GetUiName() method
1490 # Return the UI name of a section
1492 # @param self The object pointer
1493 # @retval FdName UI name
1495 def _GetUiName(self
):
1497 if self
._GetNextWord
():
1502 ## _GetCreateFile() method
1504 # Return the output file name of object
1506 # @param self The object pointer
1507 # @param Obj object whose data will be stored in file
1508 # @retval FdName UI name
1510 def _GetCreateFile(self
, Obj
):
1511 if self
._IsKeyword
("CREATE_FILE"):
1512 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1513 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1515 if not self
._GetNextToken
():
1516 raise Warning("expected file name", self
.FileName
, self
.CurrentLineNumber
)
1518 FileName
= self
._Token
1519 Obj
.CreateFileName
= FileName
1523 def SetPcdLocalation(self
,pcdpair
):
1524 self
.Profile
.PcdLocalDict
[pcdpair
] = (self
.Profile
.FileName
,self
.CurrentLineNumber
)
1526 ## _GetTokenStatements() method
1528 # Get token statements
1530 # @param self The object pointer
1531 # @param Obj for whom token statement is got
1533 def _GetTokenStatements(self
, Obj
):
1534 if self
._IsKeyword
("BaseAddress"):
1535 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1536 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1538 if not self
._GetNextHexNumber
():
1539 raise Warning("expected Hex base address", self
.FileName
, self
.CurrentLineNumber
)
1541 Obj
.BaseAddress
= self
._Token
1543 if self
._IsToken
(TAB_VALUE_SPLIT
):
1544 pcdPair
= self
._GetNextPcdSettings
()
1545 Obj
.BaseAddressPcd
= pcdPair
1546 self
.Profile
.PcdDict
[pcdPair
] = Obj
.BaseAddress
1547 self
.SetPcdLocalation(pcdPair
)
1548 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1549 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1552 if self
._IsKeyword
("Size"):
1553 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1554 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1556 if not self
._GetNextHexNumber
():
1557 raise Warning("expected Hex size", self
.FileName
, self
.CurrentLineNumber
)
1560 if self
._IsToken
(TAB_VALUE_SPLIT
):
1561 pcdPair
= self
._GetNextPcdSettings
()
1562 Obj
.SizePcd
= pcdPair
1563 self
.Profile
.PcdDict
[pcdPair
] = Size
1564 self
.SetPcdLocalation(pcdPair
)
1565 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1566 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1567 Obj
.Size
= long(Size
, 0)
1570 if self
._IsKeyword
("ErasePolarity"):
1571 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1572 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1574 if not self
._GetNextToken
():
1575 raise Warning("expected Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1577 if self
._Token
!= "1" and self
._Token
!= "0":
1578 raise Warning("expected 1 or 0 Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1580 Obj
.ErasePolarity
= self
._Token
1583 return self
._GetBlockStatements
(Obj
)
1585 ## _GetAddressStatements() method
1587 # Get address statements
1589 # @param self The object pointer
1590 # @param Obj for whom address statement is got
1591 # @retval True Successfully find
1592 # @retval False Not able to find
1594 def _GetAddressStatements(self
, Obj
):
1595 if self
._IsKeyword
("BsBaseAddress"):
1596 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1597 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1599 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1600 raise Warning("expected address", self
.FileName
, self
.CurrentLineNumber
)
1602 BsAddress
= long(self
._Token
, 0)
1603 Obj
.BsBaseAddress
= BsAddress
1605 if self
._IsKeyword
("RtBaseAddress"):
1606 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1607 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1609 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1610 raise Warning("expected address", self
.FileName
, self
.CurrentLineNumber
)
1612 RtAddress
= long(self
._Token
, 0)
1613 Obj
.RtBaseAddress
= RtAddress
1615 ## _GetBlockStatements() method
1617 # Get block statements
1619 # @param self The object pointer
1620 # @param Obj for whom block statement is got
1622 def _GetBlockStatements(self
, Obj
):
1624 while self
._GetBlockStatement
(Obj
):
1627 Item
= Obj
.BlockSizeList
[-1]
1628 if Item
[0] is None or Item
[1] is None:
1629 raise Warning("expected block statement", self
.FileName
, self
.CurrentLineNumber
)
1632 ## _GetBlockStatement() method
1634 # Get block statement
1636 # @param self The object pointer
1637 # @param Obj for whom block statement is got
1638 # @retval True Successfully find
1639 # @retval False Not able to find
1641 def _GetBlockStatement(self
, Obj
):
1642 if not self
._IsKeyword
("BlockSize"):
1645 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1646 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1648 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
1649 raise Warning("expected Hex or Integer block size", self
.FileName
, self
.CurrentLineNumber
)
1651 BlockSize
= self
._Token
1653 if self
._IsToken
(TAB_VALUE_SPLIT
):
1654 PcdPair
= self
._GetNextPcdSettings
()
1655 BlockSizePcd
= PcdPair
1656 self
.Profile
.PcdDict
[PcdPair
] = BlockSize
1657 self
.SetPcdLocalation(PcdPair
)
1658 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1659 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1660 BlockSize
= long(BlockSize
, 0)
1663 if self
._IsKeyword
("NumBlocks"):
1664 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1665 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1667 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1668 raise Warning("expected block numbers", self
.FileName
, self
.CurrentLineNumber
)
1670 BlockNumber
= long(self
._Token
, 0)
1672 Obj
.BlockSizeList
.append((BlockSize
, BlockNumber
, BlockSizePcd
))
1675 ## _GetDefineStatements() method
1677 # Get define statements
1679 # @param self The object pointer
1680 # @param Obj for whom define statement is got
1681 # @retval True Successfully find
1682 # @retval False Not able to find
1684 def _GetDefineStatements(self
, Obj
):
1685 while self
._GetDefineStatement
(Obj
):
1688 ## _GetDefineStatement() method
1690 # Get define statement
1692 # @param self The object pointer
1693 # @param Obj for whom define statement is got
1694 # @retval True Successfully find
1695 # @retval False Not able to find
1697 def _GetDefineStatement(self
, Obj
):
1698 if self
._IsKeyword
(TAB_DEFINE
):
1699 self
._GetNextToken
()
1701 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1702 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1704 if not self
._GetNextToken
():
1705 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
1708 Macro
= '$(' + Macro
+ ')'
1709 Obj
.DefineVarDict
[Macro
] = Value
1714 ## _GetSetStatements() method
1716 # Get set statements
1718 # @param self The object pointer
1719 # @param Obj for whom set statement is got
1720 # @retval True Successfully find
1721 # @retval False Not able to find
1723 def _GetSetStatements(self
, Obj
):
1724 while self
._GetSetStatement
(Obj
):
1727 ## _GetSetStatement() method
1731 # @param self The object pointer
1732 # @param Obj for whom set statement is got
1733 # @retval True Successfully find
1734 # @retval False Not able to find
1736 def _GetSetStatement(self
, Obj
):
1737 if self
._IsKeyword
("SET"):
1738 PcdPair
= self
._GetNextPcdSettings
()
1740 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1741 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1743 Value
= self
._GetExpression
()
1744 Value
= self
._EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
1747 Obj
.SetVarDict
[PcdPair
] = Value
1748 self
.Profile
.PcdDict
[PcdPair
] = Value
1749 self
.SetPcdLocalation(PcdPair
)
1750 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1751 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1756 ## _CalcRegionExpr(self)
1758 # Calculate expression for offset or size of a region
1760 # @return: None if invalid expression
1761 # Calculated number if successfully
1763 def _CalcRegionExpr(self
):
1764 StartPos
= self
.GetFileBufferPos()
1767 while not self
._EndOfFile
():
1768 CurCh
= self
._CurrentChar
()
1774 if CurCh
in '|\r\n' and PairCount
== 0:
1780 ValueExpression(Expr
,
1781 self
._CollectMacroPcd
()
1784 self
.SetFileBufferPos(StartPos
)
1787 ## _GetRegionLayout() method
1789 # Get region layout for FD
1791 # @param self The object pointer
1792 # @param theFd for whom region is got
1793 # @retval True Successfully find
1794 # @retval False Not able to find
1796 def _GetRegionLayout(self
, theFd
):
1797 Offset
= self
._CalcRegionExpr
()
1801 RegionObj
= Region()
1802 RegionObj
.Offset
= Offset
1803 theFd
.RegionList
.append(RegionObj
)
1805 if not self
._IsToken
(TAB_VALUE_SPLIT
):
1806 raise Warning("expected '|'", self
.FileName
, self
.CurrentLineNumber
)
1808 Size
= self
._CalcRegionExpr
()
1810 raise Warning("expected Region Size", self
.FileName
, self
.CurrentLineNumber
)
1811 RegionObj
.Size
= Size
1813 if not self
._GetNextWord
():
1816 if not self
._Token
in ("SET", BINARY_FILE_TYPE_FV
, "FILE", "DATA", "CAPSULE", "INF"):
1818 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1819 # Or it might be next region's offset described by an expression which starts with a PCD.
1820 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1823 IsRegionPcd
= (RegionSizeGuidPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]) or
1824 RegionOffsetPcdPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]))
1826 RegionObj
.PcdOffset
= self
._GetNextPcdSettings
()
1827 self
.Profile
.PcdDict
[RegionObj
.PcdOffset
] = "0x%08X" % (RegionObj
.Offset
+ long(theFd
.BaseAddress
, 0))
1828 self
.SetPcdLocalation(RegionObj
.PcdOffset
)
1829 self
._PcdDict
['%s.%s' % (RegionObj
.PcdOffset
[1], RegionObj
.PcdOffset
[0])] = "0x%x" % RegionObj
.Offset
1830 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1831 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdOffset
] = FileLineTuple
1832 if self
._IsToken
(TAB_VALUE_SPLIT
):
1833 RegionObj
.PcdSize
= self
._GetNextPcdSettings
()
1834 self
.Profile
.PcdDict
[RegionObj
.PcdSize
] = "0x%08X" % RegionObj
.Size
1835 self
.SetPcdLocalation(RegionObj
.PcdSize
)
1836 self
._PcdDict
['%s.%s' % (RegionObj
.PcdSize
[1], RegionObj
.PcdSize
[0])] = "0x%x" % RegionObj
.Size
1837 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1838 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdSize
] = FileLineTuple
1840 if not self
._GetNextWord
():
1843 if self
._Token
== "SET":
1845 self
._GetSetStatements
(RegionObj
)
1846 if not self
._GetNextWord
():
1849 elif self
._Token
== BINARY_FILE_TYPE_FV
:
1851 self
._GetRegionFvType
(RegionObj
)
1853 elif self
._Token
== "CAPSULE":
1855 self
._GetRegionCapType
(RegionObj
)
1857 elif self
._Token
== "FILE":
1859 self
._GetRegionFileType
(RegionObj
)
1861 elif self
._Token
== "INF":
1863 RegionObj
.RegionType
= "INF"
1864 while self
._IsKeyword
("INF"):
1866 ffsInf
= self
._ParseInfStatement
()
1869 RegionObj
.RegionDataList
.append(ffsInf
)
1871 elif self
._Token
== "DATA":
1873 self
._GetRegionDataType
(RegionObj
)
1876 if self
._GetRegionLayout
(theFd
):
1878 raise Warning("A valid region type was not found. "
1879 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
1880 self
.FileName
, self
.CurrentLineNumber
)
1884 ## _GetRegionFvType() method
1886 # Get region fv data for region
1888 # @param self The object pointer
1889 # @param RegionObj for whom region data is got
1891 def _GetRegionFvType(self
, RegionObj
):
1892 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1893 raise Warning("expected Keyword BINARY_FILE_TYPE_FV", self
.FileName
, self
.CurrentLineNumber
)
1895 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1896 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1898 if not self
._GetNextToken
():
1899 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1901 RegionObj
.RegionType
= BINARY_FILE_TYPE_FV
1902 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1904 while self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1906 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1907 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1909 if not self
._GetNextToken
():
1910 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
1912 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1914 ## _GetRegionCapType() method
1916 # Get region capsule data for region
1918 # @param self The object pointer
1919 # @param RegionObj for whom region data is got
1921 def _GetRegionCapType(self
, RegionObj
):
1922 if not self
._IsKeyword
("CAPSULE"):
1923 raise Warning("expected Keyword 'CAPSULE'", self
.FileName
, self
.CurrentLineNumber
)
1925 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1926 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1928 if not self
._GetNextToken
():
1929 raise Warning("expected CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1931 RegionObj
.RegionType
= "CAPSULE"
1932 RegionObj
.RegionDataList
.append(self
._Token
)
1934 while self
._IsKeyword
("CAPSULE"):
1936 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1937 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1939 if not self
._GetNextToken
():
1940 raise Warning("expected CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1942 RegionObj
.RegionDataList
.append(self
._Token
)
1944 ## _GetRegionFileType() method
1946 # Get region file data for region
1948 # @param self The object pointer
1949 # @param RegionObj for whom region data is got
1951 def _GetRegionFileType(self
, RegionObj
):
1952 if not self
._IsKeyword
("FILE"):
1953 raise Warning("expected Keyword 'FILE'", self
.FileName
, self
.CurrentLineNumber
)
1955 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1956 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1958 if not self
._GetNextToken
():
1959 raise Warning("expected File name", self
.FileName
, self
.CurrentLineNumber
)
1961 RegionObj
.RegionType
= "FILE"
1962 RegionObj
.RegionDataList
.append(self
._Token
)
1964 while self
._IsKeyword
("FILE"):
1966 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1967 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1969 if not self
._GetNextToken
():
1970 raise Warning("expected FILE name", self
.FileName
, self
.CurrentLineNumber
)
1972 RegionObj
.RegionDataList
.append(self
._Token
)
1974 ## _GetRegionDataType() method
1976 # Get region array data for region
1978 # @param self The object pointer
1979 # @param RegionObj for whom region data is got
1981 def _GetRegionDataType(self
, RegionObj
):
1982 if not self
._IsKeyword
("DATA"):
1983 raise Warning("expected Region Data type", self
.FileName
, self
.CurrentLineNumber
)
1985 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1986 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
1988 if not self
._IsToken
("{"):
1989 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
1991 if not self
._GetNextHexNumber
():
1992 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
1994 if len(self
._Token
) > 18:
1995 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
1997 # convert hex string value to byte hex string array
1998 AllString
= self
._Token
1999 AllStrLen
= len (AllString
)
2001 while AllStrLen
> 4:
2002 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
2003 AllStrLen
= AllStrLen
- 2
2004 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
2007 if len (self
._Token
) <= 4:
2008 while self
._IsToken
(TAB_COMMA_SPLIT
):
2009 if not self
._GetNextHexNumber
():
2010 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2011 if len(self
._Token
) > 4:
2012 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2013 DataString
+= self
._Token
2014 DataString
+= TAB_COMMA_SPLIT
2016 if not self
._IsToken
("}"):
2017 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2019 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2020 RegionObj
.RegionType
= "DATA"
2021 RegionObj
.RegionDataList
.append(DataString
)
2023 while self
._IsKeyword
("DATA"):
2025 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2026 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2028 if not self
._IsToken
("{"):
2029 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2031 if not self
._GetNextHexNumber
():
2032 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2034 if len(self
._Token
) > 18:
2035 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2037 # convert hex string value to byte hex string array
2038 AllString
= self
._Token
2039 AllStrLen
= len (AllString
)
2041 while AllStrLen
> 4:
2042 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
2043 AllStrLen
= AllStrLen
- 2
2044 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
2047 if len (self
._Token
) <= 4:
2048 while self
._IsToken
(TAB_COMMA_SPLIT
):
2049 if not self
._GetNextHexNumber
():
2050 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2051 if len(self
._Token
) > 4:
2052 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2053 DataString
+= self
._Token
2054 DataString
+= TAB_COMMA_SPLIT
2056 if not self
._IsToken
("}"):
2057 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2059 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2060 RegionObj
.RegionDataList
.append(DataString
)
2064 # Get FV section contents and store its data into FV dictionary of self.Profile
2066 # @param self The object pointer
2067 # @retval True Successfully find a FV
2068 # @retval False Not able to find a FV
2071 if not self
._GetNextToken
():
2074 S
= self
._Token
.upper()
2075 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FV."):
2076 self
.SectionParser(S
)
2081 if not self
._IsToken
("[FV.", True):
2082 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2083 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2084 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2085 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2087 FvName
= self
._GetUiName
()
2088 self
.CurrentFvName
= FvName
.upper()
2090 if not self
._IsToken
(TAB_SECTION_END
):
2091 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
2094 FvObj
.UiFvName
= self
.CurrentFvName
2095 self
.Profile
.FvDict
[self
.CurrentFvName
] = FvObj
2097 Status
= self
._GetCreateFile
(FvObj
)
2099 raise Warning("FV name error", self
.FileName
, self
.CurrentLineNumber
)
2101 self
._GetDefineStatements
(FvObj
)
2103 self
._GetAddressStatements
(FvObj
)
2105 FvObj
.FvExtEntryTypeValue
= []
2106 FvObj
.FvExtEntryType
= []
2107 FvObj
.FvExtEntryData
= []
2109 self
._GetSetStatements
(FvObj
)
2111 if not (self
._GetBlockStatement
(FvObj
) or self
._GetFvBaseAddress
(FvObj
) or
2112 self
._GetFvForceRebase
(FvObj
) or self
._GetFvAlignment
(FvObj
) or
2113 self
._GetFvAttributes
(FvObj
) or self
._GetFvNameGuid
(FvObj
) or
2114 self
._GetFvExtEntryStatement
(FvObj
) or self
._GetFvNameString
(FvObj
)):
2117 if FvObj
.FvNameString
== 'TRUE' and not FvObj
.FvNameGuid
:
2118 raise Warning("FvNameString found but FvNameGuid was not found", self
.FileName
, self
.CurrentLineNumber
)
2120 self
._GetAprioriSection
(FvObj
, FvObj
.DefineVarDict
.copy())
2121 self
._GetAprioriSection
(FvObj
, FvObj
.DefineVarDict
.copy())
2124 isInf
= self
._GetInfStatement
(FvObj
)
2125 isFile
= self
._GetFileStatement
(FvObj
, MacroDict
= FvObj
.DefineVarDict
.copy())
2126 if not isInf
and not isFile
:
2131 ## _GetFvAlignment() method
2133 # Get alignment for FV
2135 # @param self The object pointer
2136 # @param Obj for whom alignment is got
2137 # @retval True Successfully find a alignment statement
2138 # @retval False Not able to find a alignment statement
2140 def _GetFvAlignment(self
, Obj
):
2141 if not self
._IsKeyword
("FvAlignment"):
2144 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2145 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2147 if not self
._GetNextToken
():
2148 raise Warning("expected alignment value", self
.FileName
, self
.CurrentLineNumber
)
2150 if self
._Token
.upper() not in ("1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2151 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2152 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2154 raise Warning("Unknown alignment value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2155 Obj
.FvAlignment
= self
._Token
2158 ## _GetFvBaseAddress() method
2160 # Get BaseAddress for FV
2162 # @param self The object pointer
2163 # @param Obj for whom FvBaseAddress is got
2164 # @retval True Successfully find a FvBaseAddress statement
2165 # @retval False Not able to find a FvBaseAddress statement
2167 def _GetFvBaseAddress(self
, Obj
):
2168 if not self
._IsKeyword
("FvBaseAddress"):
2171 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2172 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2174 if not self
._GetNextToken
():
2175 raise Warning("expected FV base address value", self
.FileName
, self
.CurrentLineNumber
)
2177 if not BaseAddrValuePattern
.match(self
._Token
.upper()):
2178 raise Warning("Unknown FV base address value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2179 Obj
.FvBaseAddress
= self
._Token
2182 ## _GetFvForceRebase() method
2184 # Get FvForceRebase for FV
2186 # @param self The object pointer
2187 # @param Obj for whom FvForceRebase is got
2188 # @retval True Successfully find a FvForceRebase statement
2189 # @retval False Not able to find a FvForceRebase statement
2191 def _GetFvForceRebase(self
, Obj
):
2192 if not self
._IsKeyword
("FvForceRebase"):
2195 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2196 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2198 if not self
._GetNextToken
():
2199 raise Warning("expected FvForceRebase value", self
.FileName
, self
.CurrentLineNumber
)
2201 if self
._Token
.upper() not in ["TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"]:
2202 raise Warning("Unknown FvForceRebase value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2204 if self
._Token
.upper() in ["TRUE", "1", "0X1", "0X01"]:
2205 Obj
.FvForceRebase
= True
2206 elif self
._Token
.upper() in ["FALSE", "0", "0X0", "0X00"]:
2207 Obj
.FvForceRebase
= False
2209 Obj
.FvForceRebase
= None
2214 ## _GetFvAttributes() method
2216 # Get attributes for FV
2218 # @param self The object pointer
2219 # @param Obj for whom attribute is got
2222 def _GetFvAttributes(self
, FvObj
):
2224 while self
._GetNextWord
():
2227 if name
not in ("ERASE_POLARITY", "MEMORY_MAPPED", \
2228 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2229 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2230 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2231 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2232 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"):
2236 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2237 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2239 if not self
._GetNextToken
() or self
._Token
.upper() not in ("TRUE", "FALSE", "1", "0"):
2240 raise Warning("expected TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
2242 FvObj
.FvAttributeDict
[name
] = self
._Token
2246 ## _GetFvNameGuid() method
2248 # Get FV GUID for FV
2250 # @param self The object pointer
2251 # @param Obj for whom GUID is got
2254 def _GetFvNameGuid(self
, FvObj
):
2255 if not self
._IsKeyword
("FvNameGuid"):
2258 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2259 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2261 if not self
._GetNextGuid
():
2262 raise Warning("expected FV GUID value", self
.FileName
, self
.CurrentLineNumber
)
2264 FvObj
.FvNameGuid
= self
._Token
2268 def _GetFvNameString(self
, FvObj
):
2269 if not self
._IsKeyword
("FvNameString"):
2272 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2273 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2275 if not self
._GetNextToken
() or self
._Token
not in ('TRUE', 'FALSE'):
2276 raise Warning("expected TRUE or FALSE for FvNameString", self
.FileName
, self
.CurrentLineNumber
)
2278 FvObj
.FvNameString
= self
._Token
2282 def _GetFvExtEntryStatement(self
, FvObj
):
2283 if not (self
._IsKeyword
("FV_EXT_ENTRY") or self
._IsKeyword
("FV_EXT_ENTRY_TYPE")):
2286 if not self
._IsKeyword
("TYPE"):
2287 raise Warning("expected 'TYPE'", self
.FileName
, self
.CurrentLineNumber
)
2289 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2290 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2292 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
2293 raise Warning("expected Hex FV extension entry type value At Line ", self
.FileName
, self
.CurrentLineNumber
)
2295 FvObj
.FvExtEntryTypeValue
.append(self
._Token
)
2297 if not self
._IsToken
("{"):
2298 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2300 if not self
._IsKeyword
("FILE") and not self
._IsKeyword
("DATA"):
2301 raise Warning("expected 'FILE' or 'DATA'", self
.FileName
, self
.CurrentLineNumber
)
2303 FvObj
.FvExtEntryType
.append(self
._Token
)
2305 if self
._Token
== 'DATA':
2307 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2308 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2310 if not self
._IsToken
("{"):
2311 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2313 if not self
._GetNextHexNumber
():
2314 raise Warning("expected Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2316 if len(self
._Token
) > 4:
2317 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2319 DataString
= self
._Token
2320 DataString
+= TAB_COMMA_SPLIT
2322 while self
._IsToken
(TAB_COMMA_SPLIT
):
2323 if not self
._GetNextHexNumber
():
2324 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2325 if len(self
._Token
) > 4:
2326 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2327 DataString
+= self
._Token
2328 DataString
+= TAB_COMMA_SPLIT
2330 if not self
._IsToken
("}"):
2331 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2333 if not self
._IsToken
("}"):
2334 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2336 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2337 FvObj
.FvExtEntryData
.append(DataString
)
2339 if self
._Token
== 'FILE':
2341 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2342 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2344 if not self
._GetNextToken
():
2345 raise Warning("expected FV Extension Entry file path At Line ", self
.FileName
, self
.CurrentLineNumber
)
2347 FvObj
.FvExtEntryData
.append(self
._Token
)
2349 if not self
._IsToken
("}"):
2350 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2354 ## _GetAprioriSection() method
2356 # Get token statements
2358 # @param self The object pointer
2359 # @param FvObj for whom apriori is got
2360 # @param MacroDict dictionary used to replace macro
2361 # @retval True Successfully find apriori statement
2362 # @retval False Not able to find apriori statement
2364 def _GetAprioriSection(self
, FvObj
, MacroDict
= {}):
2365 if not self
._IsKeyword
("APRIORI"):
2368 if not self
._IsKeyword
("PEI") and not self
._IsKeyword
("DXE"):
2369 raise Warning("expected Apriori file type", self
.FileName
, self
.CurrentLineNumber
)
2370 AprType
= self
._Token
2372 if not self
._IsToken
("{"):
2373 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2375 AprSectionObj
= AprioriSection()
2376 AprSectionObj
.AprioriType
= AprType
2378 self
._GetDefineStatements
(AprSectionObj
)
2379 MacroDict
.update(AprSectionObj
.DefineVarDict
)
2382 IsInf
= self
._GetInfStatement
(AprSectionObj
)
2383 IsFile
= self
._GetFileStatement
(AprSectionObj
)
2384 if not IsInf
and not IsFile
:
2387 if not self
._IsToken
("}"):
2388 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2390 FvObj
.AprioriSectionList
.append(AprSectionObj
)
2393 def _ParseInfStatement(self
):
2394 if not self
._IsKeyword
("INF"):
2397 ffsInf
= FfsInfStatement()
2398 self
._GetInfOptions
(ffsInf
)
2400 if not self
._GetNextToken
():
2401 raise Warning("expected INF file path", self
.FileName
, self
.CurrentLineNumber
)
2402 ffsInf
.InfFileName
= self
._Token
2403 if not ffsInf
.InfFileName
.endswith('.inf'):
2404 raise Warning("expected .inf file path", self
.FileName
, self
.CurrentLineNumber
)
2406 ffsInf
.CurrentLineNum
= self
.CurrentLineNumber
2407 ffsInf
.CurrentLineContent
= self
._CurrentLine
()
2409 #Replace $(SAPCE) with real space
2410 ffsInf
.InfFileName
= ffsInf
.InfFileName
.replace('$(SPACE)', ' ')
2412 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
2413 #do case sensitive check for file path
2414 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2416 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2418 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
2419 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
2420 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2421 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
2423 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
2424 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
2426 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
2428 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
2430 if self
._IsToken
(TAB_VALUE_SPLIT
):
2431 if self
._IsKeyword
('RELOCS_STRIPPED'):
2432 ffsInf
.KeepReloc
= False
2433 elif self
._IsKeyword
('RELOCS_RETAINED'):
2434 ffsInf
.KeepReloc
= True
2436 raise Warning("Unknown reloc strip flag '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2439 ## _GetInfStatement() method
2441 # Get INF statements
2443 # @param self The object pointer
2444 # @param Obj for whom inf statement is got
2445 # @retval True Successfully find inf statement
2446 # @retval False Not able to find inf statement
2448 def _GetInfStatement(self
, Obj
, ForCapsule
=False):
2449 ffsInf
= self
._ParseInfStatement
()
2454 myCapsuleFfs
= CapsuleFfs()
2455 myCapsuleFfs
.Ffs
= ffsInf
2456 Obj
.CapsuleDataList
.append(myCapsuleFfs
)
2458 Obj
.FfsList
.append(ffsInf
)
2461 ## _GetInfOptions() method
2463 # Get options for INF
2465 # @param self The object pointer
2466 # @param FfsInfObj for whom option is got
2468 def _GetInfOptions(self
, FfsInfObj
):
2469 if self
._IsKeyword
("FILE_GUID"):
2470 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2471 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2472 if not self
._GetNextGuid
():
2473 raise Warning("expected GUID value", self
.FileName
, self
.CurrentLineNumber
)
2474 FfsInfObj
.OverrideGuid
= self
._Token
2476 if self
._IsKeyword
("RuleOverride"):
2477 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2478 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2479 if not self
._GetNextToken
():
2480 raise Warning("expected Rule name", self
.FileName
, self
.CurrentLineNumber
)
2481 FfsInfObj
.Rule
= self
._Token
2483 if self
._IsKeyword
("VERSION"):
2484 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2485 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2486 if not self
._GetNextToken
():
2487 raise Warning("expected Version", self
.FileName
, self
.CurrentLineNumber
)
2489 if self
._GetStringData
():
2490 FfsInfObj
.Version
= self
._Token
2492 if self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2493 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2494 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2495 if not self
._GetNextToken
():
2496 raise Warning("expected UI name", self
.FileName
, self
.CurrentLineNumber
)
2498 if self
._GetStringData
():
2499 FfsInfObj
.Ui
= self
._Token
2501 if self
._IsKeyword
("USE"):
2502 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2503 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2504 if not self
._GetNextToken
():
2505 raise Warning("expected ARCH name", self
.FileName
, self
.CurrentLineNumber
)
2506 FfsInfObj
.UseArch
= self
._Token
2509 if self
._GetNextToken
():
2510 p
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2511 if p
.match(self
._Token
) and p
.match(self
._Token
).span()[1] == len(self
._Token
):
2512 FfsInfObj
.KeyStringList
.append(self
._Token
)
2513 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2519 while self
._GetNextToken
():
2520 if not p
.match(self
._Token
):
2521 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2522 FfsInfObj
.KeyStringList
.append(self
._Token
)
2524 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2527 ## _GetFileStatement() method
2529 # Get FILE statements
2531 # @param self The object pointer
2532 # @param Obj for whom FILE statement is got
2533 # @param MacroDict dictionary used to replace macro
2534 # @retval True Successfully find FILE statement
2535 # @retval False Not able to find FILE statement
2537 def _GetFileStatement(self
, Obj
, ForCapsule
= False, MacroDict
= {}):
2538 if not self
._IsKeyword
("FILE"):
2541 if not self
._GetNextWord
():
2542 raise Warning("expected FFS type", self
.FileName
, self
.CurrentLineNumber
)
2544 if ForCapsule
and self
._Token
== 'DATA':
2549 FfsFileObj
= FileStatement()
2550 FfsFileObj
.FvFileType
= self
._Token
2552 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2553 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2555 if not self
._GetNextGuid
():
2556 if not self
._GetNextWord
():
2557 raise Warning("expected File GUID", self
.FileName
, self
.CurrentLineNumber
)
2558 if self
._Token
== 'PCD':
2559 if not self
._IsToken
("("):
2560 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
2561 PcdPair
= self
._GetNextPcdSettings
()
2562 if not self
._IsToken
(")"):
2563 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
2564 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
2566 FfsFileObj
.NameGuid
= self
._Token
2568 self
._GetFilePart
(FfsFileObj
, MacroDict
.copy())
2571 capsuleFfs
= CapsuleFfs()
2572 capsuleFfs
.Ffs
= FfsFileObj
2573 Obj
.CapsuleDataList
.append(capsuleFfs
)
2575 Obj
.FfsList
.append(FfsFileObj
)
2579 ## _FileCouldHaveRelocFlag() method
2581 # Check whether reloc strip flag can be set for a file type.
2583 # @param FileType The file type to check with
2584 # @retval True This type could have relocation strip flag
2585 # @retval False No way to have it
2588 def _FileCouldHaveRelocFlag (FileType
):
2589 if FileType
in (SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
, 'PEI_DXE_COMBO'):
2594 ## _SectionCouldHaveRelocFlag() method
2596 # Check whether reloc strip flag can be set for a section type.
2598 # @param SectionType The section type to check with
2599 # @retval True This type could have relocation strip flag
2600 # @retval False No way to have it
2603 def _SectionCouldHaveRelocFlag (SectionType
):
2604 if SectionType
in (BINARY_FILE_TYPE_TE
, BINARY_FILE_TYPE_PE32
):
2609 ## _GetFilePart() method
2611 # Get components for FILE statement
2613 # @param self The object pointer
2614 # @param FfsFileObj for whom component is got
2615 # @param MacroDict dictionary used to replace macro
2617 def _GetFilePart(self
, FfsFileObj
, MacroDict
= {}):
2618 self
._GetFileOpts
(FfsFileObj
)
2620 if not self
._IsToken
("{"):
2621 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2622 if self
._FileCouldHaveRelocFlag
(FfsFileObj
.FvFileType
):
2623 if self
._Token
== 'RELOCS_STRIPPED':
2624 FfsFileObj
.KeepReloc
= False
2626 FfsFileObj
.KeepReloc
= True
2628 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj
.FvFileType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
2630 if not self
._IsToken
("{"):
2631 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2633 if not self
._GetNextToken
():
2634 raise Warning("expected File name or section data", self
.FileName
, self
.CurrentLineNumber
)
2636 if self
._Token
== BINARY_FILE_TYPE_FV
:
2637 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2638 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2639 if not self
._GetNextToken
():
2640 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
2641 FfsFileObj
.FvName
= self
._Token
2643 elif self
._Token
== "FD":
2644 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2645 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2646 if not self
._GetNextToken
():
2647 raise Warning("expected FD name", self
.FileName
, self
.CurrentLineNumber
)
2648 FfsFileObj
.FdName
= self
._Token
2650 elif self
._Token
in (TAB_DEFINE
, "APRIORI", "SECTION"):
2652 self
._GetSectionData
(FfsFileObj
, MacroDict
)
2654 elif hasattr(FfsFileObj
, 'FvFileType') and FfsFileObj
.FvFileType
== 'RAW':
2656 self
._GetRAWData
(FfsFileObj
, MacroDict
)
2659 FfsFileObj
.CurrentLineNum
= self
.CurrentLineNumber
2660 FfsFileObj
.CurrentLineContent
= self
._CurrentLine
()
2661 FfsFileObj
.FileName
= self
._Token
.replace('$(SPACE)', ' ')
2662 self
._VerifyFile
(FfsFileObj
.FileName
)
2664 if not self
._IsToken
("}"):
2665 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2667 ## _GetRAWData() method
2669 # Get RAW data for FILE statement
2671 # @param self The object pointer
2672 # @param FfsFileObj for whom section is got
2673 # @param MacroDict dictionary used to replace macro
2675 def _GetRAWData(self
, FfsFileObj
, MacroDict
= {}):
2676 FfsFileObj
.FileName
= []
2677 FfsFileObj
.SubAlignment
= []
2680 if self
._GetAlignment
():
2681 if self
._Token
not in ALIGNMENTS
:
2682 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2683 #For FFS, Auto is default option same to ""
2684 if not self
._Token
== "Auto":
2685 AlignValue
= self
._Token
2686 if not self
._GetNextToken
():
2687 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2689 FileName
= self
._Token
.replace('$(SPACE)', ' ')
2692 raise Warning("expected Filename value", self
.FileName
, self
.CurrentLineNumber
)
2694 self
._VerifyFile
(FileName
)
2695 File
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
)
2696 FfsFileObj
.FileName
.append(File
.Path
)
2697 FfsFileObj
.SubAlignment
.append(AlignValue
)
2699 if self
._IsToken
("}"):
2703 if len(FfsFileObj
.SubAlignment
) == 1:
2704 FfsFileObj
.SubAlignment
= FfsFileObj
.SubAlignment
[0]
2705 if len(FfsFileObj
.FileName
) == 1:
2706 FfsFileObj
.FileName
= FfsFileObj
.FileName
[0]
2708 ## _GetFileOpts() method
2710 # Get options for FILE statement
2712 # @param self The object pointer
2713 # @param FfsFileObj for whom options is got
2715 def _GetFileOpts(self
, FfsFileObj
):
2716 if self
._GetNextToken
():
2717 if TokenFindPattern
.match(self
._Token
):
2718 FfsFileObj
.KeyStringList
.append(self
._Token
)
2719 if self
._IsToken
(TAB_COMMA_SPLIT
):
2720 while self
._GetNextToken
():
2721 if not TokenFindPattern
.match(self
._Token
):
2722 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2723 FfsFileObj
.KeyStringList
.append(self
._Token
)
2725 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2731 if self
._IsKeyword
("FIXED", True):
2732 FfsFileObj
.Fixed
= True
2734 if self
._IsKeyword
("CHECKSUM", True):
2735 FfsFileObj
.CheckSum
= True
2737 if self
._GetAlignment
():
2738 if self
._Token
not in ALIGNMENTS
:
2739 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2740 #For FFS, Auto is default option same to ""
2741 if not self
._Token
== "Auto":
2742 FfsFileObj
.Alignment
= self
._Token
2744 ## _GetAlignment() method
2746 # Return the alignment value
2748 # @param self The object pointer
2749 # @retval True Successfully find alignment
2750 # @retval False Not able to find alignment
2752 def _GetAlignment(self
):
2753 if self
._IsKeyword
("Align", True):
2754 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2755 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2757 if not self
._GetNextToken
():
2758 raise Warning("expected alignment value", self
.FileName
, self
.CurrentLineNumber
)
2763 ## _GetFilePart() method
2765 # Get section data for FILE statement
2767 # @param self The object pointer
2768 # @param FfsFileObj for whom section is got
2769 # @param MacroDict dictionary used to replace macro
2771 def _GetSectionData(self
, FfsFileObj
, MacroDict
= {}):
2773 Dict
.update(MacroDict
)
2775 self
._GetDefineStatements
(FfsFileObj
)
2777 Dict
.update(FfsFileObj
.DefineVarDict
)
2778 self
._GetAprioriSection
(FfsFileObj
, Dict
.copy())
2779 self
._GetAprioriSection
(FfsFileObj
, Dict
.copy())
2782 IsLeafSection
= self
._GetLeafSection
(FfsFileObj
, Dict
)
2783 IsEncapSection
= self
._GetEncapsulationSec
(FfsFileObj
)
2784 if not IsLeafSection
and not IsEncapSection
:
2787 ## _GetLeafSection() method
2789 # Get leaf section for Obj
2791 # @param self The object pointer
2792 # @param Obj for whom leaf section is got
2793 # @param MacroDict dictionary used to replace macro
2794 # @retval True Successfully find section statement
2795 # @retval False Not able to find section statement
2797 def _GetLeafSection(self
, Obj
, MacroDict
= {}):
2798 OldPos
= self
.GetFileBufferPos()
2800 if not self
._IsKeyword
("SECTION"):
2801 if len(Obj
.SectionList
) == 0:
2802 raise Warning("expected SECTION", self
.FileName
, self
.CurrentLineNumber
)
2807 if self
._GetAlignment
():
2808 if self
._Token
not in ALIGNMENTS
:
2809 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2810 AlignValue
= self
._Token
2813 if self
._IsKeyword
("BUILD_NUM"):
2814 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2815 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2817 if not self
._GetNextToken
():
2818 raise Warning("expected Build number value", self
.FileName
, self
.CurrentLineNumber
)
2820 BuildNum
= self
._Token
2822 if self
._IsKeyword
("VERSION"):
2823 if AlignValue
== 'Auto':
2824 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2825 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2826 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2827 if not self
._GetNextToken
():
2828 raise Warning("expected version", self
.FileName
, self
.CurrentLineNumber
)
2829 VerSectionObj
= VerSection()
2830 VerSectionObj
.Alignment
= AlignValue
2831 VerSectionObj
.BuildNum
= BuildNum
2832 if self
._GetStringData
():
2833 VerSectionObj
.StringData
= self
._Token
2835 VerSectionObj
.FileName
= self
._Token
2836 Obj
.SectionList
.append(VerSectionObj
)
2838 elif self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2839 if AlignValue
== 'Auto':
2840 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2841 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2842 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2843 if not self
._GetNextToken
():
2844 raise Warning("expected UI", self
.FileName
, self
.CurrentLineNumber
)
2845 UiSectionObj
= UiSection()
2846 UiSectionObj
.Alignment
= AlignValue
2847 if self
._GetStringData
():
2848 UiSectionObj
.StringData
= self
._Token
2850 UiSectionObj
.FileName
= self
._Token
2851 Obj
.SectionList
.append(UiSectionObj
)
2853 elif self
._IsKeyword
("FV_IMAGE"):
2854 if AlignValue
== 'Auto':
2855 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2856 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2857 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2858 if not self
._GetNextToken
():
2859 raise Warning("expected FV name or FV file path", self
.FileName
, self
.CurrentLineNumber
)
2861 FvName
= self
._Token
2864 if self
._IsToken
("{"):
2866 FvObj
.UiFvName
= FvName
.upper()
2867 self
._GetDefineStatements
(FvObj
)
2868 MacroDict
.update(FvObj
.DefineVarDict
)
2869 self
._GetBlockStatement
(FvObj
)
2870 self
._GetSetStatements
(FvObj
)
2871 self
._GetFvAlignment
(FvObj
)
2872 self
._GetFvAttributes
(FvObj
)
2873 self
._GetAprioriSection
(FvObj
, MacroDict
.copy())
2874 self
._GetAprioriSection
(FvObj
, MacroDict
.copy())
2877 IsInf
= self
._GetInfStatement
(FvObj
)
2878 IsFile
= self
._GetFileStatement
(FvObj
, MacroDict
.copy())
2879 if not IsInf
and not IsFile
:
2882 if not self
._IsToken
("}"):
2883 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
2885 FvImageSectionObj
= FvImageSection()
2886 FvImageSectionObj
.Alignment
= AlignValue
2887 if FvObj
is not None:
2888 FvImageSectionObj
.Fv
= FvObj
2889 FvImageSectionObj
.FvName
= None
2891 FvImageSectionObj
.FvName
= FvName
.upper()
2892 FvImageSectionObj
.FvFileName
= FvName
2894 Obj
.SectionList
.append(FvImageSectionObj
)
2896 elif self
._IsKeyword
("PEI_DEPEX_EXP") or self
._IsKeyword
("DXE_DEPEX_EXP") or self
._IsKeyword
("SMM_DEPEX_EXP"):
2897 if AlignValue
== 'Auto':
2898 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2899 DepexSectionObj
= DepexSection()
2900 DepexSectionObj
.Alignment
= AlignValue
2901 DepexSectionObj
.DepexType
= self
._Token
2903 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2904 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
2905 if not self
._IsToken
("{"):
2906 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2907 if not self
._SkipToToken
("}"):
2908 raise Warning("expected Depex expression ending '}'", self
.FileName
, self
.CurrentLineNumber
)
2910 DepexSectionObj
.Expression
= self
._SkippedChars
.rstrip('}')
2911 Obj
.SectionList
.append(DepexSectionObj
)
2914 if not self
._GetNextWord
():
2915 raise Warning("expected section type", self
.FileName
, self
.CurrentLineNumber
)
2917 # Encapsulation section appear, UndoToken and return
2918 if self
._Token
== "COMPRESS" or self
._Token
== "GUIDED":
2919 self
.SetFileBufferPos(OldPos
)
2922 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
,\
2923 BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX
):
2924 raise Warning("Unknown section type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2925 if AlignValue
== 'Auto'and (not self
._Token
== BINARY_FILE_TYPE_PE32
) and (not self
._Token
== BINARY_FILE_TYPE_TE
):
2926 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2929 DataSectionObj
= DataSection()
2930 DataSectionObj
.Alignment
= AlignValue
2931 DataSectionObj
.SecType
= self
._Token
2933 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2934 if self
._FileCouldHaveRelocFlag
(Obj
.FvFileType
) and self
._SectionCouldHaveRelocFlag
(DataSectionObj
.SecType
):
2935 if self
._Token
== 'RELOCS_STRIPPED':
2936 DataSectionObj
.KeepReloc
= False
2938 DataSectionObj
.KeepReloc
= True
2940 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
)
2942 if self
._IsToken
(TAB_EQUAL_SPLIT
):
2943 if not self
._GetNextToken
():
2944 raise Warning("expected section file path", self
.FileName
, self
.CurrentLineNumber
)
2945 DataSectionObj
.SectFileName
= self
._Token
2946 self
._VerifyFile
(DataSectionObj
.SectFileName
)
2948 if not self
._GetCglSection
(DataSectionObj
):
2951 Obj
.SectionList
.append(DataSectionObj
)
2957 # Check if file exists or not:
2958 # If current phase if GenFds, the file must exist;
2959 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
2960 # @param FileName: File path to be verified.
2962 def _VerifyFile(self
, FileName
):
2963 if FileName
.replace(TAB_WORKSPACE
, '').find('$') != -1:
2965 if not GlobalData
.gAutoGenPhase
or not self
._GetMacroValue
(TAB_DSC_DEFINES_OUTPUT_DIRECTORY
) in FileName
:
2966 ErrorCode
, ErrorInfo
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2968 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2970 ## _GetCglSection() method
2972 # Get compressed or GUIDed section for Obj
2974 # @param self The object pointer
2975 # @param Obj for whom leaf section is got
2976 # @param AlignValue alignment value for complex section
2977 # @retval True Successfully find section statement
2978 # @retval False Not able to find section statement
2980 def _GetCglSection(self
, Obj
, AlignValue
= None):
2982 if self
._IsKeyword
("COMPRESS"):
2984 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
2987 if not self
._IsToken
("{"):
2988 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
2990 CompressSectionObj
= CompressSection()
2991 CompressSectionObj
.Alignment
= AlignValue
2992 CompressSectionObj
.CompType
= type
2993 # Recursive sections...
2995 IsLeafSection
= self
._GetLeafSection
(CompressSectionObj
)
2996 IsEncapSection
= self
._GetEncapsulationSec
(CompressSectionObj
)
2997 if not IsLeafSection
and not IsEncapSection
:
3001 if not self
._IsToken
("}"):
3002 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3003 Obj
.SectionList
.append(CompressSectionObj
)
3006 # raise Warning("Compress type not known")
3010 elif self
._IsKeyword
("GUIDED"):
3012 if self
._GetNextGuid
():
3013 GuidValue
= self
._Token
3015 AttribDict
= self
._GetGuidAttrib
()
3016 if not self
._IsToken
("{"):
3017 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
3018 GuidSectionObj
= GuidSection()
3019 GuidSectionObj
.Alignment
= AlignValue
3020 GuidSectionObj
.NameGuid
= GuidValue
3021 GuidSectionObj
.SectionType
= "GUIDED"
3022 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
3023 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
3024 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
3025 # Recursive sections...
3027 IsLeafSection
= self
._GetLeafSection
(GuidSectionObj
)
3028 IsEncapSection
= self
._GetEncapsulationSec
(GuidSectionObj
)
3029 if not IsLeafSection
and not IsEncapSection
:
3032 if not self
._IsToken
("}"):
3033 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3034 Obj
.SectionList
.append(GuidSectionObj
)
3040 ## _GetGuidAttri() method
3042 # Get attributes for GUID section
3044 # @param self The object pointer
3045 # @retval AttribDict Dictionary of key-value pair of section attributes
3047 def _GetGuidAttrib(self
):
3049 AttribDict
["PROCESSING_REQUIRED"] = "NONE"
3050 AttribDict
["AUTH_STATUS_VALID"] = "NONE"
3051 AttribDict
["EXTRA_HEADER_SIZE"] = -1
3052 while self
._IsKeyword
("PROCESSING_REQUIRED") or self
._IsKeyword
("AUTH_STATUS_VALID") \
3053 or self
._IsKeyword
("EXTRA_HEADER_SIZE"):
3054 AttribKey
= self
._Token
3056 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3057 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3059 if not self
._GetNextToken
():
3060 raise Warning("expected TRUE(1)/FALSE(0)/Number", self
.FileName
, self
.CurrentLineNumber
)
3061 elif AttribKey
== "EXTRA_HEADER_SIZE":
3063 if self
._Token
[0:2].upper() == "0X":
3066 AttribDict
[AttribKey
] = int(self
._Token
, Base
)
3069 raise Warning("expected Number", self
.FileName
, self
.CurrentLineNumber
)
3070 elif self
._Token
.upper() not in ("TRUE", "FALSE", "1", "0"):
3071 raise Warning("expected TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
3072 AttribDict
[AttribKey
] = self
._Token
3076 ## _GetEncapsulationSec() method
3078 # Get encapsulation section for FILE
3080 # @param self The object pointer
3081 # @param FfsFile for whom section is got
3082 # @retval True Successfully find section statement
3083 # @retval False Not able to find section statement
3085 def _GetEncapsulationSec(self
, FfsFileObj
):
3086 OldPos
= self
.GetFileBufferPos()
3087 if not self
._IsKeyword
("SECTION"):
3088 if len(FfsFileObj
.SectionList
) == 0:
3089 raise Warning("expected SECTION", self
.FileName
, self
.CurrentLineNumber
)
3094 if self
._GetAlignment
():
3095 if self
._Token
not in ALIGNMENT_NOAUTO
:
3096 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3097 AlignValue
= self
._Token
3099 if not self
._GetCglSection
(FfsFileObj
, AlignValue
):
3100 self
.SetFileBufferPos(OldPos
)
3106 if not self
._GetNextToken
():
3108 S
= self
._Token
.upper()
3109 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FMPPAYLOAD."):
3110 self
.SectionParser(S
)
3115 self
._SkipToToken
("[FMPPAYLOAD.", True)
3116 FmpUiName
= self
._GetUiName
().upper()
3117 if FmpUiName
in self
.Profile
.FmpPayloadDict
:
3118 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName
, self
.FileName
, self
.CurrentLineNumber
)
3120 FmpData
= CapsulePayload()
3121 FmpData
.UiName
= FmpUiName
3123 if not self
._IsToken
(TAB_SECTION_END
):
3124 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
3126 if not self
._GetNextToken
():
3127 raise Warning("The FMP payload section is empty!", self
.FileName
, self
.CurrentLineNumber
)
3128 FmpKeyList
= ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']
3129 while self
._Token
in FmpKeyList
:
3131 FmpKeyList
.remove(Name
)
3132 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3133 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3134 if Name
== 'IMAGE_TYPE_ID':
3135 if not self
._GetNextGuid
():
3136 raise Warning("expected GUID value for IMAGE_TYPE_ID.", self
.FileName
, self
.CurrentLineNumber
)
3137 FmpData
.ImageTypeId
= self
._Token
3138 elif Name
== 'CERTIFICATE_GUID':
3139 if not self
._GetNextGuid
():
3140 raise Warning("expected GUID value for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3141 FmpData
.Certificate_Guid
= self
._Token
3142 if UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_RSA2048_SHA256_GUID
and UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_PKCS7_GUID
:
3143 raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3145 if not self
._GetNextToken
():
3146 raise Warning("expected value of %s" % Name
, self
.FileName
, self
.CurrentLineNumber
)
3148 if Name
== 'IMAGE_HEADER_INIT_VERSION':
3149 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3150 FmpData
.Version
= Value
3151 elif Name
== 'IMAGE_INDEX':
3152 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3153 FmpData
.ImageIndex
= Value
3154 elif Name
== 'HARDWARE_INSTANCE':
3155 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3156 FmpData
.HardwareInstance
= Value
3157 elif Name
== 'MONOTONIC_COUNT':
3158 if FdfParser
._Verify
(Name
, Value
, 'UINT64'):
3159 FmpData
.MonotonicCount
= Value
3160 if FmpData
.MonotonicCount
.upper().startswith('0X'):
3161 FmpData
.MonotonicCount
= (long)(FmpData
.MonotonicCount
, 16)
3163 FmpData
.MonotonicCount
= (long)(FmpData
.MonotonicCount
)
3164 if not self
._GetNextToken
():
3169 if (FmpData
.MonotonicCount
and not FmpData
.Certificate_Guid
) or (not FmpData
.MonotonicCount
and FmpData
.Certificate_Guid
):
3170 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")
3172 # Only the IMAGE_TYPE_ID is required item
3173 if FmpKeyList
and 'IMAGE_TYPE_ID' in FmpKeyList
:
3174 raise Warning("Missing keywords IMAGE_TYPE_ID in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3175 # get the Image file and Vendor code file
3176 self
._GetFMPCapsuleData
(FmpData
)
3177 if not FmpData
.ImageFile
:
3178 raise Warning("Missing image file in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3179 # check whether more than one Vendor code file
3180 if len(FmpData
.VendorCodeFile
) > 1:
3181 raise Warning("At most one Image file and one Vendor code file are allowed in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3182 self
.Profile
.FmpPayloadDict
[FmpUiName
] = FmpData
3185 ## _GetCapsule() method
3187 # Get capsule section contents and store its data into capsule list of self.Profile
3189 # @param self The object pointer
3190 # @retval True Successfully find a capsule
3191 # @retval False Not able to find a capsule
3193 def _GetCapsule(self
):
3194 if not self
._GetNextToken
():
3197 S
= self
._Token
.upper()
3198 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[CAPSULE."):
3199 self
.SectionParser(S
)
3204 if not self
._IsToken
("[CAPSULE.", True):
3205 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3206 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3207 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3208 raise Warning("expected [Capsule.]", self
.FileName
, self
.CurrentLineNumber
)
3210 CapsuleObj
= Capsule()
3212 CapsuleName
= self
._GetUiName
()
3214 raise Warning("expected capsule name", self
.FileName
, self
.CurrentLineNumber
)
3216 CapsuleObj
.UiCapsuleName
= CapsuleName
.upper()
3218 if not self
._IsToken
(TAB_SECTION_END
):
3219 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
3221 if self
._IsKeyword
("CREATE_FILE"):
3222 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3223 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3225 if not self
._GetNextToken
():
3226 raise Warning("expected file name", self
.FileName
, self
.CurrentLineNumber
)
3228 CapsuleObj
.CreateFile
= self
._Token
3230 self
._GetCapsuleStatements
(CapsuleObj
)
3231 self
.Profile
.CapsuleDict
[CapsuleObj
.UiCapsuleName
] = CapsuleObj
3234 ## _GetCapsuleStatements() method
3236 # Get statements for capsule
3238 # @param self The object pointer
3239 # @param Obj for whom statements are got
3241 def _GetCapsuleStatements(self
, Obj
):
3242 self
._GetCapsuleTokens
(Obj
)
3243 self
._GetDefineStatements
(Obj
)
3244 self
._GetSetStatements
(Obj
)
3245 self
._GetCapsuleData
(Obj
)
3247 ## _GetCapsuleTokens() method
3249 # Get token statements for capsule
3251 # @param self The object pointer
3252 # @param Obj for whom token statements are got
3254 def _GetCapsuleTokens(self
, Obj
):
3255 if not self
._GetNextToken
():
3257 while self
._Token
in ("CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"):
3258 Name
= self
._Token
.strip()
3259 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3260 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3261 if not self
._GetNextToken
():
3262 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
3263 if Name
== 'CAPSULE_FLAGS':
3264 if not self
._Token
in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
3265 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3266 Value
= self
._Token
.strip()
3267 while self
._IsToken
(TAB_COMMA_SPLIT
):
3268 Value
+= TAB_COMMA_SPLIT
3269 if not self
._GetNextToken
():
3270 raise Warning("expected value", self
.FileName
, self
.CurrentLineNumber
)
3271 if not self
._Token
in ("PersistAcrossReset", "PopulateSystemTable", "InitiateReset"):
3272 raise Warning("expected PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3273 Value
+= self
._Token
.strip()
3274 elif Name
== 'OEM_CAPSULE_FLAGS':
3275 Value
= self
._Token
.strip()
3276 if not Value
.upper().startswith('0X'):
3277 raise Warning("expected hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3279 Value
= int(Value
, 0)
3281 raise Warning("expected hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3282 if not 0x0000 <= Value
<= 0xFFFF:
3283 raise Warning("expected hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3284 Value
= self
._Token
.strip()
3286 Value
= self
._Token
.strip()
3287 Obj
.TokensDict
[Name
] = Value
3288 if not self
._GetNextToken
():
3292 ## _GetCapsuleData() method
3294 # Get capsule data for capsule
3296 # @param self The object pointer
3297 # @param Obj for whom capsule data are got
3299 def _GetCapsuleData(self
, Obj
):
3301 IsInf
= self
._GetInfStatement
(Obj
, True)
3302 IsFile
= self
._GetFileStatement
(Obj
, True)
3303 IsFv
= self
._GetFvStatement
(Obj
)
3304 IsFd
= self
._GetFdStatement
(Obj
)
3305 IsAnyFile
= self
._GetAnyFileStatement
(Obj
)
3306 IsAfile
= self
._GetAfileStatement
(Obj
)
3307 IsFmp
= self
._GetFmpStatement
(Obj
)
3308 if not (IsInf
or IsFile
or IsFv
or IsFd
or IsAnyFile
or IsAfile
or IsFmp
):
3311 ## _GetFMPCapsuleData() method
3313 # Get capsule data for FMP capsule
3315 # @param self The object pointer
3316 # @param Obj for whom capsule data are got
3318 def _GetFMPCapsuleData(self
, Obj
):
3320 IsFv
= self
._GetFvStatement
(Obj
, True)
3321 IsFd
= self
._GetFdStatement
(Obj
, True)
3322 IsAnyFile
= self
._GetAnyFileStatement
(Obj
, True)
3323 if not (IsFv
or IsFd
or IsAnyFile
):
3326 ## _GetFvStatement() method
3328 # Get FV for capsule
3330 # @param self The object pointer
3331 # @param CapsuleObj for whom FV is got
3332 # @retval True Successfully find a FV statement
3333 # @retval False Not able to find a FV statement
3335 def _GetFvStatement(self
, CapsuleObj
, FMPCapsule
= False):
3336 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3339 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3340 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3342 if not self
._GetNextToken
():
3343 raise Warning("expected FV name", self
.FileName
, self
.CurrentLineNumber
)
3345 if self
._Token
.upper() not in self
.Profile
.FvDict
:
3346 raise Warning("FV name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3348 myCapsuleFv
= CapsuleFv()
3349 myCapsuleFv
.FvName
= self
._Token
3351 if not CapsuleObj
.ImageFile
:
3352 CapsuleObj
.ImageFile
.append(myCapsuleFv
)
3354 CapsuleObj
.VendorCodeFile
.append(myCapsuleFv
)
3356 CapsuleObj
.CapsuleDataList
.append(myCapsuleFv
)
3359 ## _GetFdStatement() method
3361 # Get FD for capsule
3363 # @param self The object pointer
3364 # @param CapsuleObj for whom FD is got
3365 # @retval True Successfully find a FD statement
3366 # @retval False Not able to find a FD statement
3368 def _GetFdStatement(self
, CapsuleObj
, FMPCapsule
= False):
3369 if not self
._IsKeyword
("FD"):
3372 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3373 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3375 if not self
._GetNextToken
():
3376 raise Warning("expected FD name", self
.FileName
, self
.CurrentLineNumber
)
3378 if self
._Token
.upper() not in self
.Profile
.FdDict
:
3379 raise Warning("FD name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3381 myCapsuleFd
= CapsuleFd()
3382 myCapsuleFd
.FdName
= self
._Token
3384 if not CapsuleObj
.ImageFile
:
3385 CapsuleObj
.ImageFile
.append(myCapsuleFd
)
3387 CapsuleObj
.VendorCodeFile
.append(myCapsuleFd
)
3389 CapsuleObj
.CapsuleDataList
.append(myCapsuleFd
)
3392 def _GetFmpStatement(self
, CapsuleObj
):
3393 if not self
._IsKeyword
("FMP_PAYLOAD"):
3394 if not self
._IsKeyword
("FMP"):
3397 if not self
._IsKeyword
("PAYLOAD"):
3401 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3402 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3404 if not self
._GetNextToken
():
3405 raise Warning("expected payload name after FMP_PAYLOAD =", self
.FileName
, self
.CurrentLineNumber
)
3406 Payload
= self
._Token
.upper()
3407 if Payload
not in self
.Profile
.FmpPayloadDict
:
3408 raise Warning("This FMP Payload does not exist: %s" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3409 CapsuleObj
.FmpPayloadList
.append(self
.Profile
.FmpPayloadDict
[Payload
])
3412 def _ParseRawFileStatement(self
):
3413 if not self
._IsKeyword
("FILE"):
3416 if not self
._IsKeyword
("DATA"):
3420 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3421 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3423 if not self
._GetNextToken
():
3424 raise Warning("expected File name", self
.FileName
, self
.CurrentLineNumber
)
3426 AnyFileName
= self
._Token
3427 self
._VerifyFile
(AnyFileName
)
3429 if not os
.path
.isabs(AnyFileName
):
3430 AnyFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, AnyFileName
)
3434 ## _GetAnyFileStatement() method
3436 # Get AnyFile for capsule
3438 # @param self The object pointer
3439 # @param CapsuleObj for whom AnyFile is got
3440 # @retval True Successfully find a Anyfile statement
3441 # @retval False Not able to find a AnyFile statement
3443 def _GetAnyFileStatement(self
, CapsuleObj
, FMPCapsule
= False):
3444 AnyFileName
= self
._ParseRawFileStatement
()
3448 myCapsuleAnyFile
= CapsuleAnyFile()
3449 myCapsuleAnyFile
.FileName
= AnyFileName
3451 if not CapsuleObj
.ImageFile
:
3452 CapsuleObj
.ImageFile
.append(myCapsuleAnyFile
)
3454 CapsuleObj
.VendorCodeFile
.append(myCapsuleAnyFile
)
3456 CapsuleObj
.CapsuleDataList
.append(myCapsuleAnyFile
)
3459 ## _GetAfileStatement() method
3461 # Get Afile for capsule
3463 # @param self The object pointer
3464 # @param CapsuleObj for whom Afile is got
3465 # @retval True Successfully find a Afile statement
3466 # @retval False Not able to find a Afile statement
3468 def _GetAfileStatement(self
, CapsuleObj
):
3469 if not self
._IsKeyword
("APPEND"):
3472 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3473 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3475 if not self
._GetNextToken
():
3476 raise Warning("expected Afile name", self
.FileName
, self
.CurrentLineNumber
)
3478 AfileName
= self
._Token
3479 AfileBaseName
= os
.path
.basename(AfileName
)
3481 if os
.path
.splitext(AfileBaseName
)[1] not in [".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"]:
3482 raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \
3483 self
.FileName
, self
.CurrentLineNumber
)
3485 if not os
.path
.isabs(AfileName
):
3486 AfileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(AfileName
)
3487 self
._VerifyFile
(AfileName
)
3489 if not os
.path
.exists(AfileName
):
3490 raise Warning('%s does not exist' % AfileName
, self
.FileName
, self
.CurrentLineNumber
)
3494 myCapsuleAfile
= CapsuleAfile()
3495 myCapsuleAfile
.FileName
= AfileName
3496 CapsuleObj
.CapsuleDataList
.append(myCapsuleAfile
)
3499 ## _GetRule() method
3501 # Get Rule section contents and store its data into rule list of self.Profile
3503 # @param self The object pointer
3504 # @retval True Successfully find a Rule
3505 # @retval False Not able to find a Rule
3508 if not self
._GetNextToken
():
3511 S
= self
._Token
.upper()
3512 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[RULE."):
3513 self
.SectionParser(S
)
3517 if not self
._IsToken
("[Rule.", True):
3518 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3519 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3520 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3521 raise Warning("expected [Rule.]", self
.FileName
, self
.CurrentLineNumber
)
3523 if not self
._SkipToToken
(TAB_SPLIT
):
3524 raise Warning("expected '.'", self
.FileName
, self
.CurrentLineNumber
)
3526 Arch
= self
._SkippedChars
.rstrip(TAB_SPLIT
)
3527 if Arch
.upper() not in ARCH_SET_FULL
:
3528 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
3530 ModuleType
= self
._GetModuleType
()
3533 if self
._IsToken
(TAB_SPLIT
):
3534 if not self
._GetNextWord
():
3535 raise Warning("expected template name", self
.FileName
, self
.CurrentLineNumber
)
3536 TemplateName
= self
._Token
3538 if not self
._IsToken
(TAB_SECTION_END
):
3539 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
3541 RuleObj
= self
._GetRuleFileStatements
()
3542 RuleObj
.Arch
= Arch
.upper()
3543 RuleObj
.ModuleType
= ModuleType
3544 RuleObj
.TemplateName
= TemplateName
3545 if TemplateName
== '':
3546 self
.Profile
.RuleDict
['RULE' + \
3550 ModuleType
.upper() ] = RuleObj
3552 self
.Profile
.RuleDict
['RULE' + \
3556 ModuleType
.upper() + \
3558 TemplateName
.upper() ] = RuleObj
3561 ## _GetModuleType() method
3563 # Return the module type
3565 # @param self The object pointer
3566 # @retval string module type
3568 def _GetModuleType(self
):
3569 if not self
._GetNextWord
():
3570 raise Warning("expected Module type", self
.FileName
, self
.CurrentLineNumber
)
3571 if self
._Token
.upper() not in (SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
, SUP_MODULE_DXE_CORE
, \
3572 SUP_MODULE_DXE_DRIVER
, SUP_MODULE_DXE_SAL_DRIVER
, \
3573 SUP_MODULE_DXE_SMM_DRIVER
, SUP_MODULE_DXE_RUNTIME_DRIVER
, \
3574 SUP_MODULE_UEFI_DRIVER
, SUP_MODULE_UEFI_APPLICATION
, SUP_MODULE_USER_DEFINED
, TAB_DEFAULT
, SUP_MODULE_BASE
, \
3575 EDK_COMPONENT_TYPE_SECURITY_CORE
, EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER
, EDK_COMPONENT_TYPE_PIC_PEIM
, EDK_COMPONENT_TYPE_RELOCATABLE_PEIM
, \
3576 "PE32_PEIM", EDK_COMPONENT_TYPE_BS_DRIVER
, EDK_COMPONENT_TYPE_RT_DRIVER
, EDK_COMPONENT_TYPE_SAL_RT_DRIVER
, EDK_COMPONENT_TYPE_APPLICATION
, "ACPITABLE", SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
, SUP_MODULE_MM_CORE_STANDALONE
):
3577 raise Warning("Unknown Module type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3580 ## _GetFileExtension() method
3582 # Return the file extension
3584 # @param self The object pointer
3585 # @retval string file name extension
3587 def _GetFileExtension(self
):
3588 if not self
._IsToken
(TAB_SPLIT
):
3589 raise Warning("expected '.'", self
.FileName
, self
.CurrentLineNumber
)
3592 if self
._GetNextToken
():
3593 if FileExtensionPattern
.match(self
._Token
):
3595 return TAB_SPLIT
+ Ext
3597 raise Warning("Unknown file extension '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3600 raise Warning("expected file extension", self
.FileName
, self
.CurrentLineNumber
)
3602 ## _GetRuleFileStatement() method
3606 # @param self The object pointer
3607 # @retval Rule Rule object
3609 def _GetRuleFileStatements(self
):
3610 if not self
._IsKeyword
("FILE"):
3611 raise Warning("expected FILE", self
.FileName
, self
.CurrentLineNumber
)
3613 if not self
._GetNextWord
():
3614 raise Warning("expected FFS type", self
.FileName
, self
.CurrentLineNumber
)
3616 Type
= self
._Token
.strip().upper()
3617 if Type
not in ("RAW", "FREEFORM", SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,\
3618 "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE
, EDK_COMPONENT_TYPE_APPLICATION
, "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
, SUP_MODULE_MM_CORE_STANDALONE
):
3619 raise Warning("Unknown FV type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3621 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3622 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3624 if not self
._IsKeyword
("$(NAMED_GUID)"):
3625 if not self
._GetNextWord
():
3626 raise Warning("expected $(NAMED_GUID)", self
.FileName
, self
.CurrentLineNumber
)
3627 if self
._Token
== 'PCD':
3628 if not self
._IsToken
("("):
3629 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
3630 PcdPair
= self
._GetNextPcdSettings
()
3631 if not self
._IsToken
(")"):
3632 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
3633 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3635 NameGuid
= self
._Token
3638 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3639 if self
._FileCouldHaveRelocFlag
(Type
):
3640 if self
._Token
== 'RELOCS_STRIPPED':
3645 raise Warning("File type %s could not have reloc strip flag%d" % (Type
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3648 if self
._GetNextToken
():
3649 if TokenFindPattern
.match(self
._Token
):
3650 KeyStringList
.append(self
._Token
)
3651 if self
._IsToken
(TAB_COMMA_SPLIT
):
3652 while self
._GetNextToken
():
3653 if not TokenFindPattern
.match(self
._Token
):
3654 raise Warning("expected KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
3655 KeyStringList
.append(self
._Token
)
3657 if not self
._IsToken
(TAB_COMMA_SPLIT
):
3665 if self
._IsKeyword
("Fixed", True):
3669 if self
._IsKeyword
("CheckSum", True):
3673 if self
._GetAlignment
():
3674 if self
._Token
not in ALIGNMENTS
:
3675 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3676 #For FFS, Auto is default option same to ""
3677 if not self
._Token
== "Auto":
3678 AlignValue
= self
._Token
3680 if self
._IsToken
("{"):
3681 # Complex file rule expected
3682 NewRule
= RuleComplexFile()
3683 NewRule
.FvFileType
= Type
3684 NewRule
.NameGuid
= NameGuid
3685 NewRule
.Alignment
= AlignValue
3686 NewRule
.CheckSum
= CheckSum
3687 NewRule
.Fixed
= Fixed
3688 NewRule
.KeyStringList
= KeyStringList
3689 if KeepReloc
is not None:
3690 NewRule
.KeepReloc
= KeepReloc
3693 IsEncapsulate
= self
._GetRuleEncapsulationSection
(NewRule
)
3694 IsLeaf
= self
._GetEfiSection
(NewRule
)
3695 if not IsEncapsulate
and not IsLeaf
:
3698 if not self
._IsToken
("}"):
3699 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3704 # Simple file rule expected
3705 if not self
._GetNextWord
():
3706 raise Warning("expected leaf section type", self
.FileName
, self
.CurrentLineNumber
)
3708 SectionName
= self
._Token
3710 if SectionName
not in ("COMPAT16", BINARY_FILE_TYPE_PE32
, BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,\
3711 BINARY_FILE_TYPE_UI
, BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX
):
3712 raise Warning("Unknown leaf section name '%s'" % SectionName
, self
.FileName
, self
.CurrentLineNumber
)
3715 if self
._IsKeyword
("Fixed", True):
3718 if self
._IsKeyword
("CheckSum", True):
3722 if self
._GetAlignment
():
3723 if self
._Token
not in ALIGNMENTS
:
3724 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3725 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3726 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3727 SectAlignment
= self
._Token
3730 if self
._IsToken
(TAB_VALUE_SPLIT
):
3731 Ext
= self
._GetFileExtension
()
3732 elif not self
._GetNextToken
():
3733 raise Warning("expected File name", self
.FileName
, self
.CurrentLineNumber
)
3735 NewRule
= RuleSimpleFile()
3736 NewRule
.SectionType
= SectionName
3737 NewRule
.FvFileType
= Type
3738 NewRule
.NameGuid
= NameGuid
3739 NewRule
.Alignment
= AlignValue
3740 NewRule
.SectAlignment
= SectAlignment
3741 NewRule
.CheckSum
= CheckSum
3742 NewRule
.Fixed
= Fixed
3743 NewRule
.KeyStringList
= KeyStringList
3744 if KeepReloc
is not None:
3745 NewRule
.KeepReloc
= KeepReloc
3746 NewRule
.FileExtension
= Ext
3747 NewRule
.FileName
= self
._Token
3750 ## _GetEfiSection() method
3752 # Get section list for Rule
3754 # @param self The object pointer
3755 # @param Obj for whom section is got
3756 # @retval True Successfully find section statement
3757 # @retval False Not able to find section statement
3759 def _GetEfiSection(self
, Obj
):
3760 OldPos
= self
.GetFileBufferPos()
3761 if not self
._GetNextWord
():
3763 SectionName
= self
._Token
3765 if SectionName
not in ("COMPAT16", BINARY_FILE_TYPE_PE32
, BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,\
3766 BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
, BINARY_FILE_TYPE_SMM_DEPEX
):
3770 if SectionName
== "FV_IMAGE":
3771 FvImageSectionObj
= FvImageSection()
3772 if self
._IsKeyword
("FV_IMAGE"):
3774 if self
._IsToken
("{"):
3776 self
._GetDefineStatements
(FvObj
)
3777 self
._GetBlockStatement
(FvObj
)
3778 self
._GetSetStatements
(FvObj
)
3779 self
._GetFvAlignment
(FvObj
)
3780 self
._GetFvAttributes
(FvObj
)
3781 self
._GetAprioriSection
(FvObj
)
3782 self
._GetAprioriSection
(FvObj
)
3785 IsInf
= self
._GetInfStatement
(FvObj
)
3786 IsFile
= self
._GetFileStatement
(FvObj
)
3787 if not IsInf
and not IsFile
:
3790 if not self
._IsToken
("}"):
3791 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
3792 FvImageSectionObj
.Fv
= FvObj
3793 FvImageSectionObj
.FvName
= None
3796 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3797 raise Warning("expected 'FV'", self
.FileName
, self
.CurrentLineNumber
)
3798 FvImageSectionObj
.FvFileType
= self
._Token
3800 if self
._GetAlignment
():
3801 if self
._Token
not in ALIGNMENT_NOAUTO
:
3802 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3803 FvImageSectionObj
.Alignment
= self
._Token
3805 if self
._IsToken
(TAB_VALUE_SPLIT
):
3806 FvImageSectionObj
.FvFileExtension
= self
._GetFileExtension
()
3807 elif self
._GetNextToken
():
3808 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
,\
3809 BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
, BINARY_FILE_TYPE_SMM_DEPEX
):
3810 FvImageSectionObj
.FvFileName
= self
._Token
3814 raise Warning("expected FV file name", self
.FileName
, self
.CurrentLineNumber
)
3816 Obj
.SectionList
.append(FvImageSectionObj
)
3819 EfiSectionObj
= EfiSection()
3820 EfiSectionObj
.SectionType
= SectionName
3822 if not self
._GetNextToken
():
3823 raise Warning("expected file type", self
.FileName
, self
.CurrentLineNumber
)
3825 if self
._Token
== "STRING":
3826 if not self
._RuleSectionCouldHaveString
(EfiSectionObj
.SectionType
):
3827 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3829 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3830 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3832 if not self
._GetNextToken
():
3833 raise Warning("expected Quoted String", self
.FileName
, self
.CurrentLineNumber
)
3835 if self
._GetStringData
():
3836 EfiSectionObj
.StringData
= self
._Token
3838 if self
._IsKeyword
("BUILD_NUM"):
3839 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3840 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3842 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3843 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3844 if not self
._GetNextToken
():
3845 raise Warning("expected Build number", self
.FileName
, self
.CurrentLineNumber
)
3846 EfiSectionObj
.BuildNum
= self
._Token
3849 EfiSectionObj
.FileType
= self
._Token
3850 self
._CheckRuleSectionFileType
(EfiSectionObj
.SectionType
, EfiSectionObj
.FileType
)
3852 if self
._IsKeyword
("Optional"):
3853 if not self
._RuleSectionCouldBeOptional
(EfiSectionObj
.SectionType
):
3854 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3855 EfiSectionObj
.Optional
= True
3857 if self
._IsKeyword
("BUILD_NUM"):
3858 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3859 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3861 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3862 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
3863 if not self
._GetNextToken
():
3864 raise Warning("expected Build number", self
.FileName
, self
.CurrentLineNumber
)
3865 EfiSectionObj
.BuildNum
= self
._Token
3867 if self
._GetAlignment
():
3868 if self
._Token
not in ALIGNMENTS
:
3869 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3870 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3871 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3872 EfiSectionObj
.Alignment
= self
._Token
3874 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3875 if self
._SectionCouldHaveRelocFlag
(EfiSectionObj
.SectionType
):
3876 if self
._Token
== 'RELOCS_STRIPPED':
3877 EfiSectionObj
.KeepReloc
= False
3879 EfiSectionObj
.KeepReloc
= True
3880 if Obj
.KeepReloc
is not None and Obj
.KeepReloc
!= EfiSectionObj
.KeepReloc
:
3881 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3883 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3886 if self
._IsToken
(TAB_VALUE_SPLIT
):
3887 EfiSectionObj
.FileExtension
= self
._GetFileExtension
()
3888 elif self
._GetNextToken
():
3889 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
,\
3890 BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
, BINARY_FILE_TYPE_SMM_DEPEX
):
3892 if self
._Token
.startswith('PCD'):
3896 if self
._Token
== 'PCD':
3897 if not self
._IsToken
("("):
3898 raise Warning("expected '('", self
.FileName
, self
.CurrentLineNumber
)
3899 PcdPair
= self
._GetNextPcdSettings
()
3900 if not self
._IsToken
(")"):
3901 raise Warning("expected ')'", self
.FileName
, self
.CurrentLineNumber
)
3902 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3904 EfiSectionObj
.FileName
= self
._Token
3909 raise Warning("expected section file name", self
.FileName
, self
.CurrentLineNumber
)
3911 Obj
.SectionList
.append(EfiSectionObj
)
3914 ## _RuleSectionCouldBeOptional() method
3916 # Get whether a section could be optional
3918 # @param SectionType The section type to check
3919 # @retval True section could be optional
3920 # @retval False section never optional
3923 def _RuleSectionCouldBeOptional(SectionType
):
3924 if SectionType
in (BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "RAW", BINARY_FILE_TYPE_SMM_DEPEX
):
3929 ## _RuleSectionCouldHaveBuildNum() method
3931 # Get whether a section could have build number information
3933 # @param SectionType The section type to check
3934 # @retval True section could have build number information
3935 # @retval False section never have build number information
3938 def _RuleSectionCouldHaveBuildNum(SectionType
):
3939 if SectionType
in ("VERSION"):
3944 ## _RuleSectionCouldHaveString() method
3946 # Get whether a section could have string
3948 # @param SectionType The section type to check
3949 # @retval True section could have string
3950 # @retval False section never have string
3953 def _RuleSectionCouldHaveString(SectionType
):
3954 if SectionType
in (BINARY_FILE_TYPE_UI
, "VERSION"):
3959 ## _CheckRuleSectionFileType() method
3961 # Get whether a section matches a file type
3963 # @param self The object pointer
3964 # @param SectionType The section type to check
3965 # @param FileType The file type to check
3967 def _CheckRuleSectionFileType(self
, SectionType
, FileType
):
3968 if SectionType
== "COMPAT16":
3969 if FileType
not in ("COMPAT16", "SEC_COMPAT16"):
3970 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3971 elif SectionType
== BINARY_FILE_TYPE_PE32
:
3972 if FileType
not in (BINARY_FILE_TYPE_PE32
, "SEC_PE32"):
3973 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3974 elif SectionType
== BINARY_FILE_TYPE_PIC
:
3975 if FileType
not in (BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_PIC
):
3976 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3977 elif SectionType
== BINARY_FILE_TYPE_TE
:
3978 if FileType
not in (BINARY_FILE_TYPE_TE
, "SEC_TE"):
3979 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3980 elif SectionType
== "RAW":
3981 if FileType
not in (BINARY_FILE_TYPE_BIN
, "SEC_BIN", "RAW", "ASL", "ACPI"):
3982 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3983 elif SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
or SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
3984 if FileType
not in (BINARY_FILE_TYPE_DXE_DEPEX
, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX
):
3985 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3986 elif SectionType
== BINARY_FILE_TYPE_UI
:
3987 if FileType
not in (BINARY_FILE_TYPE_UI
, "SEC_UI"):
3988 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3989 elif SectionType
== "VERSION":
3990 if FileType
not in ("VERSION", "SEC_VERSION"):
3991 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3992 elif SectionType
== BINARY_FILE_TYPE_PEI_DEPEX
:
3993 if FileType
not in (BINARY_FILE_TYPE_PEI_DEPEX
, "SEC_PEI_DEPEX"):
3994 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3995 elif SectionType
== BINARY_FILE_TYPE_GUID
:
3996 if FileType
not in (BINARY_FILE_TYPE_PE32
, "SEC_GUID"):
3997 raise Warning("Incorrect section file type '%s'" % FileType
, self
.FileName
, self
.CurrentLineNumber
)
3999 ## _GetRuleEncapsulationSection() method
4001 # Get encapsulation section for Rule
4003 # @param self The object pointer
4004 # @param theRule for whom section is got
4005 # @retval True Successfully find section statement
4006 # @retval False Not able to find section statement
4008 def _GetRuleEncapsulationSection(self
, theRule
):
4009 if self
._IsKeyword
("COMPRESS"):
4011 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
4014 if not self
._IsToken
("{"):
4015 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
4017 CompressSectionObj
= CompressSection()
4019 CompressSectionObj
.CompType
= Type
4020 # Recursive sections...
4022 IsEncapsulate
= self
._GetRuleEncapsulationSection
(CompressSectionObj
)
4023 IsLeaf
= self
._GetEfiSection
(CompressSectionObj
)
4024 if not IsEncapsulate
and not IsLeaf
:
4027 if not self
._IsToken
("}"):
4028 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
4029 theRule
.SectionList
.append(CompressSectionObj
)
4033 elif self
._IsKeyword
("GUIDED"):
4035 if self
._GetNextGuid
():
4036 GuidValue
= self
._Token
4038 if self
._IsKeyword
("$(NAMED_GUID)"):
4039 GuidValue
= self
._Token
4041 AttribDict
= self
._GetGuidAttrib
()
4043 if not self
._IsToken
("{"):
4044 raise Warning("expected '{'", self
.FileName
, self
.CurrentLineNumber
)
4045 GuidSectionObj
= GuidSection()
4046 GuidSectionObj
.NameGuid
= GuidValue
4047 GuidSectionObj
.SectionType
= "GUIDED"
4048 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
4049 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
4050 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
4054 IsEncapsulate
= self
._GetRuleEncapsulationSection
(GuidSectionObj
)
4055 IsLeaf
= self
._GetEfiSection
(GuidSectionObj
)
4056 if not IsEncapsulate
and not IsLeaf
:
4059 if not self
._IsToken
("}"):
4060 raise Warning("expected '}'", self
.FileName
, self
.CurrentLineNumber
)
4061 theRule
.SectionList
.append(GuidSectionObj
)
4069 # Get VTF section contents and store its data into VTF list of self.Profile
4071 # @param self The object pointer
4072 # @retval True Successfully find a VTF
4073 # @retval False Not able to find a VTF
4076 if not self
._GetNextToken
():
4079 S
= self
._Token
.upper()
4080 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[VTF."):
4081 self
.SectionParser(S
)
4086 if not self
._IsToken
("[VTF.", True):
4087 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4088 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
4089 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
4090 raise Warning("expected [VTF.]", self
.FileName
, self
.CurrentLineNumber
)
4092 if not self
._SkipToToken
(TAB_SPLIT
):
4093 raise Warning("expected '.'", self
.FileName
, self
.CurrentLineNumber
)
4095 Arch
= self
._SkippedChars
.rstrip(TAB_SPLIT
).upper()
4096 if Arch
not in {TAB_ARCH_IA32
, TAB_ARCH_X64
, TAB_ARCH_IPF
, TAB_ARCH_ARM
, TAB_ARCH_AARCH64
}:
4097 raise Warning("Unknown Arch '%s'" % Arch
, self
.FileName
, self
.CurrentLineNumber
)
4099 if not self
._GetNextWord
():
4100 raise Warning("expected VTF name", self
.FileName
, self
.CurrentLineNumber
)
4101 Name
= self
._Token
.upper()
4104 VtfObj
.UiName
= Name
4105 VtfObj
.KeyArch
= Arch
4107 if self
._IsToken
(TAB_COMMA_SPLIT
):
4108 if not self
._GetNextWord
():
4109 raise Warning("expected Arch list", self
.FileName
, self
.CurrentLineNumber
)
4110 if self
._Token
.upper() not in (TAB_ARCH_IA32
, TAB_ARCH_X64
, TAB_ARCH_IPF
, TAB_ARCH_ARM
, TAB_ARCH_AARCH64
):
4111 raise Warning("Unknown Arch '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4112 VtfObj
.ArchList
= self
._Token
.upper()
4114 if not self
._IsToken
(TAB_SECTION_END
):
4115 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
4117 if self
._IsKeyword
("IA32_RST_BIN"):
4118 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4119 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4121 if not self
._GetNextToken
():
4122 raise Warning("expected Reset file", self
.FileName
, self
.CurrentLineNumber
)
4124 VtfObj
.ResetBin
= self
._Token
4125 if VtfObj
.ResetBin
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4126 #check for file path
4127 ErrorCode
, ErrorInfo
= PathClass(NormPath(VtfObj
.ResetBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4129 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4131 while self
._GetComponentStatement
(VtfObj
):
4134 self
.Profile
.VtfList
.append(VtfObj
)
4137 ## _GetComponentStatement() method
4139 # Get components in VTF
4141 # @param self The object pointer
4142 # @param VtfObj for whom component is got
4143 # @retval True Successfully find a component
4144 # @retval False Not able to find a component
4146 def _GetComponentStatement(self
, VtfObj
):
4147 if not self
._IsKeyword
("COMP_NAME"):
4150 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4151 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4153 if not self
._GetNextWord
():
4154 raise Warning("expected Component Name", self
.FileName
, self
.CurrentLineNumber
)
4156 CompStatementObj
= ComponentStatement()
4157 CompStatementObj
.CompName
= self
._Token
4159 if not self
._IsKeyword
("COMP_LOC"):
4160 raise Warning("expected COMP_LOC", self
.FileName
, self
.CurrentLineNumber
)
4162 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4163 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4165 CompStatementObj
.CompLoc
= ""
4166 if self
._GetNextWord
():
4167 CompStatementObj
.CompLoc
= self
._Token
4168 if self
._IsToken
(TAB_VALUE_SPLIT
):
4169 if not self
._GetNextWord
():
4170 raise Warning("Expected Region Name", self
.FileName
, self
.CurrentLineNumber
)
4172 if self
._Token
not in ("F", "N", "S"): #, "H", "L", "PH", "PL"): not support
4173 raise Warning("Unknown location type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4175 CompStatementObj
.FilePos
= self
._Token
4177 self
.CurrentLineNumber
+= 1
4178 self
.CurrentOffsetWithinLine
= 0
4180 if not self
._IsKeyword
("COMP_TYPE"):
4181 raise Warning("expected COMP_TYPE", self
.FileName
, self
.CurrentLineNumber
)
4183 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4184 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4186 if not self
._GetNextToken
():
4187 raise Warning("expected Component type", self
.FileName
, self
.CurrentLineNumber
)
4188 if self
._Token
not in ("FIT", "PAL_B", "PAL_A", "OEM"):
4189 if not self
._Token
.startswith("0x") or len(self
._Token
) < 3 or len(self
._Token
) > 4 or \
4190 not self
._Token
[2] in hexdigits
or not self
._Token
[-1] in hexdigits
:
4191 raise Warning("Unknown location type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4192 CompStatementObj
.CompType
= self
._Token
4194 if not self
._IsKeyword
("COMP_VER"):
4195 raise Warning("expected COMP_VER", self
.FileName
, self
.CurrentLineNumber
)
4197 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4198 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4200 if not self
._GetNextToken
():
4201 raise Warning("expected Component version", self
.FileName
, self
.CurrentLineNumber
)
4203 Pattern
= compile('-$|[0-9a-fA-F]{1,2}\.[0-9a-fA-F]{1,2}$', DOTALL
)
4204 if Pattern
.match(self
._Token
) is None:
4205 raise Warning("Unknown version format '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4206 CompStatementObj
.CompVer
= self
._Token
4208 if not self
._IsKeyword
("COMP_CS"):
4209 raise Warning("expected COMP_CS", self
.FileName
, self
.CurrentLineNumber
)
4211 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4212 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4214 if not self
._GetNextToken
():
4215 raise Warning("expected Component CS", self
.FileName
, self
.CurrentLineNumber
)
4216 if self
._Token
not in ("1", "0"):
4217 raise Warning("Unknown Component CS '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4218 CompStatementObj
.CompCs
= self
._Token
4221 if not self
._IsKeyword
("COMP_BIN"):
4222 raise Warning("expected COMP_BIN", self
.FileName
, self
.CurrentLineNumber
)
4224 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4225 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4227 if not self
._GetNextToken
():
4228 raise Warning("expected Component file", self
.FileName
, self
.CurrentLineNumber
)
4230 CompStatementObj
.CompBin
= self
._Token
4231 if CompStatementObj
.CompBin
!= '-' and CompStatementObj
.CompBin
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4232 #check for file path
4233 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompBin
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4235 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4237 if not self
._IsKeyword
("COMP_SYM"):
4238 raise Warning("expected COMP_SYM", self
.FileName
, self
.CurrentLineNumber
)
4240 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4241 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4243 if not self
._GetNextToken
():
4244 raise Warning("expected Component symbol file", self
.FileName
, self
.CurrentLineNumber
)
4246 CompStatementObj
.CompSym
= self
._Token
4247 if CompStatementObj
.CompSym
!= '-' and CompStatementObj
.CompSym
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4248 #check for file path
4249 ErrorCode
, ErrorInfo
= PathClass(NormPath(CompStatementObj
.CompSym
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4251 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4253 if not self
._IsKeyword
("COMP_SIZE"):
4254 raise Warning("expected COMP_SIZE", self
.FileName
, self
.CurrentLineNumber
)
4256 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4257 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4259 if self
._IsToken
("-"):
4260 CompStatementObj
.CompSize
= self
._Token
4261 elif self
._GetNextDecimalNumber
():
4262 CompStatementObj
.CompSize
= self
._Token
4263 elif self
._GetNextHexNumber
():
4264 CompStatementObj
.CompSize
= self
._Token
4266 raise Warning("Unknown size '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4268 VtfObj
.ComponentStatementList
.append(CompStatementObj
)
4271 ## _GetOptionRom() method
4273 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
4275 # @param self The object pointer
4276 # @retval True Successfully find a OptionROM
4277 # @retval False Not able to find a OptionROM
4279 def _GetOptionRom(self
):
4280 if not self
._GetNextToken
():
4283 S
= self
._Token
.upper()
4284 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[OPTIONROM."):
4285 self
.SectionParser(S
)
4290 if not self
._IsToken
("[OptionRom.", True):
4291 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4293 OptRomName
= self
._GetUiName
()
4295 if not self
._IsToken
(TAB_SECTION_END
):
4296 raise Warning("expected ']'", self
.FileName
, self
.CurrentLineNumber
)
4298 OptRomObj
= OPTIONROM(OptRomName
)
4299 self
.Profile
.OptRomDict
[OptRomName
] = OptRomObj
4302 isInf
= self
._GetOptRomInfStatement
(OptRomObj
)
4303 isFile
= self
._GetOptRomFileStatement
(OptRomObj
)
4304 if not isInf
and not isFile
:
4309 ## _GetOptRomInfStatement() method
4311 # Get INF statements
4313 # @param self The object pointer
4314 # @param Obj for whom inf statement is got
4315 # @retval True Successfully find inf statement
4316 # @retval False Not able to find inf statement
4318 def _GetOptRomInfStatement(self
, Obj
):
4319 if not self
._IsKeyword
("INF"):
4322 ffsInf
= OptRomInfStatement()
4323 self
._GetInfOptions
(ffsInf
)
4325 if not self
._GetNextToken
():
4326 raise Warning("expected INF file path", self
.FileName
, self
.CurrentLineNumber
)
4327 ffsInf
.InfFileName
= self
._Token
4328 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4329 #check for file path
4330 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4332 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4334 if not ffsInf
.InfFileName
in self
.Profile
.InfList
:
4335 self
.Profile
.InfList
.append(ffsInf
.InfFileName
)
4336 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4337 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
4339 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
4340 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
4342 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
4344 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
4347 self
._GetOptRomOverrides
(ffsInf
)
4349 Obj
.FfsList
.append(ffsInf
)
4352 ## _GetOptRomOverrides() method
4354 # Get overrides for OptROM INF & FILE
4356 # @param self The object pointer
4357 # @param FfsInfObj for whom overrides is got
4359 def _GetOptRomOverrides(self
, Obj
):
4360 if self
._IsToken
('{'):
4361 Overrides
= OverrideAttribs()
4363 if self
._IsKeyword
("PCI_VENDOR_ID"):
4364 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4365 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4366 if not self
._GetNextHexNumber
():
4367 raise Warning("expected Hex vendor id", self
.FileName
, self
.CurrentLineNumber
)
4368 Overrides
.PciVendorId
= self
._Token
4371 if self
._IsKeyword
("PCI_CLASS_CODE"):
4372 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4373 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4374 if not self
._GetNextHexNumber
():
4375 raise Warning("expected Hex class code", self
.FileName
, self
.CurrentLineNumber
)
4376 Overrides
.PciClassCode
= self
._Token
4379 if self
._IsKeyword
("PCI_DEVICE_ID"):
4380 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4381 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4382 if not self
._GetNextHexNumber
():
4383 raise Warning("expected Hex device id", self
.FileName
, self
.CurrentLineNumber
)
4385 Overrides
.PciDeviceId
= self
._Token
4388 if self
._IsKeyword
("PCI_REVISION"):
4389 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4390 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4391 if not self
._GetNextHexNumber
():
4392 raise Warning("expected Hex revision", self
.FileName
, self
.CurrentLineNumber
)
4393 Overrides
.PciRevision
= self
._Token
4396 if self
._IsKeyword
("PCI_COMPRESS"):
4397 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4398 raise Warning("expected '='", self
.FileName
, self
.CurrentLineNumber
)
4399 if not self
._GetNextToken
():
4400 raise Warning("expected TRUE/FALSE for compress", self
.FileName
, self
.CurrentLineNumber
)
4401 Overrides
.NeedCompress
= self
._Token
.upper() == 'TRUE'
4404 if self
._IsToken
("}"):
4407 EdkLogger
.error("FdfParser", FORMAT_INVALID
, File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
4409 Obj
.OverrideAttribs
= Overrides
4411 ## _GetOptRomFileStatement() method
4413 # Get FILE statements
4415 # @param self The object pointer
4416 # @param Obj for whom FILE statement is got
4417 # @retval True Successfully find FILE statement
4418 # @retval False Not able to find FILE statement
4420 def _GetOptRomFileStatement(self
, Obj
):
4421 if not self
._IsKeyword
("FILE"):
4424 FfsFileObj
= OptRomFileStatement()
4426 if not self
._IsKeyword
("EFI") and not self
._IsKeyword
(BINARY_FILE_TYPE_BIN
):
4427 raise Warning("expected Binary type (EFI/BIN)", self
.FileName
, self
.CurrentLineNumber
)
4428 FfsFileObj
.FileType
= self
._Token
4430 if not self
._GetNextToken
():
4431 raise Warning("expected File path", self
.FileName
, self
.CurrentLineNumber
)
4432 FfsFileObj
.FileName
= self
._Token
4433 if FfsFileObj
.FileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4434 #check for file path
4435 ErrorCode
, ErrorInfo
= PathClass(NormPath(FfsFileObj
.FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4437 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4439 if FfsFileObj
.FileType
== 'EFI':
4440 self
._GetOptRomOverrides
(FfsFileObj
)
4442 Obj
.FfsList
.append(FfsFileObj
)
4446 ## _GetCapInFd() method
4448 # Get Cap list contained in FD
4450 # @param self The object pointer
4451 # @param FdName FD name
4452 # @retval CapList List of Capsule in FD
4454 def _GetCapInFd (self
, FdName
):
4456 if FdName
.upper() in self
.Profile
.FdDict
:
4457 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4458 for elementRegion
in FdObj
.RegionList
:
4459 if elementRegion
.RegionType
== 'CAPSULE':
4460 for elementRegionData
in elementRegion
.RegionDataList
:
4461 if elementRegionData
.endswith(".cap"):
4463 if elementRegionData
is not None and elementRegionData
.upper() not in CapList
:
4464 CapList
.append(elementRegionData
.upper())
4467 ## _GetReferencedFdCapTuple() method
4469 # Get FV and FD list referenced by a capsule image
4471 # @param self The object pointer
4472 # @param CapObj Capsule section to be searched
4473 # @param RefFdList referenced FD by section
4474 # @param RefFvList referenced FV by section
4476 def _GetReferencedFdCapTuple(self
, CapObj
, RefFdList
= [], RefFvList
= []):
4477 for CapsuleDataObj
in CapObj
.CapsuleDataList
:
4478 if hasattr(CapsuleDataObj
, 'FvName') and CapsuleDataObj
.FvName
is not None and CapsuleDataObj
.FvName
.upper() not in RefFvList
:
4479 RefFvList
.append (CapsuleDataObj
.FvName
.upper())
4480 elif hasattr(CapsuleDataObj
, 'FdName') and CapsuleDataObj
.FdName
is not None and CapsuleDataObj
.FdName
.upper() not in RefFdList
:
4481 RefFdList
.append (CapsuleDataObj
.FdName
.upper())
4482 elif CapsuleDataObj
.Ffs
is not None:
4483 if isinstance(CapsuleDataObj
.Ffs
, FileStatement
):
4484 if CapsuleDataObj
.Ffs
.FvName
is not None and CapsuleDataObj
.Ffs
.FvName
.upper() not in RefFvList
:
4485 RefFvList
.append(CapsuleDataObj
.Ffs
.FvName
.upper())
4486 elif CapsuleDataObj
.Ffs
.FdName
is not None and CapsuleDataObj
.Ffs
.FdName
.upper() not in RefFdList
:
4487 RefFdList
.append(CapsuleDataObj
.Ffs
.FdName
.upper())
4489 self
._GetReferencedFdFvTupleFromSection
(CapsuleDataObj
.Ffs
, RefFdList
, RefFvList
)
4491 ## _GetFvInFd() method
4493 # Get FV list contained in FD
4495 # @param self The object pointer
4496 # @param FdName FD name
4497 # @retval FvList list of FV in FD
4499 def _GetFvInFd (self
, FdName
):
4501 if FdName
.upper() in self
.Profile
.FdDict
:
4502 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4503 for elementRegion
in FdObj
.RegionList
:
4504 if elementRegion
.RegionType
== BINARY_FILE_TYPE_FV
:
4505 for elementRegionData
in elementRegion
.RegionDataList
:
4506 if elementRegionData
.endswith(".fv"):
4508 if elementRegionData
is not None and elementRegionData
.upper() not in FvList
:
4509 FvList
.append(elementRegionData
.upper())
4512 ## _GetReferencedFdFvTuple() method
4514 # Get FD and FV list referenced by a FFS file
4516 # @param self The object pointer
4517 # @param FfsFile contains sections to be searched
4518 # @param RefFdList referenced FD by section
4519 # @param RefFvList referenced FV by section
4521 def _GetReferencedFdFvTuple(self
, FvObj
, RefFdList
= [], RefFvList
= []):
4522 for FfsObj
in FvObj
.FfsList
:
4523 if isinstance(FfsObj
, FileStatement
):
4524 if FfsObj
.FvName
is not None and FfsObj
.FvName
.upper() not in RefFvList
:
4525 RefFvList
.append(FfsObj
.FvName
.upper())
4526 elif FfsObj
.FdName
is not None and FfsObj
.FdName
.upper() not in RefFdList
:
4527 RefFdList
.append(FfsObj
.FdName
.upper())
4529 self
._GetReferencedFdFvTupleFromSection
(FfsObj
, RefFdList
, RefFvList
)
4531 ## _GetReferencedFdFvTupleFromSection() method
4533 # Get FD and FV list referenced by a FFS section
4535 # @param self The object pointer
4536 # @param FfsFile contains sections to be searched
4537 # @param FdList referenced FD by section
4538 # @param FvList referenced FV by section
4540 def _GetReferencedFdFvTupleFromSection(self
, FfsFile
, FdList
= [], FvList
= []):
4542 SectionStack
.extend(FfsFile
.SectionList
)
4543 while SectionStack
!= []:
4544 SectionObj
= SectionStack
.pop()
4545 if isinstance(SectionObj
, FvImageSection
):
4546 if SectionObj
.FvName
is not None and SectionObj
.FvName
.upper() not in FvList
:
4547 FvList
.append(SectionObj
.FvName
.upper())
4548 if SectionObj
.Fv
is not None and SectionObj
.Fv
.UiFvName
is not None and SectionObj
.Fv
.UiFvName
.upper() not in FvList
:
4549 FvList
.append(SectionObj
.Fv
.UiFvName
.upper())
4550 self
._GetReferencedFdFvTuple
(SectionObj
.Fv
, FdList
, FvList
)
4552 if isinstance(SectionObj
, CompressSection
) or isinstance(SectionObj
, GuidSection
):
4553 SectionStack
.extend(SectionObj
.SectionList
)
4555 ## CycleReferenceCheck() method
4557 # Check whether cycle reference exists in FDF
4559 # @param self The object pointer
4560 # @retval True cycle reference exists
4561 # @retval False Not exists cycle reference
4563 def CycleReferenceCheck(self
):
4565 # Check the cycle between FV and FD image
4567 MaxLength
= len (self
.Profile
.FvDict
)
4568 for FvName
in self
.Profile
.FvDict
:
4569 LogStr
= "\nCycle Reference Checking for FV: %s\n" % FvName
4571 RefFvStack
.append(FvName
)
4575 while RefFvStack
and Index
< MaxLength
:
4577 FvNameFromStack
= RefFvStack
.pop()
4578 if FvNameFromStack
.upper() in self
.Profile
.FvDict
:
4579 FvObj
= self
.Profile
.FvDict
[FvNameFromStack
.upper()]
4585 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4587 for RefFdName
in RefFdList
:
4588 if RefFdName
in FdAnalyzedList
:
4591 LogStr
+= "FV %s contains FD %s\n" % (FvNameFromStack
, RefFdName
)
4592 FvInFdList
= self
._GetFvInFd
(RefFdName
)
4593 if FvInFdList
!= []:
4594 for FvNameInFd
in FvInFdList
:
4595 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4596 if FvNameInFd
not in RefFvStack
:
4597 RefFvStack
.append(FvNameInFd
)
4599 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4600 EdkLogger
.info(LogStr
)
4602 FdAnalyzedList
.append(RefFdName
)
4604 for RefFvName
in RefFvList
:
4605 LogStr
+= "FV %s contains FV %s\n" % (FvNameFromStack
, RefFvName
)
4606 if RefFvName
not in RefFvStack
:
4607 RefFvStack
.append(RefFvName
)
4609 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4610 EdkLogger
.info(LogStr
)
4614 # Check the cycle between Capsule and FD image
4616 MaxLength
= len (self
.Profile
.CapsuleDict
)
4617 for CapName
in self
.Profile
.CapsuleDict
:
4619 # Capsule image to be checked.
4621 LogStr
= "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4623 RefCapStack
.append(CapName
)
4628 while RefCapStack
!= [] and Index
< MaxLength
:
4630 CapNameFromStack
= RefCapStack
.pop()
4631 if CapNameFromStack
.upper() in self
.Profile
.CapsuleDict
:
4632 CapObj
= self
.Profile
.CapsuleDict
[CapNameFromStack
.upper()]
4638 self
._GetReferencedFdCapTuple
(CapObj
, RefFdList
, RefFvList
)
4642 while FvListLength
< len (RefFvList
) or FdListLength
< len (RefFdList
):
4643 for RefFdName
in RefFdList
:
4644 if RefFdName
in FdAnalyzedList
:
4647 LogStr
+= "Capsule %s contains FD %s\n" % (CapNameFromStack
, RefFdName
)
4648 CapInFdList
= self
._GetCapInFd
(RefFdName
)
4649 if CapInFdList
!= []:
4650 for CapNameInFd
in CapInFdList
:
4651 LogStr
+= "FD %s contains Capsule %s\n" % (RefFdName
, CapNameInFd
)
4652 if CapNameInFd
not in RefCapStack
:
4653 RefCapStack
.append(CapNameInFd
)
4655 if CapName
in RefCapStack
or CapNameFromStack
in RefCapStack
:
4656 EdkLogger
.info(LogStr
)
4659 FvInFdList
= self
._GetFvInFd
(RefFdName
)
4660 if FvInFdList
!= []:
4661 for FvNameInFd
in FvInFdList
:
4662 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4663 if FvNameInFd
not in RefFvList
:
4664 RefFvList
.append(FvNameInFd
)
4666 FdAnalyzedList
.append(RefFdName
)
4668 # the number of the parsed FV and FD image
4670 FvListLength
= len (RefFvList
)
4671 FdListLength
= len (RefFdList
)
4672 for RefFvName
in RefFvList
:
4673 if RefFvName
in FvAnalyzedList
:
4675 LogStr
+= "Capsule %s contains FV %s\n" % (CapNameFromStack
, RefFvName
)
4676 if RefFvName
.upper() in self
.Profile
.FvDict
:
4677 FvObj
= self
.Profile
.FvDict
[RefFvName
.upper()]
4680 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4681 FvAnalyzedList
.append(RefFvName
)
4685 def GetAllIncludedFile (self
):
4686 global AllIncludeFileList
4687 return AllIncludeFileList
4689 if __name__
== "__main__":
4692 test_file
= sys
.argv
[1]
4693 except IndexError as v
:
4694 print("Usage: %s filename" % sys
.argv
[0])
4697 parser
= FdfParser(test_file
)
4700 parser
.CycleReferenceCheck()
4701 except Warning as X
: