4 # Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
5 # Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
7 # SPDX-License-Identifier: BSD-2-Clause-Patent
13 from __future__
import print_function
14 from __future__
import absolute_import
15 from re
import compile, DOTALL
16 from string
import hexdigits
19 from Common
.BuildToolError
import *
20 from Common
import EdkLogger
21 from Common
.Misc
import PathClass
, tdict
, ProcessDuplicatedInf
, GuidStructureStringToGuidString
22 from Common
.StringUtils
import NormPath
, ReplaceMacro
23 from Common
import GlobalData
24 from Common
.Expression
import *
25 from Common
.DataType
import *
26 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
27 import Common
.LongFilePathOs
as os
28 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
29 from Common
.RangeExpression
import RangeExpression
30 from collections
import OrderedDict
33 from .Region
import Region
35 from .AprioriSection
import AprioriSection
36 from .FfsInfStatement
import FfsInfStatement
37 from .FfsFileStatement
import FileStatement
38 from .VerSection
import VerSection
39 from .UiSection
import UiSection
40 from .FvImageSection
import FvImageSection
41 from .DataSection
import DataSection
42 from .DepexSection
import DepexSection
43 from .CompressSection
import CompressSection
44 from .GuidSection
import GuidSection
45 from .SubTypeGuidSection
import SubTypeGuidSection
46 from .Capsule
import EFI_CERT_TYPE_PKCS7_GUID
, EFI_CERT_TYPE_RSA2048_SHA256_GUID
, Capsule
47 from .CapsuleData
import CapsuleFfs
, CapsulePayload
, CapsuleFv
, CapsuleFd
, CapsuleAnyFile
, CapsuleAfile
48 from .RuleComplexFile
import RuleComplexFile
49 from .RuleSimpleFile
import RuleSimpleFile
50 from .EfiSection
import EfiSection
51 from .OptionRom
import OPTIONROM
52 from .OptRomInfStatement
import OptRomInfStatement
, OverrideAttribs
53 from .OptRomFileStatement
import OptRomFileStatement
54 from .GenFdsGlobalVariable
import GenFdsGlobalVariable
58 T_CHAR_DOUBLE_QUOTE
= '\"'
59 T_CHAR_SINGLE_QUOTE
= '\''
62 SEPARATORS
= {TAB_EQUAL_SPLIT
, TAB_VALUE_SPLIT
, TAB_COMMA_SPLIT
, '{', T_CHAR_BRACE_R
}
63 ALIGNMENTS
= {"Auto", "8", "16", "32", "64", "128", "512", "1K", "4K", "32K", "64K", "128K",
64 "256K", "512K", "1M", "2M", "4M", "8M", "16M"}
65 ALIGNMENT_NOAUTO
= ALIGNMENTS
- {"Auto"}
66 CR_LB_SET
= {T_CHAR_CR
, TAB_LINE_BREAK
}
68 RegionSizePattern
= compile("\s*(?P<base>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<size>(?:0x|0X)?[a-fA-F0-9]+)\s*")
69 RegionSizeGuidPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*\|\s*(?P<size>\w+\.\w+[\.\w\[\]]*)\s*")
70 RegionOffsetPcdPattern
= compile("\s*(?P<base>\w+\.\w+[\.\w\[\]]*)\s*$")
71 ShortcutPcdPattern
= compile("\s*\w+\s*=\s*(?P<value>(?:0x|0X)?[a-fA-F0-9]+)\s*\|\s*(?P<name>\w+\.\w+)\s*")
72 BaseAddrValuePattern
= compile('^0[xX][0-9a-fA-F]+')
73 FileExtensionPattern
= compile(r
'([a-zA-Z][a-zA-Z0-9]*)')
74 TokenFindPattern
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
75 AllIncludeFileList
= []
77 # Get the closest parent
78 def GetParentAtLine (Line
):
79 for Profile
in AllIncludeFileList
:
80 if Profile
.IsLineInFile(Line
):
85 def IsValidInclude (File
, Line
):
86 for Profile
in AllIncludeFileList
:
87 if Profile
.IsLineInFile(Line
) and Profile
.FileName
== File
:
92 def GetRealFileLine (File
, Line
):
94 for Profile
in AllIncludeFileList
:
95 if Profile
.IsLineInFile(Line
):
96 return Profile
.GetLineInFile(Line
)
97 elif Line
>= Profile
.InsertStartLineNumber
and Profile
.Level
== 1:
98 InsertedLines
+= Profile
.GetTotalLines()
100 return (File
, Line
- InsertedLines
)
102 ## The exception class that used to report error messages when parsing FDF
104 # Currently the "ToolName" is set to be "FdfParser".
106 class Warning (Exception):
109 # @param self The object pointer
110 # @param Str The message to record
111 # @param File The FDF name
112 # @param Line The Line number that error occurs
114 def __init__(self
, Str
, File
= None, Line
= None):
115 FileLineTuple
= GetRealFileLine(File
, Line
)
116 self
.FileName
= FileLineTuple
[0]
117 self
.LineNumber
= FileLineTuple
[1]
118 self
.OriginalLineNumber
= Line
120 self
.ToolName
= 'FdfParser'
125 # helper functions to facilitate consistency in warnings
126 # each function is for a different common warning
128 def Expected(Str
, File
, Line
):
129 return Warning("expected {}".format(Str
), File
, Line
)
131 def ExpectedEquals(File
, Line
):
132 return Warning.Expected("'='", File
, Line
)
134 def ExpectedCurlyOpen(File
, Line
):
135 return Warning.Expected("'{'", File
, Line
)
137 def ExpectedCurlyClose(File
, Line
):
138 return Warning.Expected("'}'", File
, Line
)
140 def ExpectedBracketClose(File
, Line
):
141 return Warning.Expected("']'", File
, Line
)
143 ## The Include file content class that used to record file data when parsing include file
145 # May raise Exception when opening file.
147 class IncludeFileProfile
:
150 # @param self The object pointer
151 # @param FileName The file that to be parsed
153 def __init__(self
, FileName
):
154 self
.FileName
= FileName
155 self
.FileLinesList
= []
157 with
open(FileName
, "r") as fsock
:
158 self
.FileLinesList
= fsock
.readlines()
159 for index
, line
in enumerate(self
.FileLinesList
):
160 if not line
.endswith(TAB_LINE_BREAK
):
161 self
.FileLinesList
[index
] += TAB_LINE_BREAK
163 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
165 self
.InsertStartLineNumber
= None
166 self
.InsertAdjust
= 0
167 self
.IncludeFileList
= []
168 self
.Level
= 1 # first level include file
170 def GetTotalLines(self
):
171 TotalLines
= self
.InsertAdjust
+ len(self
.FileLinesList
)
173 for Profile
in self
.IncludeFileList
:
174 TotalLines
+= Profile
.GetTotalLines()
178 def IsLineInFile(self
, Line
):
179 if Line
>= self
.InsertStartLineNumber
and Line
< self
.InsertStartLineNumber
+ self
.GetTotalLines():
184 def GetLineInFile(self
, Line
):
185 if not self
.IsLineInFile (Line
):
186 return (self
.FileName
, -1)
188 InsertedLines
= self
.InsertStartLineNumber
190 for Profile
in self
.IncludeFileList
:
191 if Profile
.IsLineInFile(Line
):
192 return Profile
.GetLineInFile(Line
)
193 elif Line
>= Profile
.InsertStartLineNumber
:
194 InsertedLines
+= Profile
.GetTotalLines()
196 return (self
.FileName
, Line
- InsertedLines
+ 1)
198 ## The FDF content class that used to record file data when parsing FDF
200 # May raise Exception when opening file.
205 # @param self The object pointer
206 # @param FileName The file that to be parsed
208 def __init__(self
, FileName
):
209 self
.FileLinesList
= []
211 with
open(FileName
, "r") as fsock
:
212 self
.FileLinesList
= fsock
.readlines()
215 EdkLogger
.error("FdfParser", FILE_OPEN_FAILURE
, ExtraData
=FileName
)
217 self
.FileName
= FileName
218 self
.PcdDict
= OrderedDict()
219 self
.PcdLocalDict
= OrderedDict()
221 self
.InfDict
= {'ArchTBD':[]}
222 # ECC will use this Dict and List information
223 self
.PcdFileLineDict
= {}
224 self
.InfFileLineList
= []
227 self
.FdNameNotSet
= False
229 self
.CapsuleDict
= {}
232 self
.FmpPayloadDict
= {}
234 ## The syntax parser for FDF
236 # PreprocessFile method should be called prior to ParseFile
237 # CycleReferenceCheck method can detect cycles in FDF contents
239 # GetNext*** procedures mean these procedures will get next token first, then make judgement.
240 # Get*** procedures mean these procedures will make judgement on current token only.
245 # @param self The object pointer
246 # @param FileName The file that to be parsed
248 def __init__(self
, FileName
):
249 self
.Profile
= FileProfile(FileName
)
250 self
.FileName
= FileName
251 self
.CurrentLineNumber
= 1
252 self
.CurrentOffsetWithinLine
= 0
253 self
.CurrentFdName
= None
254 self
.CurrentFvName
= None
256 self
._SkippedChars
= ""
257 GlobalData
.gFdfParser
= self
259 # Used to section info
260 self
._CurSection
= []
261 # Key: [section name, UI name, arch]
262 # Value: {MACRO_NAME: MACRO_VALUE}
263 self
._MacroDict
= tdict(True, 3)
264 self
._PcdDict
= OrderedDict()
266 self
._WipeOffArea
= []
267 if GenFdsGlobalVariable
.WorkSpaceDir
== '':
268 GenFdsGlobalVariable
.WorkSpaceDir
= os
.getenv("WORKSPACE")
270 ## _SkipWhiteSpace() method
272 # Skip white spaces from current char.
274 # @param self The object pointer
276 def _SkipWhiteSpace(self
):
277 while not self
._EndOfFile
():
278 if self
._CurrentChar
() in {TAB_PRINTCHAR_NUL
, T_CHAR_CR
, TAB_LINE_BREAK
, TAB_SPACE_SPLIT
, T_CHAR_TAB
}:
279 self
._SkippedChars
+= str(self
._CurrentChar
())
285 ## _EndOfFile() method
287 # Judge current buffer pos is at file end
289 # @param self The object pointer
290 # @retval True Current File buffer position is at file end
291 # @retval False Current File buffer position is NOT at file end
293 def _EndOfFile(self
):
294 NumberOfLines
= len(self
.Profile
.FileLinesList
)
295 SizeOfLastLine
= len(self
.Profile
.FileLinesList
[-1])
296 if self
.CurrentLineNumber
== NumberOfLines
and self
.CurrentOffsetWithinLine
>= SizeOfLastLine
- 1:
298 if self
.CurrentLineNumber
> NumberOfLines
:
302 ## _EndOfLine() method
304 # Judge current buffer pos is at line end
306 # @param self The object pointer
307 # @retval True Current File buffer position is at line end
308 # @retval False Current File buffer position is NOT at line end
310 def _EndOfLine(self
):
311 if self
.CurrentLineNumber
> len(self
.Profile
.FileLinesList
):
313 SizeOfCurrentLine
= len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
314 if self
.CurrentOffsetWithinLine
>= SizeOfCurrentLine
:
320 # Reset file data buffer to the initial state
322 # @param self The object pointer
323 # @param DestLine Optional new destination line number.
324 # @param DestOffset Optional new destination offset.
326 def Rewind(self
, DestLine
= 1, DestOffset
= 0):
327 self
.CurrentLineNumber
= DestLine
328 self
.CurrentOffsetWithinLine
= DestOffset
330 ## _UndoOneChar() method
332 # Go back one char in the file buffer
334 # @param self The object pointer
335 # @retval True Successfully go back one char
336 # @retval False Not able to go back one char as file beginning reached
338 def _UndoOneChar(self
):
339 if self
.CurrentLineNumber
== 1 and self
.CurrentOffsetWithinLine
== 0:
341 elif self
.CurrentOffsetWithinLine
== 0:
342 self
.CurrentLineNumber
-= 1
343 self
.CurrentOffsetWithinLine
= len(self
._CurrentLine
()) - 1
345 self
.CurrentOffsetWithinLine
-= 1
348 ## _GetOneChar() method
350 # Move forward one char in the file buffer
352 # @param self The object pointer
354 def _GetOneChar(self
):
355 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
356 self
.CurrentLineNumber
+= 1
357 self
.CurrentOffsetWithinLine
= 0
359 self
.CurrentOffsetWithinLine
+= 1
361 ## _CurrentChar() method
363 # Get the char pointed to by the file buffer pointer
365 # @param self The object pointer
366 # @retval Char Current char
368 def _CurrentChar(self
):
369 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
]
371 ## _NextChar() method
373 # Get the one char pass the char pointed to by the file buffer pointer
375 # @param self The object pointer
376 # @retval Char Next char
379 if self
.CurrentOffsetWithinLine
== len(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]) - 1:
380 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
][0]
381 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
+ 1]
383 ## _SetCurrentCharValue() method
385 # Modify the value of current char
387 # @param self The object pointer
388 # @param Value The new value of current char
390 def _SetCurrentCharValue(self
, Value
):
391 self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
] = Value
393 ## _CurrentLine() method
395 # Get the list that contains current line contents
397 # @param self The object pointer
398 # @retval List current line contents
400 def _CurrentLine(self
):
401 return self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
403 def _StringToList(self
):
404 self
.Profile
.FileLinesList
= [list(s
) for s
in self
.Profile
.FileLinesList
]
405 if not self
.Profile
.FileLinesList
:
406 EdkLogger
.error('FdfParser', FILE_READ_FAILURE
, 'The file is empty!', File
=self
.FileName
)
407 self
.Profile
.FileLinesList
[-1].append(' ')
409 def _ReplaceFragment(self
, StartPos
, EndPos
, Value
= ' '):
410 if StartPos
[0] == EndPos
[0]:
412 while Offset
<= EndPos
[1]:
413 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
418 while self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] not in CR_LB_SET
:
419 self
.Profile
.FileLinesList
[StartPos
[0]][Offset
] = Value
423 while Line
< EndPos
[0]:
425 while self
.Profile
.FileLinesList
[Line
][Offset
] not in CR_LB_SET
:
426 self
.Profile
.FileLinesList
[Line
][Offset
] = Value
431 while Offset
<= EndPos
[1]:
432 self
.Profile
.FileLinesList
[EndPos
[0]][Offset
] = Value
435 def _SetMacroValue(self
, Macro
, Value
):
436 if not self
._CurSection
:
440 if not self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]:
441 self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]] = MacroDict
443 MacroDict
= self
._MacroDict
[self
._CurSection
[0], self
._CurSection
[1], self
._CurSection
[2]]
444 MacroDict
[Macro
] = Value
446 def _GetMacroValue(self
, Macro
):
448 if Macro
in GlobalData
.gCommandLineDefines
:
449 return GlobalData
.gCommandLineDefines
[Macro
]
450 if Macro
in GlobalData
.gGlobalDefines
:
451 return GlobalData
.gGlobalDefines
[Macro
]
454 MacroDict
= self
._MacroDict
[
459 if MacroDict
and Macro
in MacroDict
:
460 return MacroDict
[Macro
]
463 if Macro
in GlobalData
.gPlatformDefines
:
464 return GlobalData
.gPlatformDefines
[Macro
]
467 def _SectionHeaderParser(self
, Section
):
469 # [FD.UiName]: use dummy instead if UI name is optional
472 # [Rule]: don't take rule section into account, macro is not allowed in this section
473 # [OptionRom.DriverName]
474 self
._CurSection
= []
475 Section
= Section
.strip()[1:-1].upper().replace(' ', '').strip(TAB_SPLIT
)
476 ItemList
= Section
.split(TAB_SPLIT
)
478 if Item
== '' or Item
== 'RULE':
481 if Item
== TAB_COMMON_DEFINES
.upper():
482 self
._CurSection
= [TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
483 elif len(ItemList
) > 1:
484 self
._CurSection
= [ItemList
[0], ItemList
[1], TAB_COMMON
]
485 elif len(ItemList
) > 0:
486 self
._CurSection
= [ItemList
[0], 'DUMMY', TAB_COMMON
]
488 ## PreprocessFile() method
490 # Preprocess file contents, replace comments with spaces.
491 # In the end, rewind the file buffer pointer to the beginning
492 # BUGBUG: No !include statement processing contained in this procedure
493 # !include statement should be expanded at the same FileLinesList[CurrentLineNumber - 1]
495 # @param self The object pointer
497 def PreprocessFile(self
):
500 DoubleSlashComment
= False
502 # HashComment in quoted string " " is ignored.
505 while not self
._EndOfFile
():
507 if self
._CurrentChar
() == T_CHAR_DOUBLE_QUOTE
and not InComment
:
508 InString
= not InString
509 # meet new line, then no longer in a comment for // and '#'
510 if self
._CurrentChar
() == TAB_LINE_BREAK
:
511 self
.CurrentLineNumber
+= 1
512 self
.CurrentOffsetWithinLine
= 0
513 if InComment
and DoubleSlashComment
:
515 DoubleSlashComment
= False
516 if InComment
and HashComment
:
519 # check for */ comment end
520 elif InComment
and not DoubleSlashComment
and not HashComment
and self
._CurrentChar
() == TAB_STAR
and self
._NextChar
() == TAB_BACK_SLASH
:
521 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
523 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
526 # set comments to spaces
528 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
530 # check for // comment
531 elif self
._CurrentChar
() == TAB_BACK_SLASH
and self
._NextChar
() == TAB_BACK_SLASH
and not self
._EndOfLine
():
533 DoubleSlashComment
= True
534 # check for '#' comment
535 elif self
._CurrentChar
() == TAB_COMMENT_SPLIT
and not self
._EndOfLine
() and not InString
:
538 # check for /* comment start
539 elif self
._CurrentChar
() == TAB_BACK_SLASH
and self
._NextChar
() == TAB_STAR
:
540 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
542 self
._SetCurrentCharValue
(TAB_SPACE_SPLIT
)
548 # restore from ListOfList to ListOfString
549 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
552 ## PreprocessIncludeFile() method
554 # Preprocess file contents, replace !include statements with file contents.
555 # In the end, rewind the file buffer pointer to the beginning
557 # @param self The object pointer
559 def PreprocessIncludeFile(self
):
560 # nested include support
563 while self
._GetNextToken
():
565 if self
._Token
== TAB_DEFINE
:
566 if not self
._GetNextToken
():
567 raise Warning.Expected("Macro name", self
.FileName
, self
.CurrentLineNumber
)
569 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
570 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
571 Value
= self
._GetExpression
()
572 MacroDict
[Macro
] = Value
574 elif self
._Token
== TAB_INCLUDE
:
576 IncludeLine
= self
.CurrentLineNumber
577 IncludeOffset
= self
.CurrentOffsetWithinLine
- len(TAB_INCLUDE
)
578 if not self
._GetNextToken
():
579 raise Warning.Expected("include file name", self
.FileName
, self
.CurrentLineNumber
)
580 IncFileName
= self
._Token
582 StartPos
= IncFileName
.find('$(', PreIndex
)
583 EndPos
= IncFileName
.find(')', StartPos
+2)
584 while StartPos
!= -1 and EndPos
!= -1:
585 Macro
= IncFileName
[StartPos
+2: EndPos
]
586 MacroVal
= self
._GetMacroValue
(Macro
)
588 if Macro
in MacroDict
:
589 MacroVal
= MacroDict
[Macro
]
590 if MacroVal
is not None:
591 IncFileName
= IncFileName
.replace('$(' + Macro
+ ')', MacroVal
, 1)
592 if MacroVal
.find('$(') != -1:
595 PreIndex
= StartPos
+ len(MacroVal
)
597 raise Warning("The Macro %s is not defined" %Macro
, self
.FileName
, self
.CurrentLineNumber
)
598 StartPos
= IncFileName
.find('$(', PreIndex
)
599 EndPos
= IncFileName
.find(')', StartPos
+2)
601 IncludedFile
= NormPath(IncFileName
)
603 # First search the include file under the same directory as FDF file
605 IncludedFile1
= PathClass(IncludedFile
, os
.path
.dirname(self
.FileName
))
606 ErrorCode
= IncludedFile1
.Validate()[0]
609 # Then search the include file under the same directory as DSC file
612 if GenFdsGlobalVariable
.ActivePlatform
:
613 PlatformDir
= GenFdsGlobalVariable
.ActivePlatform
.Dir
614 elif GlobalData
.gActivePlatform
:
615 PlatformDir
= GlobalData
.gActivePlatform
.MetaFile
.Dir
616 IncludedFile1
= PathClass(IncludedFile
, PlatformDir
)
617 ErrorCode
= IncludedFile1
.Validate()[0]
620 # Also search file under the WORKSPACE directory
622 IncludedFile1
= PathClass(IncludedFile
, GlobalData
.gWorkspace
)
623 ErrorCode
= IncludedFile1
.Validate()[0]
625 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
),
626 self
.FileName
, self
.CurrentLineNumber
)
628 if not IsValidInclude (IncludedFile1
.Path
, self
.CurrentLineNumber
):
629 raise Warning("The include file {0} is causing a include loop.\n".format (IncludedFile1
.Path
), self
.FileName
, self
.CurrentLineNumber
)
631 IncFileProfile
= IncludeFileProfile(IncludedFile1
.Path
)
633 CurrentLine
= self
.CurrentLineNumber
634 CurrentOffset
= self
.CurrentOffsetWithinLine
635 # list index of the insertion, note that line number is 'CurrentLine + 1'
636 InsertAtLine
= CurrentLine
637 ParentProfile
= GetParentAtLine (CurrentLine
)
638 if ParentProfile
is not None:
639 ParentProfile
.IncludeFileList
.insert(0, IncFileProfile
)
640 IncFileProfile
.Level
= ParentProfile
.Level
+ 1
641 IncFileProfile
.InsertStartLineNumber
= InsertAtLine
+ 1
642 # deal with remaining portions after "!include filename", if exists.
643 if self
._GetNextToken
():
644 if self
.CurrentLineNumber
== CurrentLine
:
645 RemainingLine
= self
._CurrentLine
()[CurrentOffset
:]
646 self
.Profile
.FileLinesList
.insert(self
.CurrentLineNumber
, RemainingLine
)
647 IncFileProfile
.InsertAdjust
+= 1
648 self
.CurrentLineNumber
+= 1
649 self
.CurrentOffsetWithinLine
= 0
651 for Line
in IncFileProfile
.FileLinesList
:
652 self
.Profile
.FileLinesList
.insert(InsertAtLine
, Line
)
653 self
.CurrentLineNumber
+= 1
656 # reversely sorted to better determine error in file
657 AllIncludeFileList
.insert(0, IncFileProfile
)
659 # comment out the processed include file statement
660 TempList
= list(self
.Profile
.FileLinesList
[IncludeLine
- 1])
661 TempList
.insert(IncludeOffset
, TAB_COMMENT_SPLIT
)
662 self
.Profile
.FileLinesList
[IncludeLine
- 1] = ''.join(TempList
)
663 if Processed
: # Nested and back-to-back support
664 self
.Rewind(DestLine
= IncFileProfile
.InsertStartLineNumber
- 1)
670 def _GetIfListCurrentItemStat(IfList
):
680 ## PreprocessConditionalStatement() method
682 # Preprocess conditional statement.
683 # In the end, rewind the file buffer pointer to the beginning
685 # @param self The object pointer
687 def PreprocessConditionalStatement(self
):
688 # IfList is a stack of if branches with elements of list [Pos, CondSatisfied, BranchDetermined]
692 while self
._GetNextToken
():
693 # Determine section name and the location dependent macro
694 if self
._GetIfListCurrentItemStat
(IfList
):
695 if self
._Token
.startswith(TAB_SECTION_START
):
697 if not self
._Token
.endswith(TAB_SECTION_END
):
698 self
._SkipToToken
(TAB_SECTION_END
)
699 Header
+= self
._SkippedChars
700 if Header
.find('$(') != -1:
701 raise Warning("macro cannot be used in section header", self
.FileName
, self
.CurrentLineNumber
)
702 self
._SectionHeaderParser
(Header
)
704 # Replace macros except in RULE section or out of section
705 elif self
._CurSection
and ReplacedLine
!= self
.CurrentLineNumber
:
706 ReplacedLine
= self
.CurrentLineNumber
708 CurLine
= self
.Profile
.FileLinesList
[ReplacedLine
- 1]
710 StartPos
= CurLine
.find('$(', PreIndex
)
711 EndPos
= CurLine
.find(')', StartPos
+2)
712 while StartPos
!= -1 and EndPos
!= -1 and self
._Token
not in {TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_IF
, TAB_ELSE_IF
}:
713 MacroName
= CurLine
[StartPos
+2: EndPos
]
714 MacroValue
= self
._GetMacroValue
(MacroName
)
715 if MacroValue
is not None:
716 CurLine
= CurLine
.replace('$(' + MacroName
+ ')', MacroValue
, 1)
717 if MacroValue
.find('$(') != -1:
720 PreIndex
= StartPos
+ len(MacroValue
)
722 PreIndex
= EndPos
+ 1
723 StartPos
= CurLine
.find('$(', PreIndex
)
724 EndPos
= CurLine
.find(')', StartPos
+2)
725 self
.Profile
.FileLinesList
[ReplacedLine
- 1] = CurLine
728 if self
._Token
== TAB_DEFINE
:
729 if self
._GetIfListCurrentItemStat
(IfList
):
730 if not self
._CurSection
:
731 raise Warning("macro cannot be defined in Rule section or out of section", self
.FileName
, self
.CurrentLineNumber
)
732 DefineLine
= self
.CurrentLineNumber
- 1
733 DefineOffset
= self
.CurrentOffsetWithinLine
- len(TAB_DEFINE
)
734 if not self
._GetNextToken
():
735 raise Warning.Expected("Macro name", self
.FileName
, self
.CurrentLineNumber
)
737 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
738 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
740 Value
= self
._GetExpression
()
741 self
._SetMacroValue
(Macro
, Value
)
742 self
._WipeOffArea
.append(((DefineLine
, DefineOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
743 elif self
._Token
== 'SET':
744 if not self
._GetIfListCurrentItemStat
(IfList
):
746 SetLine
= self
.CurrentLineNumber
- 1
747 SetOffset
= self
.CurrentOffsetWithinLine
- len('SET')
748 PcdPair
= self
._GetNextPcdSettings
()
749 PcdName
= "%s.%s" % (PcdPair
[1], PcdPair
[0])
750 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
751 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
753 Value
= self
._GetExpression
()
754 Value
= self
._EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
756 self
._PcdDict
[PcdName
] = Value
758 self
.Profile
.PcdDict
[PcdPair
] = Value
759 self
.SetPcdLocalation(PcdPair
)
760 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
761 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
763 self
._WipeOffArea
.append(((SetLine
, SetOffset
), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
764 elif self
._Token
in {TAB_IF_DEF
, TAB_IF_N_DEF
, TAB_IF
}:
765 IfStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
._Token
))
766 IfList
.append([IfStartPos
, None, None])
768 CondLabel
= self
._Token
769 Expression
= self
._GetExpression
()
771 if CondLabel
== TAB_IF
:
772 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
774 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'in')
775 if CondLabel
== TAB_IF_N_DEF
:
776 ConditionSatisfied
= not ConditionSatisfied
778 BranchDetermined
= ConditionSatisfied
779 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, BranchDetermined
]
780 if ConditionSatisfied
:
781 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
782 elif self
._Token
in {TAB_ELSE_IF
, TAB_ELSE
}:
783 ElseStartPos
= (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len(self
._Token
))
785 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
788 IfList
[-1] = [ElseStartPos
, False, True]
789 self
._WipeOffArea
.append((ElseStartPos
, (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
791 self
._WipeOffArea
.append((IfList
[-1][0], ElseStartPos
))
792 IfList
[-1] = [ElseStartPos
, True, IfList
[-1][2]]
793 if self
._Token
== TAB_ELSE_IF
:
794 Expression
= self
._GetExpression
()
795 ConditionSatisfied
= self
._EvaluateConditional
(Expression
, IfList
[-1][0][0] + 1, 'eval')
796 IfList
[-1] = [IfList
[-1][0], ConditionSatisfied
, IfList
[-1][2]]
800 IfList
[-1][1] = False
803 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
804 elif self
._Token
== '!endif':
806 raise Warning("Missing !if statement", self
.FileName
, self
.CurrentLineNumber
)
808 self
._WipeOffArea
.append(((self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- len('!endif')), (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
810 self
._WipeOffArea
.append((IfList
[-1][0], (self
.CurrentLineNumber
- 1, self
.CurrentOffsetWithinLine
- 1)))
813 elif not IfList
: # Don't use PCDs inside conditional directive
814 if self
.CurrentLineNumber
<= RegionLayoutLine
:
815 # Don't try the same line twice
817 SetPcd
= ShortcutPcdPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
819 self
._PcdDict
[SetPcd
.group('name')] = SetPcd
.group('value')
820 RegionLayoutLine
= self
.CurrentLineNumber
822 RegionSize
= RegionSizePattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1])
824 RegionLayoutLine
= self
.CurrentLineNumber
826 RegionSizeGuid
= RegionSizeGuidPattern
.match(self
.Profile
.FileLinesList
[self
.CurrentLineNumber
])
827 if not RegionSizeGuid
:
828 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
830 self
._PcdDict
[RegionSizeGuid
.group('base')] = RegionSize
.group('base')
831 self
._PcdDict
[RegionSizeGuid
.group('size')] = RegionSize
.group('size')
832 RegionLayoutLine
= self
.CurrentLineNumber
+ 1
835 raise Warning("Missing !endif", self
.FileName
, self
.CurrentLineNumber
)
838 def _CollectMacroPcd(self
):
842 MacroDict
.update(GlobalData
.gPlatformPcds
)
843 MacroDict
.update(self
._PcdDict
)
846 MacroDict
.update(GlobalData
.gPlatformDefines
)
850 ScopeMacro
= self
._MacroDict
[TAB_COMMON
, TAB_COMMON
, TAB_COMMON
]
852 MacroDict
.update(ScopeMacro
)
855 ScopeMacro
= self
._MacroDict
[
861 MacroDict
.update(ScopeMacro
)
863 MacroDict
.update(GlobalData
.gGlobalDefines
)
864 MacroDict
.update(GlobalData
.gCommandLineDefines
)
865 for Item
in GlobalData
.BuildOptionPcd
:
866 if isinstance(Item
, tuple):
868 PcdName
, TmpValue
= Item
.split(TAB_EQUAL_SPLIT
)
869 TmpValue
= BuildOptionValue(TmpValue
, {})
870 MacroDict
[PcdName
.strip()] = TmpValue
875 def _EvaluateConditional(self
, Expression
, Line
, Op
= None, Value
= None):
876 MacroPcdDict
= self
._CollectMacroPcd
()
880 return ValueExpression(Expression
, MacroPcdDict
)(True)
882 return ValueExpression(Expression
, MacroPcdDict
)()
883 except WrnExpression
as Excpt
:
885 # Catch expression evaluation warning here. We need to report
886 # the precise number of line and return the evaluation result
888 EdkLogger
.warn('Parser', "Suspicious expression: %s" % str(Excpt
),
889 File
=self
.FileName
, ExtraData
=self
._CurrentLine
(),
892 except Exception as Excpt
:
893 if hasattr(Excpt
, 'Pcd'):
894 if Excpt
.Pcd
in GlobalData
.gPlatformOtherPcds
:
895 Info
= GlobalData
.gPlatformOtherPcds
[Excpt
.Pcd
]
896 raise Warning("Cannot use this PCD (%s) in an expression as"
897 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
898 " of the DSC file (%s), and it is currently defined in this section:"
899 " %s, line #: %d." % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE'], Info
[0], Info
[1]),
902 raise Warning("PCD (%s) is not defined in DSC file (%s)" % (Excpt
.Pcd
, GlobalData
.gPlatformOtherPcds
['DSCFILE']),
905 raise Warning(str(Excpt
), self
.FileName
, Line
)
907 if Expression
.startswith('$(') and Expression
[-1] == ')':
908 Expression
= Expression
[2:-1]
909 return Expression
in MacroPcdDict
913 # Check whether input string is found from current char position along
914 # If found, the string value is put into self._Token
916 # @param self The object pointer
917 # @param String The string to search
918 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
919 # @retval True Successfully find string, file buffer pointer moved forward
920 # @retval False Not able to find string, file buffer pointer not changed
922 def _IsToken(self
, String
, IgnoreCase
= False):
923 self
._SkipWhiteSpace
()
925 # Only consider the same line, no multi-line token allowed
926 StartPos
= self
.CurrentOffsetWithinLine
929 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
931 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
933 self
.CurrentOffsetWithinLine
+= len(String
)
934 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
938 ## _IsKeyword() method
940 # Check whether input keyword is found from current char position along, whole word only!
941 # If found, the string value is put into self._Token
943 # @param self The object pointer
944 # @param Keyword The string to search
945 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
946 # @retval True Successfully find string, file buffer pointer moved forward
947 # @retval False Not able to find string, file buffer pointer not changed
949 def _IsKeyword(self
, KeyWord
, IgnoreCase
= False):
950 self
._SkipWhiteSpace
()
952 # Only consider the same line, no multi-line token allowed
953 StartPos
= self
.CurrentOffsetWithinLine
956 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(KeyWord
.upper())
958 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(KeyWord
)
960 followingChar
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
+ len(KeyWord
)]
961 if not str(followingChar
).isspace() and followingChar
not in SEPARATORS
:
963 self
.CurrentOffsetWithinLine
+= len(KeyWord
)
964 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
968 def _GetExpression(self
):
969 Line
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1]
970 Index
= len(Line
) - 1
971 while Line
[Index
] in CR_LB_SET
:
973 ExpressionString
= self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:Index
+1]
974 self
.CurrentOffsetWithinLine
+= len(ExpressionString
)
975 ExpressionString
= ExpressionString
.strip()
976 return ExpressionString
978 ## _GetNextWord() method
980 # Get next C name from file lines
981 # If found, the string value is put into self._Token
983 # @param self The object pointer
984 # @retval True Successfully find a C name string, file buffer pointer moved forward
985 # @retval False Not able to find a C name string, file buffer pointer not changed
987 def _GetNextWord(self
):
988 self
._SkipWhiteSpace
()
989 if self
._EndOfFile
():
992 TempChar
= self
._CurrentChar
()
993 StartPos
= self
.CurrentOffsetWithinLine
994 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_':
996 while not self
._EndOfLine
():
997 TempChar
= self
._CurrentChar
()
998 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
999 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-':
1005 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1010 def _GetNextPcdWord(self
):
1011 self
._SkipWhiteSpace
()
1012 if self
._EndOfFile
():
1015 TempChar
= self
._CurrentChar
()
1016 StartPos
= self
.CurrentOffsetWithinLine
1017 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') or TempChar
== '_' or TempChar
== TAB_SECTION_START
or TempChar
== TAB_SECTION_END
:
1019 while not self
._EndOfLine
():
1020 TempChar
= self
._CurrentChar
()
1021 if (TempChar
>= 'a' and TempChar
<= 'z') or (TempChar
>= 'A' and TempChar
<= 'Z') \
1022 or (TempChar
>= '0' and TempChar
<= '9') or TempChar
== '_' or TempChar
== '-' or TempChar
== TAB_SECTION_START
or TempChar
== TAB_SECTION_END
:
1028 self
._Token
= self
._CurrentLine
()[StartPos
: self
.CurrentOffsetWithinLine
]
1033 ## _GetNextToken() method
1035 # Get next token unit before a separator
1036 # If found, the string value is put into self._Token
1038 # @param self The object pointer
1039 # @retval True Successfully find a token unit, file buffer pointer moved forward
1040 # @retval False Not able to find a token unit, file buffer pointer not changed
1042 def _GetNextToken(self
):
1043 # Skip leading spaces, if exist.
1044 self
._SkipWhiteSpace
()
1045 if self
._EndOfFile
():
1047 # Record the token start position, the position of the first non-space char.
1048 StartPos
= self
.CurrentOffsetWithinLine
1049 StartLine
= self
.CurrentLineNumber
1050 while StartLine
== self
.CurrentLineNumber
:
1051 TempChar
= self
._CurrentChar
()
1052 # Try to find the end char that is not a space and not in separator tuple.
1053 # That is, when we got a space or any char in the tuple, we got the end of token.
1054 if not str(TempChar
).isspace() and TempChar
not in SEPARATORS
:
1056 # if we happen to meet a separator as the first char, we must proceed to get it.
1057 # That is, we get a token that is a separator char. normally it is the boundary of other tokens.
1058 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPARATORS
:
1066 EndPos
= self
.CurrentOffsetWithinLine
1067 if self
.CurrentLineNumber
!= StartLine
:
1068 EndPos
= len(self
.Profile
.FileLinesList
[StartLine
-1])
1069 self
._Token
= self
.Profile
.FileLinesList
[StartLine
-1][StartPos
: EndPos
]
1070 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
}:
1071 self
._Token
= self
._Token
.lower()
1072 if StartPos
!= self
.CurrentOffsetWithinLine
:
1077 ## _GetNextGuid() method
1079 # Get next token unit before a separator
1080 # If found, the GUID string is put into self._Token
1082 # @param self The object pointer
1083 # @retval True Successfully find a registry format GUID, file buffer pointer moved forward
1084 # @retval False Not able to find a registry format GUID, file buffer pointer not changed
1086 def _GetNextGuid(self
):
1087 if not self
._GetNextToken
():
1089 if GlobalData
.gGuidPattern
.match(self
._Token
) is not None:
1091 elif self
._Token
in GlobalData
.gGuidDict
:
1098 def _Verify(Name
, Value
, Scope
):
1099 # value verification only applies to numeric values.
1100 if Scope
not in TAB_PCD_NUMERIC_TYPES
:
1105 ValueNumber
= int(Value
, 0)
1107 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value is not valid dec or hex number for %s." % Name
)
1109 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "The value can't be set to negative value for %s." % Name
)
1110 if ValueNumber
> MAX_VAL_TYPE
[Scope
]:
1111 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "Too large value for %s." % Name
)
1114 ## _UndoToken() method
1116 # Go back one token unit in file buffer
1118 # @param self The object pointer
1120 def _UndoToken(self
):
1122 while self
._CurrentChar
().isspace():
1123 if not self
._UndoOneChar
():
1128 StartPos
= self
.CurrentOffsetWithinLine
1129 CurrentLine
= self
.CurrentLineNumber
1130 while CurrentLine
== self
.CurrentLineNumber
:
1132 TempChar
= self
._CurrentChar
()
1133 # Try to find the end char that is not a space and not in separator tuple.
1134 # That is, when we got a space or any char in the tuple, we got the end of token.
1135 if not str(TempChar
).isspace() and not TempChar
in SEPARATORS
:
1136 if not self
._UndoOneChar
():
1138 # if we happen to meet a separator as the first char, we must proceed to get it.
1139 # That is, we get a token that is a separator char. normally it is the boundary of other tokens.
1140 elif StartPos
== self
.CurrentOffsetWithinLine
and TempChar
in SEPARATORS
:
1147 ## _GetNextHexNumber() method
1149 # Get next HEX data before a separator
1150 # If found, the HEX data is put into self._Token
1152 # @param self The object pointer
1153 # @retval True Successfully find a HEX data, file buffer pointer moved forward
1154 # @retval False Not able to find a HEX data, file buffer pointer not changed
1156 def _GetNextHexNumber(self
):
1157 if not self
._GetNextToken
():
1159 if GlobalData
.gHexPatternAll
.match(self
._Token
):
1165 ## _GetNextDecimalNumber() method
1167 # Get next decimal data before a separator
1168 # If found, the decimal data is put into self._Token
1170 # @param self The object pointer
1171 # @retval True Successfully find a decimal data, file buffer pointer moved forward
1172 # @retval False Not able to find a decimal data, file buffer pointer not changed
1174 def _GetNextDecimalNumber(self
):
1175 if not self
._GetNextToken
():
1177 if self
._Token
.isdigit():
1183 def _GetNextPcdSettings(self
):
1184 if not self
._GetNextWord
():
1185 raise Warning.Expected("<PcdTokenSpaceCName>", self
.FileName
, self
.CurrentLineNumber
)
1186 pcdTokenSpaceCName
= self
._Token
1188 if not self
._IsToken
(TAB_SPLIT
):
1189 raise Warning.Expected(".", self
.FileName
, self
.CurrentLineNumber
)
1191 if not self
._GetNextWord
():
1192 raise Warning.Expected("<PcdCName>", self
.FileName
, self
.CurrentLineNumber
)
1193 pcdCName
= self
._Token
1196 while self
._IsToken
(TAB_SPLIT
):
1197 if not self
._GetNextPcdWord
():
1198 raise Warning.Expected("Pcd Fields", self
.FileName
, self
.CurrentLineNumber
)
1199 Fields
.append(self
._Token
)
1201 return (pcdCName
, pcdTokenSpaceCName
,TAB_SPLIT
.join(Fields
))
1203 ## _GetStringData() method
1205 # Get string contents quoted in ""
1206 # If found, the decimal data is put into self._Token
1208 # @param self The object pointer
1209 # @retval True Successfully find a string data, file buffer pointer moved forward
1210 # @retval False Not able to find a string data, file buffer pointer not changed
1212 def _GetStringData(self
):
1214 if self
._Token
.startswith(T_CHAR_DOUBLE_QUOTE
) or self
._Token
.startswith("L\""):
1215 QuoteToUse
= T_CHAR_DOUBLE_QUOTE
1216 elif self
._Token
.startswith(T_CHAR_SINGLE_QUOTE
) or self
._Token
.startswith("L\'"):
1217 QuoteToUse
= T_CHAR_SINGLE_QUOTE
1222 self
._SkipToToken
(QuoteToUse
)
1223 currentLineNumber
= self
.CurrentLineNumber
1225 if not self
._SkipToToken
(QuoteToUse
):
1226 raise Warning(QuoteToUse
, self
.FileName
, self
.CurrentLineNumber
)
1227 if currentLineNumber
!= self
.CurrentLineNumber
:
1228 raise Warning(QuoteToUse
, self
.FileName
, self
.CurrentLineNumber
)
1229 self
._Token
= self
._SkippedChars
.rstrip(QuoteToUse
)
1232 ## _SkipToToken() method
1234 # Search forward in file buffer for the string
1235 # The skipped chars are put into self._SkippedChars
1237 # @param self The object pointer
1238 # @param String The string to search
1239 # @param IgnoreCase Indicate case sensitive/non-sensitive search, default is case sensitive
1240 # @retval True Successfully find the string, file buffer pointer moved forward
1241 # @retval False Not able to find the string, file buffer pointer not changed
1243 def _SkipToToken(self
, String
, IgnoreCase
= False):
1244 StartPos
= self
.GetFileBufferPos()
1246 self
._SkippedChars
= ""
1247 while not self
._EndOfFile
():
1250 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].upper().find(String
.upper())
1252 index
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
: ].find(String
)
1254 self
.CurrentOffsetWithinLine
+= len(String
)
1255 self
._SkippedChars
+= String
1257 self
._SkippedChars
+= str(self
._CurrentChar
())
1260 self
.SetFileBufferPos(StartPos
)
1261 self
._SkippedChars
= ""
1264 ## GetFileBufferPos() method
1266 # Return the tuple of current line and offset within the line
1268 # @param self The object pointer
1269 # @retval Tuple Line number and offset pair
1271 def GetFileBufferPos(self
):
1272 return (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
)
1274 ## SetFileBufferPos() method
1276 # Restore the file buffer position
1278 # @param self The object pointer
1279 # @param Pos The new file buffer position
1281 def SetFileBufferPos(self
, Pos
):
1282 (self
.CurrentLineNumber
, self
.CurrentOffsetWithinLine
) = Pos
1284 ## Preprocess() method
1286 # Preprocess comment, conditional directive, include directive, replace macro.
1287 # Exception will be raised if syntax error found
1289 # @param self The object pointer
1291 def Preprocess(self
):
1292 self
._StringToList
()
1293 self
.PreprocessFile()
1294 self
.PreprocessIncludeFile()
1295 self
._StringToList
()
1296 self
.PreprocessFile()
1297 self
.PreprocessConditionalStatement()
1298 self
._StringToList
()
1299 for Pos
in self
._WipeOffArea
:
1300 self
._ReplaceFragment
(Pos
[0], Pos
[1])
1301 self
.Profile
.FileLinesList
= ["".join(list) for list in self
.Profile
.FileLinesList
]
1303 while self
._GetDefines
():
1306 ## ParseFile() method
1308 # Parse the file profile buffer to extract fd, fv ... information
1309 # Exception will be raised if syntax error found
1311 # @param self The object pointer
1313 def ParseFile(self
):
1318 # Keep processing sections of the FDF until no new sections or a syntax error is found
1320 while self
._GetFd
() or self
._GetFv
() or self
._GetFmp
() or self
._GetCapsule
() or self
._GetRule
() or self
._GetOptionRom
():
1323 except Warning as X
:
1325 #'\n\tGot Token: \"%s\" from File %s\n' % (self._Token, FileLineTuple[0]) + \
1326 # At this point, the closest parent would be the included file itself
1327 Profile
= GetParentAtLine(X
.OriginalLineNumber
)
1328 if Profile
is not None:
1329 X
.Message
+= ' near line %d, column %d: %s' \
1330 % (X
.LineNumber
, 0, Profile
.FileLinesList
[X
.LineNumber
-1])
1332 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1333 X
.Message
+= ' near line %d, column %d: %s' \
1334 % (FileLineTuple
[1], self
.CurrentOffsetWithinLine
+ 1, self
.Profile
.FileLinesList
[self
.CurrentLineNumber
- 1][self
.CurrentOffsetWithinLine
:].rstrip(TAB_LINE_BREAK
).rstrip(T_CHAR_CR
))
1337 ## SectionParser() method
1339 # Parse the file section info
1340 # Exception will be raised if syntax error found
1342 # @param self The object pointer
1343 # @param section The section string
1345 def SectionParser(self
, section
):
1347 if not S
.startswith("[DEFINES") and not S
.startswith("[FD.") and not S
.startswith("[FV.") and not S
.startswith("[CAPSULE.") \
1348 and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM.") and not S
.startswith('[FMPPAYLOAD.'):
1349 raise Warning("Unknown section or section appear sequence error (The correct sequence should be [DEFINES], [FD.], [FV.], [Capsule.], [Rule.], [OptionRom.], [FMPPAYLOAD.])", self
.FileName
, self
.CurrentLineNumber
)
1351 ## _GetDefines() method
1353 # Get Defines section contents and store its data into AllMacrosList
1355 # @param self The object pointer
1356 # @retval True Successfully find a Defines
1357 # @retval False Not able to find a Defines
1359 def _GetDefines(self
):
1360 if not self
._GetNextToken
():
1363 S
= self
._Token
.upper()
1364 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[DEFINES"):
1365 self
.SectionParser(S
)
1370 if not self
._IsToken
("[DEFINES", True):
1371 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1372 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1373 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1374 raise Warning.Expected("[DEFINES", self
.FileName
, self
.CurrentLineNumber
)
1376 if not self
._IsToken
(TAB_SECTION_END
):
1377 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
1379 while self
._GetNextWord
():
1380 # handle the SET statement
1381 if self
._Token
== 'SET':
1383 self
._GetSetStatement
(None)
1388 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1389 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1390 if not self
._GetNextToken
() or self
._Token
.startswith(TAB_SECTION_START
):
1391 raise Warning.Expected("MACRO value", self
.FileName
, self
.CurrentLineNumber
)
1396 ##_GetError() method
1397 def _GetError(self
):
1398 #save the Current information
1399 CurrentLine
= self
.CurrentLineNumber
1400 CurrentOffset
= self
.CurrentOffsetWithinLine
1401 while self
._GetNextToken
():
1402 if self
._Token
== TAB_ERROR
:
1403 EdkLogger
.error('FdfParser', ERROR_STATEMENT
, self
._CurrentLine
().replace(TAB_ERROR
, '', 1), File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
1404 self
.CurrentLineNumber
= CurrentLine
1405 self
.CurrentOffsetWithinLine
= CurrentOffset
1409 # Get FD section contents and store its data into FD dictionary of self.Profile
1411 # @param self The object pointer
1412 # @retval True Successfully find a FD
1413 # @retval False Not able to find a FD
1416 if not self
._GetNextToken
():
1419 S
= self
._Token
.upper()
1420 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FD."):
1421 if not S
.startswith("[FV.") and not S
.startswith('[FMPPAYLOAD.') and not S
.startswith("[CAPSULE.") \
1422 and not S
.startswith("[RULE.") and not S
.startswith("[OPTIONROM."):
1423 raise Warning("Unknown section", self
.FileName
, self
.CurrentLineNumber
)
1428 if not self
._IsToken
("[FD.", True):
1429 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1430 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
1431 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
1432 raise Warning.Expected("[FD.]", self
.FileName
, self
.CurrentLineNumber
)
1434 FdName
= self
._GetUiName
()
1436 if len (self
.Profile
.FdDict
) == 0:
1437 FdName
= GenFdsGlobalVariable
.PlatformName
1438 if FdName
== "" and GlobalData
.gActivePlatform
:
1439 FdName
= GlobalData
.gActivePlatform
.PlatformName
1440 self
.Profile
.FdNameNotSet
= True
1442 raise Warning.Expected("FdName in [FD.] section", self
.FileName
, self
.CurrentLineNumber
)
1443 self
.CurrentFdName
= FdName
.upper()
1445 if self
.CurrentFdName
in self
.Profile
.FdDict
:
1446 raise Warning("Unexpected the same FD name", self
.FileName
, self
.CurrentLineNumber
)
1448 if not self
._IsToken
(TAB_SECTION_END
):
1449 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
1452 FdObj
.FdUiName
= self
.CurrentFdName
1453 self
.Profile
.FdDict
[self
.CurrentFdName
] = FdObj
1455 if len (self
.Profile
.FdDict
) > 1 and self
.Profile
.FdNameNotSet
:
1456 raise Warning.Expected("all FDs have their name", self
.FileName
, self
.CurrentLineNumber
)
1458 Status
= self
._GetCreateFile
(FdObj
)
1460 raise Warning("FD name error", self
.FileName
, self
.CurrentLineNumber
)
1462 while self
._GetTokenStatements
(FdObj
):
1464 for Attr
in ("BaseAddress", "Size", "ErasePolarity"):
1465 if getattr(FdObj
, Attr
) is None:
1466 self
._GetNextToken
()
1467 raise Warning("Keyword %s missing" % Attr
, self
.FileName
, self
.CurrentLineNumber
)
1469 if not FdObj
.BlockSizeList
:
1470 FdObj
.BlockSizeList
.append((1, FdObj
.Size
, None))
1472 self
._GetDefineStatements
(FdObj
)
1474 self
._GetSetStatements
(FdObj
)
1476 if not self
._GetRegionLayout
(FdObj
):
1477 raise Warning.Expected("region layout", self
.FileName
, self
.CurrentLineNumber
)
1479 while self
._GetRegionLayout
(FdObj
):
1483 ## _GetUiName() method
1485 # Return the UI name of a section
1487 # @param self The object pointer
1488 # @retval FdName UI name
1490 def _GetUiName(self
):
1492 if self
._GetNextWord
():
1497 ## _GetCreateFile() method
1499 # Return the output file name of object
1501 # @param self The object pointer
1502 # @param Obj object whose data will be stored in file
1503 # @retval FdName UI name
1505 def _GetCreateFile(self
, Obj
):
1506 if self
._IsKeyword
("CREATE_FILE"):
1507 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1508 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1510 if not self
._GetNextToken
():
1511 raise Warning.Expected("file name", self
.FileName
, self
.CurrentLineNumber
)
1513 FileName
= self
._Token
1514 Obj
.CreateFileName
= FileName
1518 def SetPcdLocalation(self
,pcdpair
):
1519 self
.Profile
.PcdLocalDict
[pcdpair
] = (self
.Profile
.FileName
,self
.CurrentLineNumber
)
1521 ## _GetTokenStatements() method
1523 # Get token statements
1525 # @param self The object pointer
1526 # @param Obj for whom token statement is got
1528 def _GetTokenStatements(self
, Obj
):
1529 if self
._IsKeyword
("BaseAddress"):
1530 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1531 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1533 if not self
._GetNextHexNumber
():
1534 raise Warning.Expected("Hex base address", self
.FileName
, self
.CurrentLineNumber
)
1536 Obj
.BaseAddress
= self
._Token
1538 if self
._IsToken
(TAB_VALUE_SPLIT
):
1539 pcdPair
= self
._GetNextPcdSettings
()
1540 Obj
.BaseAddressPcd
= pcdPair
1541 self
.Profile
.PcdDict
[pcdPair
] = Obj
.BaseAddress
1542 self
.SetPcdLocalation(pcdPair
)
1543 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1544 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1547 if self
._IsKeyword
("Size"):
1548 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1549 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1551 if not self
._GetNextHexNumber
():
1552 raise Warning.Expected("Hex size", self
.FileName
, self
.CurrentLineNumber
)
1555 if self
._IsToken
(TAB_VALUE_SPLIT
):
1556 pcdPair
= self
._GetNextPcdSettings
()
1557 Obj
.SizePcd
= pcdPair
1558 self
.Profile
.PcdDict
[pcdPair
] = Size
1559 self
.SetPcdLocalation(pcdPair
)
1560 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1561 self
.Profile
.PcdFileLineDict
[pcdPair
] = FileLineTuple
1562 Obj
.Size
= int(Size
, 0)
1565 if self
._IsKeyword
("ErasePolarity"):
1566 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1567 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1569 if not self
._GetNextToken
():
1570 raise Warning.Expected("Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1572 if not self
._Token
in {"1", "0"}:
1573 raise Warning.Expected("1 or 0 Erase Polarity", self
.FileName
, self
.CurrentLineNumber
)
1575 Obj
.ErasePolarity
= self
._Token
1578 return self
._GetBlockStatements
(Obj
)
1580 ## _GetAddressStatements() method
1582 # Get address statements
1584 # @param self The object pointer
1585 # @param Obj for whom address statement is got
1586 # @retval True Successfully find
1587 # @retval False Not able to find
1589 def _GetAddressStatements(self
, Obj
):
1590 if self
._IsKeyword
("BsBaseAddress"):
1591 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1592 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1594 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1595 raise Warning.Expected("address", self
.FileName
, self
.CurrentLineNumber
)
1597 BsAddress
= int(self
._Token
, 0)
1598 Obj
.BsBaseAddress
= BsAddress
1600 if self
._IsKeyword
("RtBaseAddress"):
1601 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1602 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1604 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1605 raise Warning.Expected("address", self
.FileName
, self
.CurrentLineNumber
)
1607 RtAddress
= int(self
._Token
, 0)
1608 Obj
.RtBaseAddress
= RtAddress
1610 ## _GetBlockStatements() method
1612 # Get block statements
1614 # @param self The object pointer
1615 # @param Obj for whom block statement is got
1617 def _GetBlockStatements(self
, Obj
):
1619 while self
._GetBlockStatement
(Obj
):
1622 Item
= Obj
.BlockSizeList
[-1]
1623 if Item
[0] is None or Item
[1] is None:
1624 raise Warning.Expected("block statement", self
.FileName
, self
.CurrentLineNumber
)
1627 ## _GetBlockStatement() method
1629 # Get block statement
1631 # @param self The object pointer
1632 # @param Obj for whom block statement is got
1633 # @retval True Successfully find
1634 # @retval False Not able to find
1636 def _GetBlockStatement(self
, Obj
):
1637 if not self
._IsKeyword
("BlockSize"):
1640 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1641 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1643 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
1644 raise Warning.Expected("Hex or Integer block size", self
.FileName
, self
.CurrentLineNumber
)
1646 BlockSize
= self
._Token
1648 if self
._IsToken
(TAB_VALUE_SPLIT
):
1649 PcdPair
= self
._GetNextPcdSettings
()
1650 BlockSizePcd
= PcdPair
1651 self
.Profile
.PcdDict
[PcdPair
] = BlockSize
1652 self
.SetPcdLocalation(PcdPair
)
1653 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1654 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1655 BlockSize
= int(BlockSize
, 0)
1658 if self
._IsKeyword
("NumBlocks"):
1659 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1660 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1662 if not self
._GetNextDecimalNumber
() and not self
._GetNextHexNumber
():
1663 raise Warning.Expected("block numbers", self
.FileName
, self
.CurrentLineNumber
)
1665 BlockNumber
= int(self
._Token
, 0)
1667 Obj
.BlockSizeList
.append((BlockSize
, BlockNumber
, BlockSizePcd
))
1670 ## _GetDefineStatements() method
1672 # Get define statements
1674 # @param self The object pointer
1675 # @param Obj for whom define statement is got
1676 # @retval True Successfully find
1677 # @retval False Not able to find
1679 def _GetDefineStatements(self
, Obj
):
1680 while self
._GetDefineStatement
(Obj
):
1683 ## _GetDefineStatement() method
1685 # Get define statement
1687 # @param self The object pointer
1688 # @param Obj for whom define statement is got
1689 # @retval True Successfully find
1690 # @retval False Not able to find
1692 def _GetDefineStatement(self
, Obj
):
1693 if self
._IsKeyword
(TAB_DEFINE
):
1694 self
._GetNextToken
()
1696 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1697 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1699 if not self
._GetNextToken
():
1700 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
1703 Macro
= '$(' + Macro
+ ')'
1704 Obj
.DefineVarDict
[Macro
] = Value
1709 ## _GetSetStatements() method
1711 # Get set statements
1713 # @param self The object pointer
1714 # @param Obj for whom set statement is got
1715 # @retval True Successfully find
1716 # @retval False Not able to find
1718 def _GetSetStatements(self
, Obj
):
1719 while self
._GetSetStatement
(Obj
):
1722 ## _GetSetStatement() method
1726 # @param self The object pointer
1727 # @param Obj for whom set statement is got
1728 # @retval True Successfully find
1729 # @retval False Not able to find
1731 def _GetSetStatement(self
, Obj
):
1732 if self
._IsKeyword
("SET"):
1733 PcdPair
= self
._GetNextPcdSettings
()
1735 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1736 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1738 Value
= self
._GetExpression
()
1739 Value
= self
._EvaluateConditional
(Value
, self
.CurrentLineNumber
, 'eval', True)
1742 Obj
.SetVarDict
[PcdPair
] = Value
1743 self
.Profile
.PcdDict
[PcdPair
] = Value
1744 self
.SetPcdLocalation(PcdPair
)
1745 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1746 self
.Profile
.PcdFileLineDict
[PcdPair
] = FileLineTuple
1751 ## _CalcRegionExpr(self)
1753 # Calculate expression for offset or size of a region
1755 # @return: None if invalid expression
1756 # Calculated number if successfully
1758 def _CalcRegionExpr(self
):
1759 StartPos
= self
.GetFileBufferPos()
1762 while not self
._EndOfFile
():
1763 CurCh
= self
._CurrentChar
()
1769 if CurCh
in '|\r\n' and PairCount
== 0:
1775 ValueExpression(Expr
,
1776 self
._CollectMacroPcd
()
1779 self
.SetFileBufferPos(StartPos
)
1782 ## _GetRegionLayout() method
1784 # Get region layout for FD
1786 # @param self The object pointer
1787 # @param theFd for whom region is got
1788 # @retval True Successfully find
1789 # @retval False Not able to find
1791 def _GetRegionLayout(self
, theFd
):
1792 Offset
= self
._CalcRegionExpr
()
1796 RegionObj
= Region()
1797 RegionObj
.Offset
= Offset
1798 theFd
.RegionList
.append(RegionObj
)
1800 if not self
._IsToken
(TAB_VALUE_SPLIT
):
1801 raise Warning.Expected("'|'", self
.FileName
, self
.CurrentLineNumber
)
1803 Size
= self
._CalcRegionExpr
()
1805 raise Warning.Expected("Region Size", self
.FileName
, self
.CurrentLineNumber
)
1806 RegionObj
.Size
= Size
1808 if not self
._GetNextWord
():
1811 if not self
._Token
in {"SET", BINARY_FILE_TYPE_FV
, "FILE", "DATA", "CAPSULE", "INF"}:
1813 # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]
1814 # Or it might be next region's offset described by an expression which starts with a PCD.
1815 # PcdOffset[|PcdSize] or OffsetPcdExpression|Size
1818 IsRegionPcd
= (RegionSizeGuidPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]) or
1819 RegionOffsetPcdPattern
.match(self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:]))
1821 RegionObj
.PcdOffset
= self
._GetNextPcdSettings
()
1822 self
.Profile
.PcdDict
[RegionObj
.PcdOffset
] = "0x%08X" % (RegionObj
.Offset
+ int(theFd
.BaseAddress
, 0))
1823 self
.SetPcdLocalation(RegionObj
.PcdOffset
)
1824 self
._PcdDict
['%s.%s' % (RegionObj
.PcdOffset
[1], RegionObj
.PcdOffset
[0])] = "0x%x" % RegionObj
.Offset
1825 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1826 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdOffset
] = FileLineTuple
1827 if self
._IsToken
(TAB_VALUE_SPLIT
):
1828 RegionObj
.PcdSize
= self
._GetNextPcdSettings
()
1829 self
.Profile
.PcdDict
[RegionObj
.PcdSize
] = "0x%08X" % RegionObj
.Size
1830 self
.SetPcdLocalation(RegionObj
.PcdSize
)
1831 self
._PcdDict
['%s.%s' % (RegionObj
.PcdSize
[1], RegionObj
.PcdSize
[0])] = "0x%x" % RegionObj
.Size
1832 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
1833 self
.Profile
.PcdFileLineDict
[RegionObj
.PcdSize
] = FileLineTuple
1835 if not self
._GetNextWord
():
1838 if self
._Token
== "SET":
1840 self
._GetSetStatements
(RegionObj
)
1841 if not self
._GetNextWord
():
1844 elif self
._Token
== BINARY_FILE_TYPE_FV
:
1846 self
._GetRegionFvType
(RegionObj
)
1848 elif self
._Token
== "CAPSULE":
1850 self
._GetRegionCapType
(RegionObj
)
1852 elif self
._Token
== "FILE":
1854 self
._GetRegionFileType
(RegionObj
)
1856 elif self
._Token
== "INF":
1858 RegionObj
.RegionType
= "INF"
1859 while self
._IsKeyword
("INF"):
1861 ffsInf
= self
._ParseInfStatement
()
1864 RegionObj
.RegionDataList
.append(ffsInf
)
1866 elif self
._Token
== "DATA":
1868 self
._GetRegionDataType
(RegionObj
)
1871 if self
._GetRegionLayout
(theFd
):
1873 raise Warning("A valid region type was not found. "
1874 "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",
1875 self
.FileName
, self
.CurrentLineNumber
)
1879 ## _GetRegionFvType() method
1881 # Get region fv data for region
1883 # @param self The object pointer
1884 # @param RegionObj for whom region data is got
1886 def _GetRegionFvType(self
, RegionObj
):
1887 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1888 raise Warning.Expected("'FV'", self
.FileName
, self
.CurrentLineNumber
)
1890 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1891 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1893 if not self
._GetNextToken
():
1894 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
1896 RegionObj
.RegionType
= BINARY_FILE_TYPE_FV
1897 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1899 while self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
1901 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1902 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1904 if not self
._GetNextToken
():
1905 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
1907 RegionObj
.RegionDataList
.append((self
._Token
).upper())
1909 ## _GetRegionCapType() method
1911 # Get region capsule data for region
1913 # @param self The object pointer
1914 # @param RegionObj for whom region data is got
1916 def _GetRegionCapType(self
, RegionObj
):
1917 if not self
._IsKeyword
("CAPSULE"):
1918 raise Warning.Expected("'CAPSULE'", self
.FileName
, self
.CurrentLineNumber
)
1920 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1921 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1923 if not self
._GetNextToken
():
1924 raise Warning.Expected("CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1926 RegionObj
.RegionType
= "CAPSULE"
1927 RegionObj
.RegionDataList
.append(self
._Token
)
1929 while self
._IsKeyword
("CAPSULE"):
1931 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1932 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1934 if not self
._GetNextToken
():
1935 raise Warning.Expected("CAPSULE name", self
.FileName
, self
.CurrentLineNumber
)
1937 RegionObj
.RegionDataList
.append(self
._Token
)
1939 ## _GetRegionFileType() method
1941 # Get region file data for region
1943 # @param self The object pointer
1944 # @param RegionObj for whom region data is got
1946 def _GetRegionFileType(self
, RegionObj
):
1947 if not self
._IsKeyword
("FILE"):
1948 raise Warning.Expected("'FILE'", self
.FileName
, self
.CurrentLineNumber
)
1950 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1951 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1953 if not self
._GetNextToken
():
1954 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
1956 RegionObj
.RegionType
= "FILE"
1957 RegionObj
.RegionDataList
.append(self
._Token
)
1959 while self
._IsKeyword
("FILE"):
1961 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1962 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1964 if not self
._GetNextToken
():
1965 raise Warning.Expected("FILE name", self
.FileName
, self
.CurrentLineNumber
)
1967 RegionObj
.RegionDataList
.append(self
._Token
)
1969 ## _GetRegionDataType() method
1971 # Get region array data for region
1973 # @param self The object pointer
1974 # @param RegionObj for whom region data is got
1976 def _GetRegionDataType(self
, RegionObj
):
1977 if not self
._IsKeyword
("DATA"):
1978 raise Warning.Expected("Region Data type", self
.FileName
, self
.CurrentLineNumber
)
1980 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
1981 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
1983 if not self
._IsToken
("{"):
1984 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
1986 if not self
._GetNextHexNumber
():
1987 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
1989 if len(self
._Token
) > 18:
1990 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
1992 # convert hex string value to byte hex string array
1993 AllString
= self
._Token
1994 AllStrLen
= len (AllString
)
1996 while AllStrLen
> 4:
1997 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
1998 AllStrLen
= AllStrLen
- 2
1999 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
2002 if len (self
._Token
) <= 4:
2003 while self
._IsToken
(TAB_COMMA_SPLIT
):
2004 if not self
._GetNextHexNumber
():
2005 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2006 if len(self
._Token
) > 4:
2007 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2008 DataString
+= self
._Token
2009 DataString
+= TAB_COMMA_SPLIT
2011 if not self
._IsToken
(T_CHAR_BRACE_R
):
2012 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2014 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2015 RegionObj
.RegionType
= "DATA"
2016 RegionObj
.RegionDataList
.append(DataString
)
2018 while self
._IsKeyword
("DATA"):
2020 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2021 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2023 if not self
._IsToken
("{"):
2024 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2026 if not self
._GetNextHexNumber
():
2027 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2029 if len(self
._Token
) > 18:
2030 raise Warning("Hex string can't be converted to a valid UINT64 value", self
.FileName
, self
.CurrentLineNumber
)
2032 # convert hex string value to byte hex string array
2033 AllString
= self
._Token
2034 AllStrLen
= len (AllString
)
2036 while AllStrLen
> 4:
2037 DataString
= DataString
+ "0x" + AllString
[AllStrLen
- 2: AllStrLen
] + TAB_COMMA_SPLIT
2038 AllStrLen
= AllStrLen
- 2
2039 DataString
= DataString
+ AllString
[:AllStrLen
] + TAB_COMMA_SPLIT
2042 if len (self
._Token
) <= 4:
2043 while self
._IsToken
(TAB_COMMA_SPLIT
):
2044 if not self
._GetNextHexNumber
():
2045 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2046 if len(self
._Token
) > 4:
2047 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2048 DataString
+= self
._Token
2049 DataString
+= TAB_COMMA_SPLIT
2051 if not self
._IsToken
(T_CHAR_BRACE_R
):
2052 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2054 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2055 RegionObj
.RegionDataList
.append(DataString
)
2059 # Get FV section contents and store its data into FV dictionary of self.Profile
2061 # @param self The object pointer
2062 # @retval True Successfully find a FV
2063 # @retval False Not able to find a FV
2066 if not self
._GetNextToken
():
2069 S
= self
._Token
.upper()
2070 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FV."):
2071 self
.SectionParser(S
)
2076 if not self
._IsToken
("[FV.", True):
2077 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2078 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
2079 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
2080 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2082 FvName
= self
._GetUiName
()
2083 self
.CurrentFvName
= FvName
.upper()
2085 if not self
._IsToken
(TAB_SECTION_END
):
2086 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
2088 FvObj
= FV(Name
=self
.CurrentFvName
)
2089 self
.Profile
.FvDict
[self
.CurrentFvName
] = FvObj
2091 Status
= self
._GetCreateFile
(FvObj
)
2093 raise Warning("FV name error", self
.FileName
, self
.CurrentLineNumber
)
2095 self
._GetDefineStatements
(FvObj
)
2097 self
._GetAddressStatements
(FvObj
)
2100 self
._GetSetStatements
(FvObj
)
2102 if not (self
._GetBlockStatement
(FvObj
) or self
._GetFvBaseAddress
(FvObj
) or
2103 self
._GetFvForceRebase
(FvObj
) or self
._GetFvAlignment
(FvObj
) or
2104 self
._GetFvAttributes
(FvObj
) or self
._GetFvNameGuid
(FvObj
) or
2105 self
._GetFvExtEntryStatement
(FvObj
) or self
._GetFvNameString
(FvObj
)):
2108 if FvObj
.FvNameString
== 'TRUE' and not FvObj
.FvNameGuid
:
2109 raise Warning("FvNameString found but FvNameGuid was not found", self
.FileName
, self
.CurrentLineNumber
)
2111 self
._GetAprioriSection
(FvObj
)
2112 self
._GetAprioriSection
(FvObj
)
2115 isInf
= self
._GetInfStatement
(FvObj
)
2116 isFile
= self
._GetFileStatement
(FvObj
)
2117 if not isInf
and not isFile
:
2122 ## _GetFvAlignment() method
2124 # Get alignment for FV
2126 # @param self The object pointer
2127 # @param Obj for whom alignment is got
2128 # @retval True Successfully find a alignment statement
2129 # @retval False Not able to find a alignment statement
2131 def _GetFvAlignment(self
, Obj
):
2132 if not self
._IsKeyword
("FvAlignment"):
2135 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2136 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2138 if not self
._GetNextToken
():
2139 raise Warning.Expected("alignment value", self
.FileName
, self
.CurrentLineNumber
)
2141 if self
._Token
.upper() not in {"1", "2", "4", "8", "16", "32", "64", "128", "256", "512", \
2142 "1K", "2K", "4K", "8K", "16K", "32K", "64K", "128K", "256K", "512K", \
2143 "1M", "2M", "4M", "8M", "16M", "32M", "64M", "128M", "256M", "512M", \
2145 raise Warning("Unknown alignment value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2146 Obj
.FvAlignment
= self
._Token
2149 ## _GetFvBaseAddress() method
2151 # Get BaseAddress for FV
2153 # @param self The object pointer
2154 # @param Obj for whom FvBaseAddress is got
2155 # @retval True Successfully find a FvBaseAddress statement
2156 # @retval False Not able to find a FvBaseAddress statement
2158 def _GetFvBaseAddress(self
, Obj
):
2159 if not self
._IsKeyword
("FvBaseAddress"):
2162 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2163 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2165 if not self
._GetNextToken
():
2166 raise Warning.Expected("FV base address value", self
.FileName
, self
.CurrentLineNumber
)
2168 if not BaseAddrValuePattern
.match(self
._Token
.upper()):
2169 raise Warning("Unknown FV base address value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2170 Obj
.FvBaseAddress
= self
._Token
2173 ## _GetFvForceRebase() method
2175 # Get FvForceRebase for FV
2177 # @param self The object pointer
2178 # @param Obj for whom FvForceRebase is got
2179 # @retval True Successfully find a FvForceRebase statement
2180 # @retval False Not able to find a FvForceRebase statement
2182 def _GetFvForceRebase(self
, Obj
):
2183 if not self
._IsKeyword
("FvForceRebase"):
2186 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2187 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2189 if not self
._GetNextToken
():
2190 raise Warning.Expected("FvForceRebase value", self
.FileName
, self
.CurrentLineNumber
)
2192 if self
._Token
.upper() not in {"TRUE", "FALSE", "0", "0X0", "0X00", "1", "0X1", "0X01"}:
2193 raise Warning("Unknown FvForceRebase value '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2195 if self
._Token
.upper() in {"TRUE", "1", "0X1", "0X01"}:
2196 Obj
.FvForceRebase
= True
2197 elif self
._Token
.upper() in {"FALSE", "0", "0X0", "0X00"}:
2198 Obj
.FvForceRebase
= False
2200 Obj
.FvForceRebase
= None
2205 ## _GetFvAttributes() method
2207 # Get attributes for FV
2209 # @param self The object pointer
2210 # @param Obj for whom attribute is got
2213 def _GetFvAttributes(self
, FvObj
):
2215 while self
._GetNextWord
():
2218 if name
not in {"ERASE_POLARITY", "MEMORY_MAPPED", \
2219 "STICKY_WRITE", "LOCK_CAP", "LOCK_STATUS", "WRITE_ENABLED_CAP", \
2220 "WRITE_DISABLED_CAP", "WRITE_STATUS", "READ_ENABLED_CAP", \
2221 "READ_DISABLED_CAP", "READ_STATUS", "READ_LOCK_CAP", \
2222 "READ_LOCK_STATUS", "WRITE_LOCK_CAP", "WRITE_LOCK_STATUS", \
2223 "WRITE_POLICY_RELIABLE", "WEAK_ALIGNMENT", "FvUsedSizeEnable"}:
2227 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2228 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2230 if not self
._GetNextToken
() or self
._Token
.upper() not in {"TRUE", "FALSE", "1", "0"}:
2231 raise Warning.Expected("TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
2233 FvObj
.FvAttributeDict
[name
] = self
._Token
2237 ## _GetFvNameGuid() method
2239 # Get FV GUID for FV
2241 # @param self The object pointer
2242 # @param Obj for whom GUID is got
2245 def _GetFvNameGuid(self
, FvObj
):
2246 if not self
._IsKeyword
("FvNameGuid"):
2249 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2250 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2252 if not self
._GetNextGuid
():
2253 raise Warning.Expected("GUID value", self
.FileName
, self
.CurrentLineNumber
)
2254 if self
._Token
in GlobalData
.gGuidDict
:
2255 self
._Token
= GuidStructureStringToGuidString(GlobalData
.gGuidDict
[self
._Token
]).upper()
2257 FvObj
.FvNameGuid
= self
._Token
2261 def _GetFvNameString(self
, FvObj
):
2262 if not self
._IsKeyword
("FvNameString"):
2265 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2266 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2268 if not self
._GetNextToken
() or self
._Token
.upper() not in {'TRUE', 'FALSE'}:
2269 raise Warning.Expected("TRUE or FALSE for FvNameString", self
.FileName
, self
.CurrentLineNumber
)
2271 FvObj
.FvNameString
= self
._Token
2275 def _GetFvExtEntryStatement(self
, FvObj
):
2276 if not (self
._IsKeyword
("FV_EXT_ENTRY") or self
._IsKeyword
("FV_EXT_ENTRY_TYPE")):
2279 if not self
._IsKeyword
("TYPE"):
2280 raise Warning.Expected("'TYPE'", self
.FileName
, self
.CurrentLineNumber
)
2282 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2283 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2285 if not self
._GetNextHexNumber
() and not self
._GetNextDecimalNumber
():
2286 raise Warning.Expected("Hex FV extension entry type value At Line ", self
.FileName
, self
.CurrentLineNumber
)
2288 FvObj
.FvExtEntryTypeValue
.append(self
._Token
)
2290 if not self
._IsToken
("{"):
2291 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2293 if not self
._IsKeyword
("FILE") and not self
._IsKeyword
("DATA"):
2294 raise Warning.Expected("'FILE' or 'DATA'", self
.FileName
, self
.CurrentLineNumber
)
2296 FvObj
.FvExtEntryType
.append(self
._Token
)
2298 if self
._Token
== 'DATA':
2299 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2300 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2302 if not self
._IsToken
("{"):
2303 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2305 if not self
._GetNextHexNumber
():
2306 raise Warning.Expected("Hex byte", self
.FileName
, self
.CurrentLineNumber
)
2308 if len(self
._Token
) > 4:
2309 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2311 DataString
= self
._Token
2312 DataString
+= TAB_COMMA_SPLIT
2314 while self
._IsToken
(TAB_COMMA_SPLIT
):
2315 if not self
._GetNextHexNumber
():
2316 raise Warning("Invalid Hex number", self
.FileName
, self
.CurrentLineNumber
)
2317 if len(self
._Token
) > 4:
2318 raise Warning("Hex byte(must be 2 digits) too long", self
.FileName
, self
.CurrentLineNumber
)
2319 DataString
+= self
._Token
2320 DataString
+= TAB_COMMA_SPLIT
2322 if not self
._IsToken
(T_CHAR_BRACE_R
):
2323 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2325 if not self
._IsToken
(T_CHAR_BRACE_R
):
2326 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2328 DataString
= DataString
.rstrip(TAB_COMMA_SPLIT
)
2329 FvObj
.FvExtEntryData
.append(DataString
)
2331 if self
._Token
== 'FILE':
2332 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2333 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2335 if not self
._GetNextToken
():
2336 raise Warning.Expected("FV Extension Entry file path At Line ", self
.FileName
, self
.CurrentLineNumber
)
2338 FvObj
.FvExtEntryData
.append(self
._Token
)
2340 if not self
._IsToken
(T_CHAR_BRACE_R
):
2341 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2345 ## _GetAprioriSection() method
2347 # Get token statements
2349 # @param self The object pointer
2350 # @param FvObj for whom apriori is got
2351 # @retval True Successfully find apriori statement
2352 # @retval False Not able to find apriori statement
2354 def _GetAprioriSection(self
, FvObj
):
2355 if not self
._IsKeyword
("APRIORI"):
2358 if not self
._IsKeyword
("PEI") and not self
._IsKeyword
("DXE"):
2359 raise Warning.Expected("Apriori file type", self
.FileName
, self
.CurrentLineNumber
)
2360 AprType
= self
._Token
2362 if not self
._IsToken
("{"):
2363 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2365 AprSectionObj
= AprioriSection()
2366 AprSectionObj
.AprioriType
= AprType
2368 self
._GetDefineStatements
(AprSectionObj
)
2371 IsInf
= self
._GetInfStatement
(AprSectionObj
)
2372 IsFile
= self
._GetFileStatement
(AprSectionObj
)
2373 if not IsInf
and not IsFile
:
2376 if not self
._IsToken
(T_CHAR_BRACE_R
):
2377 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2379 FvObj
.AprioriSectionList
.append(AprSectionObj
)
2382 def _ParseInfStatement(self
):
2383 if not self
._IsKeyword
("INF"):
2386 ffsInf
= FfsInfStatement()
2387 self
._GetInfOptions
(ffsInf
)
2389 if not self
._GetNextToken
():
2390 raise Warning.Expected("INF file path", self
.FileName
, self
.CurrentLineNumber
)
2391 ffsInf
.InfFileName
= self
._Token
2392 if not ffsInf
.InfFileName
.endswith('.inf'):
2393 raise Warning.Expected(".inf file path", self
.FileName
, self
.CurrentLineNumber
)
2395 ffsInf
.CurrentLineNum
= self
.CurrentLineNumber
2396 ffsInf
.CurrentLineContent
= self
._CurrentLine
()
2398 #Replace $(SAPCE) with real space
2399 ffsInf
.InfFileName
= ffsInf
.InfFileName
.replace('$(SPACE)', ' ')
2401 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
2402 #do case sensitive check for file path
2403 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2405 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2407 NewFileName
= ffsInf
.InfFileName
2408 if ffsInf
.OverrideGuid
:
2409 NewFileName
= ProcessDuplicatedInf(PathClass(ffsInf
.InfFileName
,GenFdsGlobalVariable
.WorkSpaceDir
), ffsInf
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
).Path
2411 if not NewFileName
in self
.Profile
.InfList
:
2412 self
.Profile
.InfList
.append(NewFileName
)
2413 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
2414 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
2416 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
2417 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
2419 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
2421 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
2423 if self
._IsToken
(TAB_VALUE_SPLIT
):
2424 if self
._IsKeyword
('RELOCS_STRIPPED'):
2425 ffsInf
.KeepReloc
= False
2426 elif self
._IsKeyword
('RELOCS_RETAINED'):
2427 ffsInf
.KeepReloc
= True
2429 raise Warning("Unknown reloc strip flag '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2432 ## _GetInfStatement() method
2434 # Get INF statements
2436 # @param self The object pointer
2437 # @param Obj for whom inf statement is got
2438 # @retval True Successfully find inf statement
2439 # @retval False Not able to find inf statement
2441 def _GetInfStatement(self
, Obj
, ForCapsule
=False):
2442 ffsInf
= self
._ParseInfStatement
()
2447 myCapsuleFfs
= CapsuleFfs()
2448 myCapsuleFfs
.Ffs
= ffsInf
2449 Obj
.CapsuleDataList
.append(myCapsuleFfs
)
2451 Obj
.FfsList
.append(ffsInf
)
2454 ## _GetInfOptions() method
2456 # Get options for INF
2458 # @param self The object pointer
2459 # @param FfsInfObj for whom option is got
2461 def _GetInfOptions(self
, FfsInfObj
):
2462 if self
._IsKeyword
("FILE_GUID"):
2463 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2464 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2465 if not self
._GetNextGuid
():
2466 raise Warning.Expected("GUID value", self
.FileName
, self
.CurrentLineNumber
)
2467 if self
._Token
in GlobalData
.gGuidDict
:
2468 self
._Token
= GuidStructureStringToGuidString(GlobalData
.gGuidDict
[self
._Token
]).upper()
2469 FfsInfObj
.OverrideGuid
= self
._Token
2471 if self
._IsKeyword
("RuleOverride"):
2472 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2473 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2474 if not self
._GetNextToken
():
2475 raise Warning.Expected("Rule name", self
.FileName
, self
.CurrentLineNumber
)
2476 FfsInfObj
.Rule
= self
._Token
2478 if self
._IsKeyword
("VERSION"):
2479 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2480 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2481 if not self
._GetNextToken
():
2482 raise Warning.Expected("Version", self
.FileName
, self
.CurrentLineNumber
)
2484 if self
._GetStringData
():
2485 FfsInfObj
.Version
= self
._Token
2487 if self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2488 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2489 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2490 if not self
._GetNextToken
():
2491 raise Warning.Expected("UI name", self
.FileName
, self
.CurrentLineNumber
)
2493 if self
._GetStringData
():
2494 FfsInfObj
.Ui
= self
._Token
2496 if self
._IsKeyword
("USE"):
2497 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2498 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2499 if not self
._GetNextToken
():
2500 raise Warning.Expected("ARCH name", self
.FileName
, self
.CurrentLineNumber
)
2501 FfsInfObj
.UseArch
= self
._Token
2504 if self
._GetNextToken
():
2505 p
= compile(r
'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
2506 if p
.match(self
._Token
) and p
.match(self
._Token
).span()[1] == len(self
._Token
):
2507 FfsInfObj
.KeyStringList
.append(self
._Token
)
2508 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2514 while self
._GetNextToken
():
2515 if not p
.match(self
._Token
):
2516 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2517 FfsInfObj
.KeyStringList
.append(self
._Token
)
2519 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2522 ## _GetFileStatement() method
2524 # Get FILE statements
2526 # @param self The object pointer
2527 # @param Obj for whom FILE statement is got
2528 # @retval True Successfully find FILE statement
2529 # @retval False Not able to find FILE statement
2531 def _GetFileStatement(self
, Obj
, ForCapsule
= False):
2532 if not self
._IsKeyword
("FILE"):
2535 if not self
._GetNextWord
():
2536 raise Warning.Expected("FFS type", self
.FileName
, self
.CurrentLineNumber
)
2538 if ForCapsule
and self
._Token
== 'DATA':
2543 FfsFileObj
= FileStatement()
2544 FfsFileObj
.FvFileType
= self
._Token
2546 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2547 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2549 if not self
._GetNextGuid
():
2550 if not self
._GetNextWord
():
2551 raise Warning.Expected("File GUID", self
.FileName
, self
.CurrentLineNumber
)
2552 if self
._Token
== 'PCD':
2553 if not self
._IsToken
("("):
2554 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
2555 PcdPair
= self
._GetNextPcdSettings
()
2556 if not self
._IsToken
(")"):
2557 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
2558 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
2560 if self
._Token
in GlobalData
.gGuidDict
:
2561 self
._Token
= GuidStructureStringToGuidString(GlobalData
.gGuidDict
[self
._Token
]).upper()
2562 FfsFileObj
.NameGuid
= self
._Token
2564 self
._GetFilePart
(FfsFileObj
)
2567 capsuleFfs
= CapsuleFfs()
2568 capsuleFfs
.Ffs
= FfsFileObj
2569 Obj
.CapsuleDataList
.append(capsuleFfs
)
2571 Obj
.FfsList
.append(FfsFileObj
)
2575 ## _FileCouldHaveRelocFlag() method
2577 # Check whether reloc strip flag can be set for a file type.
2579 # @param FileType The file type to check with
2580 # @retval True This type could have relocation strip flag
2581 # @retval False No way to have it
2584 def _FileCouldHaveRelocFlag (FileType
):
2585 if FileType
in {SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
, SUP_MODULE_MM_CORE_STANDALONE
, 'PEI_DXE_COMBO'}:
2590 ## _SectionCouldHaveRelocFlag() method
2592 # Check whether reloc strip flag can be set for a section type.
2594 # @param SectionType The section type to check with
2595 # @retval True This type could have relocation strip flag
2596 # @retval False No way to have it
2599 def _SectionCouldHaveRelocFlag (SectionType
):
2600 if SectionType
in {BINARY_FILE_TYPE_TE
, BINARY_FILE_TYPE_PE32
}:
2605 ## _GetFilePart() method
2607 # Get components for FILE statement
2609 # @param self The object pointer
2610 # @param FfsFileObj for whom component is got
2612 def _GetFilePart(self
, FfsFileObj
):
2613 self
._GetFileOpts
(FfsFileObj
)
2615 if not self
._IsToken
("{"):
2616 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2617 if self
._FileCouldHaveRelocFlag
(FfsFileObj
.FvFileType
):
2618 if self
._Token
== 'RELOCS_STRIPPED':
2619 FfsFileObj
.KeepReloc
= False
2621 FfsFileObj
.KeepReloc
= True
2623 raise Warning("File type %s could not have reloc strip flag%d" % (FfsFileObj
.FvFileType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
2625 if not self
._IsToken
("{"):
2626 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2628 if not self
._GetNextToken
():
2629 raise Warning.Expected("File name or section data", self
.FileName
, self
.CurrentLineNumber
)
2631 if self
._Token
== BINARY_FILE_TYPE_FV
:
2632 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2633 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2634 if not self
._GetNextToken
():
2635 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
2636 FfsFileObj
.FvName
= self
._Token
2638 elif self
._Token
== "FD":
2639 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2640 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2641 if not self
._GetNextToken
():
2642 raise Warning.Expected("FD name", self
.FileName
, self
.CurrentLineNumber
)
2643 FfsFileObj
.FdName
= self
._Token
2645 elif self
._Token
in {TAB_DEFINE
, "APRIORI", "SECTION"}:
2647 self
._GetSectionData
(FfsFileObj
)
2649 elif hasattr(FfsFileObj
, 'FvFileType') and FfsFileObj
.FvFileType
== 'RAW':
2651 self
._GetRAWData
(FfsFileObj
)
2654 FfsFileObj
.CurrentLineNum
= self
.CurrentLineNumber
2655 FfsFileObj
.CurrentLineContent
= self
._CurrentLine
()
2656 FfsFileObj
.FileName
= self
._Token
.replace('$(SPACE)', ' ')
2657 self
._VerifyFile
(FfsFileObj
.FileName
)
2659 if not self
._IsToken
(T_CHAR_BRACE_R
):
2660 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2662 ## _GetRAWData() method
2664 # Get RAW data for FILE statement
2666 # @param self The object pointer
2667 # @param FfsFileObj for whom section is got
2669 def _GetRAWData(self
, FfsFileObj
):
2670 FfsFileObj
.FileName
= []
2671 FfsFileObj
.SubAlignment
= []
2674 if self
._GetAlignment
():
2675 if self
._Token
not in ALIGNMENTS
:
2676 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2677 #For FFS, Auto is default option same to ""
2678 if not self
._Token
== "Auto":
2679 AlignValue
= self
._Token
2680 if not self
._GetNextToken
():
2681 raise Warning.Expected("Filename value", self
.FileName
, self
.CurrentLineNumber
)
2683 FileName
= self
._Token
.replace('$(SPACE)', ' ')
2684 if FileName
== T_CHAR_BRACE_R
:
2686 raise Warning.Expected("Filename value", self
.FileName
, self
.CurrentLineNumber
)
2688 self
._VerifyFile
(FileName
)
2689 File
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
)
2690 FfsFileObj
.FileName
.append(File
.Path
)
2691 FfsFileObj
.SubAlignment
.append(AlignValue
)
2693 if self
._IsToken
(T_CHAR_BRACE_R
):
2697 if len(FfsFileObj
.SubAlignment
) == 1:
2698 FfsFileObj
.SubAlignment
= FfsFileObj
.SubAlignment
[0]
2699 if len(FfsFileObj
.FileName
) == 1:
2700 FfsFileObj
.FileName
= FfsFileObj
.FileName
[0]
2702 ## _GetFileOpts() method
2704 # Get options for FILE statement
2706 # @param self The object pointer
2707 # @param FfsFileObj for whom options is got
2709 def _GetFileOpts(self
, FfsFileObj
):
2710 if self
._GetNextToken
():
2711 if TokenFindPattern
.match(self
._Token
):
2712 FfsFileObj
.KeyStringList
.append(self
._Token
)
2713 if self
._IsToken
(TAB_COMMA_SPLIT
):
2714 while self
._GetNextToken
():
2715 if not TokenFindPattern
.match(self
._Token
):
2716 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
2717 FfsFileObj
.KeyStringList
.append(self
._Token
)
2719 if not self
._IsToken
(TAB_COMMA_SPLIT
):
2725 if self
._IsKeyword
("FIXED", True):
2726 FfsFileObj
.Fixed
= True
2728 if self
._IsKeyword
("CHECKSUM", True):
2729 FfsFileObj
.CheckSum
= True
2731 if self
._GetAlignment
():
2732 if self
._Token
not in ALIGNMENTS
:
2733 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2734 #For FFS, Auto is default option same to ""
2735 if not self
._Token
== "Auto":
2736 FfsFileObj
.Alignment
= self
._Token
2738 ## _GetAlignment() method
2740 # Return the alignment value
2742 # @param self The object pointer
2743 # @retval True Successfully find alignment
2744 # @retval False Not able to find alignment
2746 def _GetAlignment(self
):
2747 if self
._IsKeyword
("Align", True):
2748 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2749 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2751 if not self
._GetNextToken
():
2752 raise Warning.Expected("alignment value", self
.FileName
, self
.CurrentLineNumber
)
2757 ## _GetSectionData() method
2759 # Get section data for FILE statement
2761 # @param self The object pointer
2762 # @param FfsFileObj for whom section is got
2764 def _GetSectionData(self
, FfsFileObj
):
2765 self
._GetDefineStatements
(FfsFileObj
)
2768 IsLeafSection
= self
._GetLeafSection
(FfsFileObj
)
2769 IsEncapSection
= self
._GetEncapsulationSec
(FfsFileObj
)
2770 if not IsLeafSection
and not IsEncapSection
:
2773 ## _GetLeafSection() method
2775 # Get leaf section for Obj
2777 # @param self The object pointer
2778 # @param Obj for whom leaf section is got
2779 # @retval True Successfully find section statement
2780 # @retval False Not able to find section statement
2782 def _GetLeafSection(self
, Obj
):
2783 OldPos
= self
.GetFileBufferPos()
2785 if not self
._IsKeyword
("SECTION"):
2786 if len(Obj
.SectionList
) == 0:
2787 raise Warning.Expected("SECTION", self
.FileName
, self
.CurrentLineNumber
)
2792 if self
._GetAlignment
():
2793 if self
._Token
not in ALIGNMENTS
:
2794 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2795 AlignValue
= self
._Token
2798 if self
._IsKeyword
("BUILD_NUM"):
2799 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2800 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2802 if not self
._GetNextToken
():
2803 raise Warning.Expected("Build number value", self
.FileName
, self
.CurrentLineNumber
)
2805 BuildNum
= self
._Token
2807 if self
._IsKeyword
("VERSION"):
2808 if AlignValue
== 'Auto':
2809 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2810 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2811 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2812 if not self
._GetNextToken
():
2813 raise Warning.Expected("version", self
.FileName
, self
.CurrentLineNumber
)
2814 VerSectionObj
= VerSection()
2815 VerSectionObj
.Alignment
= AlignValue
2816 VerSectionObj
.BuildNum
= BuildNum
2817 if self
._GetStringData
():
2818 VerSectionObj
.StringData
= self
._Token
2820 VerSectionObj
.FileName
= self
._Token
2821 Obj
.SectionList
.append(VerSectionObj
)
2823 elif self
._IsKeyword
(BINARY_FILE_TYPE_UI
):
2824 if AlignValue
== 'Auto':
2825 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2826 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2827 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2828 if not self
._GetNextToken
():
2829 raise Warning.Expected("UI", self
.FileName
, self
.CurrentLineNumber
)
2830 UiSectionObj
= UiSection()
2831 UiSectionObj
.Alignment
= AlignValue
2832 if self
._GetStringData
():
2833 UiSectionObj
.StringData
= self
._Token
2835 UiSectionObj
.FileName
= self
._Token
2836 Obj
.SectionList
.append(UiSectionObj
)
2838 elif self
._IsKeyword
("FV_IMAGE"):
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.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2843 if not self
._GetNextToken
():
2844 raise Warning.Expected("FV name or FV file path", self
.FileName
, self
.CurrentLineNumber
)
2846 FvName
= self
._Token
2849 if self
._IsToken
("{"):
2851 FvObj
.UiFvName
= FvName
.upper()
2852 self
._GetDefineStatements
(FvObj
)
2854 self
._GetBlockStatement
(FvObj
)
2855 self
._GetSetStatements
(FvObj
)
2856 self
._GetFvAlignment
(FvObj
)
2857 self
._GetFvAttributes
(FvObj
)
2860 IsInf
= self
._GetInfStatement
(FvObj
)
2861 IsFile
= self
._GetFileStatement
(FvObj
)
2862 if not IsInf
and not IsFile
:
2865 if not self
._IsToken
(T_CHAR_BRACE_R
):
2866 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
2868 FvImageSectionObj
= FvImageSection()
2869 FvImageSectionObj
.Alignment
= AlignValue
2870 if FvObj
is not None:
2871 FvImageSectionObj
.Fv
= FvObj
2872 FvImageSectionObj
.FvName
= None
2874 FvImageSectionObj
.FvName
= FvName
.upper()
2875 FvImageSectionObj
.FvFileName
= FvName
2877 Obj
.SectionList
.append(FvImageSectionObj
)
2879 elif self
._IsKeyword
("PEI_DEPEX_EXP") or self
._IsKeyword
("DXE_DEPEX_EXP") or self
._IsKeyword
("SMM_DEPEX_EXP"):
2880 if AlignValue
== 'Auto':
2881 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2882 DepexSectionObj
= DepexSection()
2883 DepexSectionObj
.Alignment
= AlignValue
2884 DepexSectionObj
.DepexType
= self
._Token
2886 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2887 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2888 if not self
._IsToken
("{"):
2889 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2890 if not self
._SkipToToken
(T_CHAR_BRACE_R
):
2891 raise Warning.Expected("Depex expression ending '}'", self
.FileName
, self
.CurrentLineNumber
)
2893 DepexSectionObj
.Expression
= self
._SkippedChars
.rstrip(T_CHAR_BRACE_R
)
2894 Obj
.SectionList
.append(DepexSectionObj
)
2896 elif self
._IsKeyword
("SUBTYPE_GUID"):
2897 if AlignValue
== 'Auto':
2898 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2899 SubTypeGuidValue
= None
2900 if not self
._GetNextGuid
():
2901 raise Warning.Expected("GUID", self
.FileName
, self
.CurrentLineNumber
)
2903 SubTypeGuidValue
= self
._Token
2905 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
2906 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
2907 if not self
._GetNextToken
():
2908 raise Warning.Expected("section file path", self
.FileName
, self
.CurrentLineNumber
)
2909 FileName
= self
._Token
2911 SubTypeGuidSectionObj
= SubTypeGuidSection()
2912 SubTypeGuidSectionObj
.Alignment
= AlignValue
2913 SubTypeGuidSectionObj
.SubTypeGuid
= SubTypeGuidValue
2914 SubTypeGuidSectionObj
.SectFileName
= FileName
2915 Obj
.SectionList
.append(SubTypeGuidSectionObj
)
2918 if not self
._GetNextWord
():
2919 raise Warning.Expected("section type", self
.FileName
, self
.CurrentLineNumber
)
2921 # Encapsulation section appear, UndoToken and return
2922 if self
._Token
== "COMPRESS" or self
._Token
== "GUIDED":
2923 self
.SetFileBufferPos(OldPos
)
2926 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
,\
2927 BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "SUBTYPE_GUID", BINARY_FILE_TYPE_SMM_DEPEX
}:
2928 raise Warning("Unknown section type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
2929 if AlignValue
== 'Auto'and (not self
._Token
== BINARY_FILE_TYPE_PE32
) and (not self
._Token
== BINARY_FILE_TYPE_TE
):
2930 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
2933 DataSectionObj
= DataSection()
2934 DataSectionObj
.Alignment
= AlignValue
2935 DataSectionObj
.SecType
= self
._Token
2937 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
2938 if self
._FileCouldHaveRelocFlag
(Obj
.FvFileType
) and self
._SectionCouldHaveRelocFlag
(DataSectionObj
.SecType
):
2939 if self
._Token
== 'RELOCS_STRIPPED':
2940 DataSectionObj
.KeepReloc
= False
2942 DataSectionObj
.KeepReloc
= True
2944 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
)
2946 if self
._IsToken
(TAB_EQUAL_SPLIT
):
2947 if not self
._GetNextToken
():
2948 raise Warning.Expected("section file path", self
.FileName
, self
.CurrentLineNumber
)
2949 DataSectionObj
.SectFileName
= self
._Token
2950 self
._VerifyFile
(DataSectionObj
.SectFileName
)
2952 if not self
._GetCglSection
(DataSectionObj
):
2955 Obj
.SectionList
.append(DataSectionObj
)
2961 # Check if file exists or not:
2962 # If current phase if GenFds, the file must exist;
2963 # If current phase is AutoGen and the file is not in $(OUTPUT_DIRECTORY), the file must exist
2964 # @param FileName: File path to be verified.
2966 def _VerifyFile(self
, FileName
):
2967 if FileName
.replace(TAB_WORKSPACE
, '').find('$') != -1:
2969 if not GlobalData
.gAutoGenPhase
or not self
._GetMacroValue
(TAB_DSC_DEFINES_OUTPUT_DIRECTORY
) in FileName
:
2970 ErrorCode
, ErrorInfo
= PathClass(NormPath(FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
2972 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
2974 ## _GetCglSection() method
2976 # Get compressed or GUIDed section for Obj
2978 # @param self The object pointer
2979 # @param Obj for whom leaf section is got
2980 # @param AlignValue alignment value for complex section
2981 # @retval True Successfully find section statement
2982 # @retval False Not able to find section statement
2984 def _GetCglSection(self
, Obj
, AlignValue
= None):
2986 if self
._IsKeyword
("COMPRESS"):
2988 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
2991 if not self
._IsToken
("{"):
2992 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
2994 CompressSectionObj
= CompressSection()
2995 CompressSectionObj
.Alignment
= AlignValue
2996 CompressSectionObj
.CompType
= type
2997 # Recursive sections...
2999 IsLeafSection
= self
._GetLeafSection
(CompressSectionObj
)
3000 IsEncapSection
= self
._GetEncapsulationSec
(CompressSectionObj
)
3001 if not IsLeafSection
and not IsEncapSection
:
3005 if not self
._IsToken
(T_CHAR_BRACE_R
):
3006 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3007 Obj
.SectionList
.append(CompressSectionObj
)
3010 elif self
._IsKeyword
("GUIDED"):
3012 if self
._GetNextGuid
():
3013 if self
._Token
in GlobalData
.gGuidDict
:
3014 self
._Token
= GuidStructureStringToGuidString(GlobalData
.gGuidDict
[self
._Token
]).upper()
3015 GuidValue
= self
._Token
3017 AttribDict
= self
._GetGuidAttrib
()
3018 if not self
._IsToken
("{"):
3019 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
3020 GuidSectionObj
= GuidSection()
3021 GuidSectionObj
.Alignment
= AlignValue
3022 GuidSectionObj
.NameGuid
= GuidValue
3023 GuidSectionObj
.SectionType
= "GUIDED"
3024 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
3025 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
3026 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
3027 # Recursive sections...
3029 IsLeafSection
= self
._GetLeafSection
(GuidSectionObj
)
3030 IsEncapSection
= self
._GetEncapsulationSec
(GuidSectionObj
)
3031 if not IsLeafSection
and not IsEncapSection
:
3034 if not self
._IsToken
(T_CHAR_BRACE_R
):
3035 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3036 Obj
.SectionList
.append(GuidSectionObj
)
3042 ## _GetGuidAttri() method
3044 # Get attributes for GUID section
3046 # @param self The object pointer
3047 # @retval AttribDict Dictionary of key-value pair of section attributes
3049 def _GetGuidAttrib(self
):
3051 AttribDict
["PROCESSING_REQUIRED"] = "NONE"
3052 AttribDict
["AUTH_STATUS_VALID"] = "NONE"
3053 AttribDict
["EXTRA_HEADER_SIZE"] = -1
3054 while self
._IsKeyword
("PROCESSING_REQUIRED") or self
._IsKeyword
("AUTH_STATUS_VALID") \
3055 or self
._IsKeyword
("EXTRA_HEADER_SIZE"):
3056 AttribKey
= self
._Token
3058 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3059 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3061 if not self
._GetNextToken
():
3062 raise Warning.Expected("TRUE(1)/FALSE(0)/Number", self
.FileName
, self
.CurrentLineNumber
)
3063 elif AttribKey
== "EXTRA_HEADER_SIZE":
3065 if self
._Token
[0:2].upper() == "0X":
3068 AttribDict
[AttribKey
] = int(self
._Token
, Base
)
3071 raise Warning.Expected("Number", self
.FileName
, self
.CurrentLineNumber
)
3072 elif self
._Token
.upper() not in {"TRUE", "FALSE", "1", "0"}:
3073 raise Warning.Expected("TRUE/FALSE (1/0)", self
.FileName
, self
.CurrentLineNumber
)
3074 AttribDict
[AttribKey
] = self
._Token
3078 ## _GetEncapsulationSec() method
3080 # Get encapsulation section for FILE
3082 # @param self The object pointer
3083 # @param FfsFile for whom section is got
3084 # @retval True Successfully find section statement
3085 # @retval False Not able to find section statement
3087 def _GetEncapsulationSec(self
, FfsFileObj
):
3088 OldPos
= self
.GetFileBufferPos()
3089 if not self
._IsKeyword
("SECTION"):
3090 if len(FfsFileObj
.SectionList
) == 0:
3091 raise Warning.Expected("SECTION", self
.FileName
, self
.CurrentLineNumber
)
3096 if self
._GetAlignment
():
3097 if self
._Token
not in ALIGNMENT_NOAUTO
:
3098 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3099 AlignValue
= self
._Token
3101 if not self
._GetCglSection
(FfsFileObj
, AlignValue
):
3102 self
.SetFileBufferPos(OldPos
)
3108 if not self
._GetNextToken
():
3110 S
= self
._Token
.upper()
3111 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[FMPPAYLOAD."):
3112 self
.SectionParser(S
)
3117 self
._SkipToToken
("[FMPPAYLOAD.", True)
3118 FmpUiName
= self
._GetUiName
().upper()
3119 if FmpUiName
in self
.Profile
.FmpPayloadDict
:
3120 raise Warning("Duplicated FMP UI name found: %s" % FmpUiName
, self
.FileName
, self
.CurrentLineNumber
)
3122 FmpData
= CapsulePayload()
3123 FmpData
.UiName
= FmpUiName
3125 if not self
._IsToken
(TAB_SECTION_END
):
3126 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3128 if not self
._GetNextToken
():
3129 raise Warning("The FMP payload section is empty!", self
.FileName
, self
.CurrentLineNumber
)
3130 FmpKeyList
= ['IMAGE_HEADER_INIT_VERSION', 'IMAGE_TYPE_ID', 'IMAGE_INDEX', 'HARDWARE_INSTANCE', 'CERTIFICATE_GUID', 'MONOTONIC_COUNT']
3131 while self
._Token
in FmpKeyList
:
3133 FmpKeyList
.remove(Name
)
3134 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3135 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3136 if Name
== 'IMAGE_TYPE_ID':
3137 if not self
._GetNextGuid
():
3138 raise Warning.Expected("GUID value for IMAGE_TYPE_ID.", self
.FileName
, self
.CurrentLineNumber
)
3139 FmpData
.ImageTypeId
= self
._Token
3140 elif Name
== 'CERTIFICATE_GUID':
3141 if not self
._GetNextGuid
():
3142 raise Warning.Expected("GUID value for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3143 FmpData
.Certificate_Guid
= self
._Token
3144 if UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_RSA2048_SHA256_GUID
and UUID(FmpData
.Certificate_Guid
) != EFI_CERT_TYPE_PKCS7_GUID
:
3145 raise Warning("Only support EFI_CERT_TYPE_RSA2048_SHA256_GUID or EFI_CERT_TYPE_PKCS7_GUID for CERTIFICATE_GUID.", self
.FileName
, self
.CurrentLineNumber
)
3147 if not self
._GetNextToken
():
3148 raise Warning.Expected("value of %s" % Name
, self
.FileName
, self
.CurrentLineNumber
)
3150 if Name
== 'IMAGE_HEADER_INIT_VERSION':
3151 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3152 FmpData
.Version
= Value
3153 elif Name
== 'IMAGE_INDEX':
3154 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3155 FmpData
.ImageIndex
= Value
3156 elif Name
== 'HARDWARE_INSTANCE':
3157 if FdfParser
._Verify
(Name
, Value
, 'UINT8'):
3158 FmpData
.HardwareInstance
= Value
3159 elif Name
== 'MONOTONIC_COUNT':
3160 if FdfParser
._Verify
(Name
, Value
, 'UINT64'):
3161 FmpData
.MonotonicCount
= Value
3162 if FmpData
.MonotonicCount
.upper().startswith('0X'):
3163 FmpData
.MonotonicCount
= int(FmpData
.MonotonicCount
, 16)
3165 FmpData
.MonotonicCount
= int(FmpData
.MonotonicCount
)
3166 if not self
._GetNextToken
():
3171 if (FmpData
.MonotonicCount
and not FmpData
.Certificate_Guid
) or (not FmpData
.MonotonicCount
and FmpData
.Certificate_Guid
):
3172 EdkLogger
.error("FdfParser", FORMAT_INVALID
, "CERTIFICATE_GUID and MONOTONIC_COUNT must be work as a pair.")
3174 # Only the IMAGE_TYPE_ID is required item
3175 if FmpKeyList
and 'IMAGE_TYPE_ID' in FmpKeyList
:
3176 raise Warning("'IMAGE_TYPE_ID' in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3177 # get the Image file and Vendor code file
3178 self
._GetFMPCapsuleData
(FmpData
)
3179 if not FmpData
.ImageFile
:
3180 raise Warning("Missing image file in FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3181 # check whether more than one Vendor code file
3182 if len(FmpData
.VendorCodeFile
) > 1:
3183 raise Warning("Vendor code file max of 1 per FMP payload section.", self
.FileName
, self
.CurrentLineNumber
)
3184 self
.Profile
.FmpPayloadDict
[FmpUiName
] = FmpData
3187 ## _GetCapsule() method
3189 # Get capsule section contents and store its data into capsule list of self.Profile
3191 # @param self The object pointer
3192 # @retval True Successfully find a capsule
3193 # @retval False Not able to find a capsule
3195 def _GetCapsule(self
):
3196 if not self
._GetNextToken
():
3199 S
= self
._Token
.upper()
3200 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[CAPSULE."):
3201 self
.SectionParser(S
)
3206 if not self
._IsToken
("[CAPSULE.", True):
3207 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3208 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3209 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3210 raise Warning.Expected("[Capsule.]", self
.FileName
, self
.CurrentLineNumber
)
3212 CapsuleObj
= Capsule()
3214 CapsuleName
= self
._GetUiName
()
3216 raise Warning.Expected("capsule name", self
.FileName
, self
.CurrentLineNumber
)
3218 CapsuleObj
.UiCapsuleName
= CapsuleName
.upper()
3220 if not self
._IsToken
(TAB_SECTION_END
):
3221 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
3223 if self
._IsKeyword
("CREATE_FILE"):
3224 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3225 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3227 if not self
._GetNextToken
():
3228 raise Warning.Expected("file name", self
.FileName
, self
.CurrentLineNumber
)
3230 CapsuleObj
.CreateFile
= self
._Token
3232 self
._GetCapsuleStatements
(CapsuleObj
)
3233 self
.Profile
.CapsuleDict
[CapsuleObj
.UiCapsuleName
] = CapsuleObj
3236 ## _GetCapsuleStatements() method
3238 # Get statements for capsule
3240 # @param self The object pointer
3241 # @param Obj for whom statements are got
3243 def _GetCapsuleStatements(self
, Obj
):
3244 self
._GetCapsuleTokens
(Obj
)
3245 self
._GetDefineStatements
(Obj
)
3246 self
._GetSetStatements
(Obj
)
3247 self
._GetCapsuleData
(Obj
)
3249 ## _GetCapsuleTokens() method
3251 # Get token statements for capsule
3253 # @param self The object pointer
3254 # @param Obj for whom token statements are got
3256 def _GetCapsuleTokens(self
, Obj
):
3257 if not self
._GetNextToken
():
3259 while self
._Token
in {"CAPSULE_GUID", "CAPSULE_HEADER_SIZE", "CAPSULE_FLAGS", "OEM_CAPSULE_FLAGS", "CAPSULE_HEADER_INIT_VERSION"}:
3260 Name
= self
._Token
.strip()
3261 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3262 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3263 if not self
._GetNextToken
():
3264 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
3265 if Name
== 'CAPSULE_FLAGS':
3266 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3267 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3268 Value
= self
._Token
.strip()
3269 while self
._IsToken
(TAB_COMMA_SPLIT
):
3270 Value
+= TAB_COMMA_SPLIT
3271 if not self
._GetNextToken
():
3272 raise Warning.Expected("value", self
.FileName
, self
.CurrentLineNumber
)
3273 if not self
._Token
in {"PersistAcrossReset", "PopulateSystemTable", "InitiateReset"}:
3274 raise Warning.Expected("PersistAcrossReset, PopulateSystemTable, or InitiateReset", self
.FileName
, self
.CurrentLineNumber
)
3275 Value
+= self
._Token
.strip()
3276 elif Name
== 'OEM_CAPSULE_FLAGS':
3277 Value
= self
._Token
.strip()
3278 if not Value
.upper().startswith('0X'):
3279 raise Warning.Expected("hex value starting with 0x", self
.FileName
, self
.CurrentLineNumber
)
3281 Value
= int(Value
, 0)
3283 raise Warning.Expected("hex string failed to convert to value", self
.FileName
, self
.CurrentLineNumber
)
3284 if not 0x0000 <= Value
<= 0xFFFF:
3285 raise Warning.Expected("hex value between 0x0000 and 0xFFFF", self
.FileName
, self
.CurrentLineNumber
)
3286 Value
= self
._Token
.strip()
3288 Value
= self
._Token
.strip()
3289 Obj
.TokensDict
[Name
] = Value
3290 if not self
._GetNextToken
():
3294 ## _GetCapsuleData() method
3296 # Get capsule data for capsule
3298 # @param self The object pointer
3299 # @param Obj for whom capsule data are got
3301 def _GetCapsuleData(self
, Obj
):
3303 IsInf
= self
._GetInfStatement
(Obj
, True)
3304 IsFile
= self
._GetFileStatement
(Obj
, True)
3305 IsFv
= self
._GetFvStatement
(Obj
)
3306 IsFd
= self
._GetFdStatement
(Obj
)
3307 IsAnyFile
= self
._GetAnyFileStatement
(Obj
)
3308 IsAfile
= self
._GetAfileStatement
(Obj
)
3309 IsFmp
= self
._GetFmpStatement
(Obj
)
3310 if not (IsInf
or IsFile
or IsFv
or IsFd
or IsAnyFile
or IsAfile
or IsFmp
):
3313 ## _GetFMPCapsuleData() method
3315 # Get capsule data for FMP capsule
3317 # @param self The object pointer
3318 # @param Obj for whom capsule data are got
3320 def _GetFMPCapsuleData(self
, Obj
):
3322 IsFv
= self
._GetFvStatement
(Obj
, True)
3323 IsFd
= self
._GetFdStatement
(Obj
, True)
3324 IsAnyFile
= self
._GetAnyFileStatement
(Obj
, True)
3325 if not (IsFv
or IsFd
or IsAnyFile
):
3328 ## _GetFvStatement() method
3330 # Get FV for capsule
3332 # @param self The object pointer
3333 # @param CapsuleObj for whom FV is got
3334 # @retval True Successfully find a FV statement
3335 # @retval False Not able to find a FV statement
3337 def _GetFvStatement(self
, CapsuleObj
, FMPCapsule
= False):
3338 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3341 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3342 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3344 if not self
._GetNextToken
():
3345 raise Warning.Expected("FV name", self
.FileName
, self
.CurrentLineNumber
)
3347 if self
._Token
.upper() not in self
.Profile
.FvDict
:
3348 raise Warning("FV name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3350 myCapsuleFv
= CapsuleFv()
3351 myCapsuleFv
.FvName
= self
._Token
3353 if not CapsuleObj
.ImageFile
:
3354 CapsuleObj
.ImageFile
.append(myCapsuleFv
)
3356 CapsuleObj
.VendorCodeFile
.append(myCapsuleFv
)
3358 CapsuleObj
.CapsuleDataList
.append(myCapsuleFv
)
3361 ## _GetFdStatement() method
3363 # Get FD for capsule
3365 # @param self The object pointer
3366 # @param CapsuleObj for whom FD is got
3367 # @retval True Successfully find a FD statement
3368 # @retval False Not able to find a FD statement
3370 def _GetFdStatement(self
, CapsuleObj
, FMPCapsule
= False):
3371 if not self
._IsKeyword
("FD"):
3374 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3375 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3377 if not self
._GetNextToken
():
3378 raise Warning.Expected("FD name", self
.FileName
, self
.CurrentLineNumber
)
3380 if self
._Token
.upper() not in self
.Profile
.FdDict
:
3381 raise Warning("FD name does not exist", self
.FileName
, self
.CurrentLineNumber
)
3383 myCapsuleFd
= CapsuleFd()
3384 myCapsuleFd
.FdName
= self
._Token
3386 if not CapsuleObj
.ImageFile
:
3387 CapsuleObj
.ImageFile
.append(myCapsuleFd
)
3389 CapsuleObj
.VendorCodeFile
.append(myCapsuleFd
)
3391 CapsuleObj
.CapsuleDataList
.append(myCapsuleFd
)
3394 def _GetFmpStatement(self
, CapsuleObj
):
3395 if not self
._IsKeyword
("FMP_PAYLOAD"):
3396 if not self
._IsKeyword
("FMP"):
3399 if not self
._IsKeyword
("PAYLOAD"):
3403 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3404 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3406 if not self
._GetNextToken
():
3407 raise Warning.Expected("payload name after FMP_PAYLOAD =", self
.FileName
, self
.CurrentLineNumber
)
3408 Payload
= self
._Token
.upper()
3409 if Payload
not in self
.Profile
.FmpPayloadDict
:
3410 raise Warning("This FMP Payload does not exist: %s" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3411 CapsuleObj
.FmpPayloadList
.append(self
.Profile
.FmpPayloadDict
[Payload
])
3414 def _ParseRawFileStatement(self
):
3415 if not self
._IsKeyword
("FILE"):
3418 if not self
._IsKeyword
("DATA"):
3422 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3423 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3425 if not self
._GetNextToken
():
3426 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
3428 AnyFileName
= self
._Token
3429 self
._VerifyFile
(AnyFileName
)
3431 if not os
.path
.isabs(AnyFileName
):
3432 AnyFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, AnyFileName
)
3436 ## _GetAnyFileStatement() method
3438 # Get AnyFile for capsule
3440 # @param self The object pointer
3441 # @param CapsuleObj for whom AnyFile is got
3442 # @retval True Successfully find a Anyfile statement
3443 # @retval False Not able to find a AnyFile statement
3445 def _GetAnyFileStatement(self
, CapsuleObj
, FMPCapsule
= False):
3446 AnyFileName
= self
._ParseRawFileStatement
()
3450 myCapsuleAnyFile
= CapsuleAnyFile()
3451 myCapsuleAnyFile
.FileName
= AnyFileName
3453 if not CapsuleObj
.ImageFile
:
3454 CapsuleObj
.ImageFile
.append(myCapsuleAnyFile
)
3456 CapsuleObj
.VendorCodeFile
.append(myCapsuleAnyFile
)
3458 CapsuleObj
.CapsuleDataList
.append(myCapsuleAnyFile
)
3461 ## _GetAfileStatement() method
3463 # Get Afile for capsule
3465 # @param self The object pointer
3466 # @param CapsuleObj for whom Afile is got
3467 # @retval True Successfully find a Afile statement
3468 # @retval False Not able to find a Afile statement
3470 def _GetAfileStatement(self
, CapsuleObj
):
3471 if not self
._IsKeyword
("APPEND"):
3474 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3475 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3477 if not self
._GetNextToken
():
3478 raise Warning.Expected("Afile name", self
.FileName
, self
.CurrentLineNumber
)
3480 AfileName
= self
._Token
3481 AfileBaseName
= os
.path
.basename(AfileName
)
3483 if os
.path
.splitext(AfileBaseName
)[1] not in {".bin", ".BIN", ".Bin", ".dat", ".DAT", ".Dat", ".data", ".DATA", ".Data"}:
3484 raise Warning('invalid binary file type, should be one of "bin",BINARY_FILE_TYPE_BIN,"Bin","dat","DAT","Dat","data","DATA","Data"', \
3485 self
.FileName
, self
.CurrentLineNumber
)
3487 if not os
.path
.isabs(AfileName
):
3488 AfileName
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(AfileName
)
3489 self
._VerifyFile
(AfileName
)
3491 if not os
.path
.exists(AfileName
):
3492 raise Warning('%s does not exist' % AfileName
, self
.FileName
, self
.CurrentLineNumber
)
3496 myCapsuleAfile
= CapsuleAfile()
3497 myCapsuleAfile
.FileName
= AfileName
3498 CapsuleObj
.CapsuleDataList
.append(myCapsuleAfile
)
3501 ## _GetRule() method
3503 # Get Rule section contents and store its data into rule list of self.Profile
3505 # @param self The object pointer
3506 # @retval True Successfully find a Rule
3507 # @retval False Not able to find a Rule
3510 if not self
._GetNextToken
():
3513 S
= self
._Token
.upper()
3514 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[RULE."):
3515 self
.SectionParser(S
)
3519 if not self
._IsToken
("[Rule.", True):
3520 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
3521 #print 'Parsing String: %s in File %s, At line: %d, Offset Within Line: %d' \
3522 # % (self.Profile.FileLinesList[self.CurrentLineNumber - 1][self.CurrentOffsetWithinLine:], FileLineTuple[0], FileLineTuple[1], self.CurrentOffsetWithinLine)
3523 raise Warning.Expected("[Rule.]", self
.FileName
, self
.CurrentLineNumber
)
3525 if not self
._SkipToToken
(TAB_SPLIT
):
3526 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
3528 Arch
= self
._SkippedChars
.rstrip(TAB_SPLIT
)
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.ExpectedBracketClose(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 {
3572 SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3573 SUP_MODULE_DXE_CORE
, SUP_MODULE_DXE_DRIVER
,
3574 SUP_MODULE_DXE_SAL_DRIVER
, SUP_MODULE_DXE_SMM_DRIVER
,
3575 SUP_MODULE_DXE_RUNTIME_DRIVER
, SUP_MODULE_UEFI_DRIVER
,
3576 SUP_MODULE_UEFI_APPLICATION
, SUP_MODULE_USER_DEFINED
, SUP_MODULE_HOST_APPLICATION
,
3577 TAB_DEFAULT
, SUP_MODULE_BASE
,
3578 EDK_COMPONENT_TYPE_SECURITY_CORE
,
3579 EDK_COMPONENT_TYPE_COMBINED_PEIM_DRIVER
,
3580 EDK_COMPONENT_TYPE_PIC_PEIM
,
3581 EDK_COMPONENT_TYPE_RELOCATABLE_PEIM
, "PE32_PEIM",
3582 EDK_COMPONENT_TYPE_BS_DRIVER
, EDK_COMPONENT_TYPE_RT_DRIVER
,
3583 EDK_COMPONENT_TYPE_SAL_RT_DRIVER
,
3584 EDK_COMPONENT_TYPE_APPLICATION
, "ACPITABLE",
3585 SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3586 SUP_MODULE_MM_CORE_STANDALONE
}:
3587 raise Warning("Unknown Module type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3590 ## _GetFileExtension() method
3592 # Return the file extension
3594 # @param self The object pointer
3595 # @retval string file name extension
3597 def _GetFileExtension(self
):
3598 if not self
._IsToken
(TAB_SPLIT
):
3599 raise Warning.Expected("'.'", self
.FileName
, self
.CurrentLineNumber
)
3602 if self
._GetNextToken
():
3603 if FileExtensionPattern
.match(self
._Token
):
3605 return TAB_SPLIT
+ Ext
3607 raise Warning("Unknown file extension '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3610 raise Warning.Expected("file extension", self
.FileName
, self
.CurrentLineNumber
)
3612 ## _GetRuleFileStatement() method
3616 # @param self The object pointer
3617 # @retval Rule Rule object
3619 def _GetRuleFileStatements(self
):
3620 if not self
._IsKeyword
("FILE"):
3621 raise Warning.Expected("FILE", self
.FileName
, self
.CurrentLineNumber
)
3623 if not self
._GetNextWord
():
3624 raise Warning.Expected("FFS type", self
.FileName
, self
.CurrentLineNumber
)
3626 Type
= self
._Token
.strip().upper()
3627 if Type
not in {"RAW", "FREEFORM", SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
,
3628 "PEI_DXE_COMBO", "DRIVER", SUP_MODULE_DXE_CORE
, EDK_COMPONENT_TYPE_APPLICATION
,
3629 "FV_IMAGE", "SMM", SUP_MODULE_SMM_CORE
, SUP_MODULE_MM_STANDALONE
,
3630 SUP_MODULE_MM_CORE_STANDALONE
}:
3631 raise Warning("Unknown FV type '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3633 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3634 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3636 if not self
._IsKeyword
("$(NAMED_GUID)"):
3637 if not self
._GetNextWord
():
3638 NamedGuid
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:].split()[0].strip()
3639 if GlobalData
.gGuidPatternEnd
.match(NamedGuid
):
3640 self
.CurrentOffsetWithinLine
+= len(NamedGuid
)
3641 self
._Token
= NamedGuid
3643 raise Warning.Expected("$(NAMED_GUID)", self
.FileName
, self
.CurrentLineNumber
)
3644 if self
._Token
== 'PCD':
3645 if not self
._IsToken
("("):
3646 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3647 PcdPair
= self
._GetNextPcdSettings
()
3648 if not self
._IsToken
(")"):
3649 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3650 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3652 NameGuid
= self
._Token
3655 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3656 if self
._FileCouldHaveRelocFlag
(Type
):
3657 if self
._Token
== 'RELOCS_STRIPPED':
3662 raise Warning("File type %s could not have reloc strip flag%d" % (Type
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3665 if self
._GetNextToken
():
3666 if TokenFindPattern
.match(self
._Token
):
3667 KeyStringList
.append(self
._Token
)
3668 if self
._IsToken
(TAB_COMMA_SPLIT
):
3669 while self
._GetNextToken
():
3670 if not TokenFindPattern
.match(self
._Token
):
3671 raise Warning.Expected("KeyString \"Target_Tag_Arch\"", self
.FileName
, self
.CurrentLineNumber
)
3672 KeyStringList
.append(self
._Token
)
3674 if not self
._IsToken
(TAB_COMMA_SPLIT
):
3682 if self
._IsKeyword
("Fixed", True):
3686 if self
._IsKeyword
("CheckSum", True):
3690 if self
._GetAlignment
():
3691 if self
._Token
not in ALIGNMENTS
:
3692 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3693 #For FFS, Auto is default option same to ""
3694 if not self
._Token
== "Auto":
3695 AlignValue
= self
._Token
3697 if self
._IsToken
("{"):
3698 # Complex file rule expected
3699 NewRule
= RuleComplexFile()
3700 NewRule
.FvFileType
= Type
3701 NewRule
.NameGuid
= NameGuid
3702 NewRule
.Alignment
= AlignValue
3703 NewRule
.CheckSum
= CheckSum
3704 NewRule
.Fixed
= Fixed
3705 NewRule
.KeyStringList
= KeyStringList
3706 if KeepReloc
is not None:
3707 NewRule
.KeepReloc
= KeepReloc
3710 IsEncapsulate
= self
._GetRuleEncapsulationSection
(NewRule
)
3711 IsLeaf
= self
._GetEfiSection
(NewRule
)
3712 if not IsEncapsulate
and not IsLeaf
:
3715 if not self
._IsToken
(T_CHAR_BRACE_R
):
3716 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3721 # Simple file rule expected
3722 if not self
._GetNextWord
():
3723 raise Warning.Expected("leaf section type", self
.FileName
, self
.CurrentLineNumber
)
3725 SectionName
= self
._Token
3727 if SectionName
not in {
3728 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3729 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3730 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3731 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3732 BINARY_FILE_TYPE_SMM_DEPEX
}:
3733 raise Warning("Unknown leaf section name '%s'" % SectionName
, self
.FileName
, self
.CurrentLineNumber
)
3736 if self
._IsKeyword
("Fixed", True):
3739 if self
._IsKeyword
("CheckSum", True):
3743 if self
._GetAlignment
():
3744 if self
._Token
not in ALIGNMENTS
:
3745 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3746 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3747 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3748 SectAlignment
= self
._Token
3751 if self
._IsToken
(TAB_VALUE_SPLIT
):
3752 Ext
= self
._GetFileExtension
()
3753 elif not self
._GetNextToken
():
3754 raise Warning.Expected("File name", self
.FileName
, self
.CurrentLineNumber
)
3756 NewRule
= RuleSimpleFile()
3757 NewRule
.SectionType
= SectionName
3758 NewRule
.FvFileType
= Type
3759 NewRule
.NameGuid
= NameGuid
3760 NewRule
.Alignment
= AlignValue
3761 NewRule
.SectAlignment
= SectAlignment
3762 NewRule
.CheckSum
= CheckSum
3763 NewRule
.Fixed
= Fixed
3764 NewRule
.KeyStringList
= KeyStringList
3765 if KeepReloc
is not None:
3766 NewRule
.KeepReloc
= KeepReloc
3767 NewRule
.FileExtension
= Ext
3768 NewRule
.FileName
= self
._Token
3771 ## _GetEfiSection() method
3773 # Get section list for Rule
3775 # @param self The object pointer
3776 # @param Obj for whom section is got
3777 # @retval True Successfully find section statement
3778 # @retval False Not able to find section statement
3780 def _GetEfiSection(self
, Obj
):
3781 OldPos
= self
.GetFileBufferPos()
3782 EfiSectionObj
= EfiSection()
3783 if not self
._GetNextWord
():
3784 CurrentLine
= self
._CurrentLine
()[self
.CurrentOffsetWithinLine
:].split()[0].strip()
3785 if self
._Token
== '{' and Obj
.FvFileType
== "RAW" and TAB_SPLIT
in CurrentLine
:
3786 if self
._IsToken
(TAB_VALUE_SPLIT
):
3787 EfiSectionObj
.FileExtension
= self
._GetFileExtension
()
3788 elif self
._GetNextToken
():
3789 EfiSectionObj
.FileName
= self
._Token
3790 EfiSectionObj
.SectionType
= BINARY_FILE_TYPE_RAW
3791 Obj
.SectionList
.append(EfiSectionObj
)
3795 SectionName
= self
._Token
3797 if SectionName
not in {
3798 "COMPAT16", BINARY_FILE_TYPE_PE32
,
3799 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
, "FV_IMAGE",
3800 "RAW",BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
,
3801 BINARY_FILE_TYPE_PEI_DEPEX
, "VERSION", "SUBTYPE_GUID",
3802 BINARY_FILE_TYPE_SMM_DEPEX
, BINARY_FILE_TYPE_GUID
}:
3806 if SectionName
== "FV_IMAGE":
3807 FvImageSectionObj
= FvImageSection()
3808 if self
._IsKeyword
("FV_IMAGE"):
3810 if self
._IsToken
("{"):
3812 self
._GetDefineStatements
(FvObj
)
3813 self
._GetBlockStatement
(FvObj
)
3814 self
._GetSetStatements
(FvObj
)
3815 self
._GetFvAlignment
(FvObj
)
3816 self
._GetFvAttributes
(FvObj
)
3817 self
._GetAprioriSection
(FvObj
)
3818 self
._GetAprioriSection
(FvObj
)
3821 IsInf
= self
._GetInfStatement
(FvObj
)
3822 IsFile
= self
._GetFileStatement
(FvObj
)
3823 if not IsInf
and not IsFile
:
3826 if not self
._IsToken
(T_CHAR_BRACE_R
):
3827 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
3828 FvImageSectionObj
.Fv
= FvObj
3829 FvImageSectionObj
.FvName
= None
3832 if not self
._IsKeyword
(BINARY_FILE_TYPE_FV
):
3833 raise Warning.Expected("'FV'", self
.FileName
, self
.CurrentLineNumber
)
3834 FvImageSectionObj
.FvFileType
= self
._Token
3836 if self
._GetAlignment
():
3837 if self
._Token
not in ALIGNMENT_NOAUTO
:
3838 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3839 FvImageSectionObj
.Alignment
= self
._Token
3841 if self
._IsToken
(TAB_VALUE_SPLIT
):
3842 FvImageSectionObj
.FvFileExtension
= self
._GetFileExtension
()
3843 elif self
._GetNextToken
():
3844 if self
._Token
not in {
3845 T_CHAR_BRACE_R
, "COMPAT16", BINARY_FILE_TYPE_PE32
,
3846 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3847 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3848 BINARY_FILE_TYPE_UI
, "VERSION",
3849 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3850 BINARY_FILE_TYPE_SMM_DEPEX
}:
3851 FvImageSectionObj
.FvFileName
= self
._Token
3855 raise Warning.Expected("FV file name", self
.FileName
, self
.CurrentLineNumber
)
3857 Obj
.SectionList
.append(FvImageSectionObj
)
3860 EfiSectionObj
.SectionType
= SectionName
3862 if not self
._GetNextToken
():
3863 raise Warning.Expected("file type", self
.FileName
, self
.CurrentLineNumber
)
3865 if self
._Token
== "STRING":
3866 if not self
._RuleSectionCouldHaveString
(EfiSectionObj
.SectionType
):
3867 raise Warning("%s section could NOT have string data%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3869 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3870 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3872 if not self
._GetNextToken
():
3873 raise Warning.Expected("Quoted String", self
.FileName
, self
.CurrentLineNumber
)
3875 if self
._GetStringData
():
3876 EfiSectionObj
.StringData
= self
._Token
3878 if self
._IsKeyword
("BUILD_NUM"):
3879 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3880 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3882 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3883 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3884 if not self
._GetNextToken
():
3885 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3886 EfiSectionObj
.BuildNum
= self
._Token
3889 EfiSectionObj
.FileType
= self
._Token
3890 self
._CheckRuleSectionFileType
(EfiSectionObj
.SectionType
, EfiSectionObj
.FileType
)
3892 if self
._IsKeyword
("Optional"):
3893 if not self
._RuleSectionCouldBeOptional
(EfiSectionObj
.SectionType
):
3894 raise Warning("%s section could NOT be optional%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3895 EfiSectionObj
.Optional
= True
3897 if self
._IsKeyword
("BUILD_NUM"):
3898 if not self
._RuleSectionCouldHaveBuildNum
(EfiSectionObj
.SectionType
):
3899 raise Warning("%s section could NOT have BUILD_NUM%d" % (EfiSectionObj
.SectionType
, self
.CurrentLineNumber
), self
.FileName
, self
.CurrentLineNumber
)
3901 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
3902 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
3903 if not self
._GetNextToken
():
3904 raise Warning.Expected("Build number", self
.FileName
, self
.CurrentLineNumber
)
3905 EfiSectionObj
.BuildNum
= self
._Token
3907 if self
._GetAlignment
():
3908 if self
._Token
not in ALIGNMENTS
:
3909 raise Warning("Incorrect alignment '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
3910 if self
._Token
== 'Auto' and (not SectionName
== BINARY_FILE_TYPE_PE32
) and (not SectionName
== BINARY_FILE_TYPE_TE
):
3911 raise Warning("Auto alignment can only be used in PE32 or TE section ", self
.FileName
, self
.CurrentLineNumber
)
3912 EfiSectionObj
.Alignment
= self
._Token
3914 if self
._IsKeyword
('RELOCS_STRIPPED') or self
._IsKeyword
('RELOCS_RETAINED'):
3915 if self
._SectionCouldHaveRelocFlag
(EfiSectionObj
.SectionType
):
3916 if self
._Token
== 'RELOCS_STRIPPED':
3917 EfiSectionObj
.KeepReloc
= False
3919 EfiSectionObj
.KeepReloc
= True
3920 if Obj
.KeepReloc
is not None and Obj
.KeepReloc
!= EfiSectionObj
.KeepReloc
:
3921 raise Warning("Section type %s has reloc strip flag conflict with Rule" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3923 raise Warning("Section type %s could not have reloc strip flag" % EfiSectionObj
.SectionType
, self
.FileName
, self
.CurrentLineNumber
)
3926 if self
._IsToken
(TAB_VALUE_SPLIT
):
3927 EfiSectionObj
.FileExtension
= self
._GetFileExtension
()
3928 elif self
._GetNextToken
():
3929 if self
._Token
not in {
3930 T_CHAR_BRACE_R
, "COMPAT16", BINARY_FILE_TYPE_PE32
,
3931 BINARY_FILE_TYPE_PIC
, BINARY_FILE_TYPE_TE
,
3932 "FV_IMAGE", "RAW", BINARY_FILE_TYPE_DXE_DEPEX
,
3933 BINARY_FILE_TYPE_UI
, "VERSION",
3934 BINARY_FILE_TYPE_PEI_DEPEX
, BINARY_FILE_TYPE_GUID
,
3935 BINARY_FILE_TYPE_SMM_DEPEX
}:
3937 if self
._Token
.startswith('PCD'):
3941 if self
._Token
== 'PCD':
3942 if not self
._IsToken
("("):
3943 raise Warning.Expected("'('", self
.FileName
, self
.CurrentLineNumber
)
3944 PcdPair
= self
._GetNextPcdSettings
()
3945 if not self
._IsToken
(")"):
3946 raise Warning.Expected("')'", self
.FileName
, self
.CurrentLineNumber
)
3947 self
._Token
= 'PCD('+PcdPair
[1]+TAB_SPLIT
+PcdPair
[0]+')'
3949 EfiSectionObj
.FileName
= self
._Token
3954 raise Warning.Expected("section file name", self
.FileName
, self
.CurrentLineNumber
)
3956 Obj
.SectionList
.append(EfiSectionObj
)
3959 ## _RuleSectionCouldBeOptional() method
3961 # Get whether a section could be optional
3963 # @param SectionType The section type to check
3964 # @retval True section could be optional
3965 # @retval False section never optional
3968 def _RuleSectionCouldBeOptional(SectionType
):
3969 if SectionType
in {BINARY_FILE_TYPE_DXE_DEPEX
, BINARY_FILE_TYPE_UI
, "VERSION", BINARY_FILE_TYPE_PEI_DEPEX
, "RAW", BINARY_FILE_TYPE_SMM_DEPEX
}:
3974 ## _RuleSectionCouldHaveBuildNum() method
3976 # Get whether a section could have build number information
3978 # @param SectionType The section type to check
3979 # @retval True section could have build number information
3980 # @retval False section never have build number information
3983 def _RuleSectionCouldHaveBuildNum(SectionType
):
3984 if SectionType
== "VERSION":
3989 ## _RuleSectionCouldHaveString() method
3991 # Get whether a section could have string
3993 # @param SectionType The section type to check
3994 # @retval True section could have string
3995 # @retval False section never have string
3998 def _RuleSectionCouldHaveString(SectionType
):
3999 if SectionType
in {BINARY_FILE_TYPE_UI
, "VERSION"}:
4004 ## _CheckRuleSectionFileType() method
4006 # Get whether a section matches a file type
4008 # @param self The object pointer
4009 # @param SectionType The section type to check
4010 # @param FileType The file type to check
4012 def _CheckRuleSectionFileType(self
, SectionType
, FileType
):
4013 WarningString
= "Incorrect section file type '%s'"
4014 if SectionType
== "COMPAT16":
4015 if FileType
not in {"COMPAT16", "SEC_COMPAT16"}:
4016 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4017 elif SectionType
== BINARY_FILE_TYPE_PE32
:
4018 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_PE32"}:
4019 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4020 elif SectionType
== BINARY_FILE_TYPE_PIC
:
4021 if FileType
not in {BINARY_FILE_TYPE_PIC
, "SEC_PIC"}:
4022 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4023 elif SectionType
== BINARY_FILE_TYPE_TE
:
4024 if FileType
not in {BINARY_FILE_TYPE_TE
, "SEC_TE"}:
4025 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4026 elif SectionType
== "RAW":
4027 if FileType
not in {BINARY_FILE_TYPE_BIN
, "SEC_BIN", "RAW", "ASL", "ACPI"}:
4028 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4029 elif SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
or SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
4030 if FileType
not in {BINARY_FILE_TYPE_DXE_DEPEX
, "SEC_DXE_DEPEX", BINARY_FILE_TYPE_SMM_DEPEX
}:
4031 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4032 elif SectionType
== BINARY_FILE_TYPE_UI
:
4033 if FileType
not in {BINARY_FILE_TYPE_UI
, "SEC_UI"}:
4034 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4035 elif SectionType
== "VERSION":
4036 if FileType
not in {"VERSION", "SEC_VERSION"}:
4037 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4038 elif SectionType
== BINARY_FILE_TYPE_PEI_DEPEX
:
4039 if FileType
not in {BINARY_FILE_TYPE_PEI_DEPEX
, "SEC_PEI_DEPEX"}:
4040 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4041 elif SectionType
== BINARY_FILE_TYPE_GUID
:
4042 if FileType
not in {BINARY_FILE_TYPE_PE32
, "SEC_GUID"}:
4043 raise Warning(WarningString
% FileType
, self
.FileName
, self
.CurrentLineNumber
)
4045 ## _GetRuleEncapsulationSection() method
4047 # Get encapsulation section for Rule
4049 # @param self The object pointer
4050 # @param theRule for whom section is got
4051 # @retval True Successfully find section statement
4052 # @retval False Not able to find section statement
4054 def _GetRuleEncapsulationSection(self
, theRule
):
4055 if self
._IsKeyword
("COMPRESS"):
4057 if self
._IsKeyword
("PI_STD") or self
._IsKeyword
("PI_NONE"):
4060 if not self
._IsToken
("{"):
4061 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4063 CompressSectionObj
= CompressSection()
4065 CompressSectionObj
.CompType
= Type
4066 # Recursive sections...
4068 IsEncapsulate
= self
._GetRuleEncapsulationSection
(CompressSectionObj
)
4069 IsLeaf
= self
._GetEfiSection
(CompressSectionObj
)
4070 if not IsEncapsulate
and not IsLeaf
:
4073 if not self
._IsToken
(T_CHAR_BRACE_R
):
4074 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4075 theRule
.SectionList
.append(CompressSectionObj
)
4079 elif self
._IsKeyword
("GUIDED"):
4081 if self
._GetNextGuid
():
4082 if self
._Token
in GlobalData
.gGuidDict
:
4083 self
._Token
= GuidStructureStringToGuidString(GlobalData
.gGuidDict
[self
._Token
]).upper()
4084 GuidValue
= self
._Token
4086 if self
._IsKeyword
("$(NAMED_GUID)"):
4087 GuidValue
= self
._Token
4089 AttribDict
= self
._GetGuidAttrib
()
4091 if not self
._IsToken
("{"):
4092 raise Warning.ExpectedCurlyOpen(self
.FileName
, self
.CurrentLineNumber
)
4093 GuidSectionObj
= GuidSection()
4094 GuidSectionObj
.NameGuid
= GuidValue
4095 GuidSectionObj
.SectionType
= "GUIDED"
4096 GuidSectionObj
.ProcessRequired
= AttribDict
["PROCESSING_REQUIRED"]
4097 GuidSectionObj
.AuthStatusValid
= AttribDict
["AUTH_STATUS_VALID"]
4098 GuidSectionObj
.ExtraHeaderSize
= AttribDict
["EXTRA_HEADER_SIZE"]
4102 IsEncapsulate
= self
._GetRuleEncapsulationSection
(GuidSectionObj
)
4103 IsLeaf
= self
._GetEfiSection
(GuidSectionObj
)
4104 if not IsEncapsulate
and not IsLeaf
:
4107 if not self
._IsToken
(T_CHAR_BRACE_R
):
4108 raise Warning.ExpectedCurlyClose(self
.FileName
, self
.CurrentLineNumber
)
4109 theRule
.SectionList
.append(GuidSectionObj
)
4115 ## _GetOptionRom() method
4117 # Get OptionROM section contents and store its data into OptionROM list of self.Profile
4119 # @param self The object pointer
4120 # @retval True Successfully find a OptionROM
4121 # @retval False Not able to find a OptionROM
4123 def _GetOptionRom(self
):
4124 if not self
._GetNextToken
():
4127 S
= self
._Token
.upper()
4128 if S
.startswith(TAB_SECTION_START
) and not S
.startswith("[OPTIONROM."):
4129 self
.SectionParser(S
)
4134 if not self
._IsToken
("[OptionRom.", True):
4135 raise Warning("Unknown Keyword '%s'" % self
._Token
, self
.FileName
, self
.CurrentLineNumber
)
4137 OptRomName
= self
._GetUiName
()
4139 if not self
._IsToken
(TAB_SECTION_END
):
4140 raise Warning.ExpectedBracketClose(self
.FileName
, self
.CurrentLineNumber
)
4142 OptRomObj
= OPTIONROM(OptRomName
)
4143 self
.Profile
.OptRomDict
[OptRomName
] = OptRomObj
4146 isInf
= self
._GetOptRomInfStatement
(OptRomObj
)
4147 isFile
= self
._GetOptRomFileStatement
(OptRomObj
)
4148 if not isInf
and not isFile
:
4153 ## _GetOptRomInfStatement() method
4155 # Get INF statements
4157 # @param self The object pointer
4158 # @param Obj for whom inf statement is got
4159 # @retval True Successfully find inf statement
4160 # @retval False Not able to find inf statement
4162 def _GetOptRomInfStatement(self
, Obj
):
4163 if not self
._IsKeyword
("INF"):
4166 ffsInf
= OptRomInfStatement()
4167 self
._GetInfOptions
(ffsInf
)
4169 if not self
._GetNextToken
():
4170 raise Warning.Expected("INF file path", self
.FileName
, self
.CurrentLineNumber
)
4171 ffsInf
.InfFileName
= self
._Token
4172 if ffsInf
.InfFileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4173 #check for file path
4174 ErrorCode
, ErrorInfo
= PathClass(NormPath(ffsInf
.InfFileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4176 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4178 NewFileName
= ffsInf
.InfFileName
4179 if ffsInf
.OverrideGuid
:
4180 NewFileName
= ProcessDuplicatedInf(PathClass(ffsInf
.InfFileName
,GenFdsGlobalVariable
.WorkSpaceDir
), ffsInf
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
).Path
4182 if not NewFileName
in self
.Profile
.InfList
:
4183 self
.Profile
.InfList
.append(NewFileName
)
4184 FileLineTuple
= GetRealFileLine(self
.FileName
, self
.CurrentLineNumber
)
4185 self
.Profile
.InfFileLineList
.append(FileLineTuple
)
4187 if ffsInf
.UseArch
not in self
.Profile
.InfDict
:
4188 self
.Profile
.InfDict
[ffsInf
.UseArch
] = [ffsInf
.InfFileName
]
4190 self
.Profile
.InfDict
[ffsInf
.UseArch
].append(ffsInf
.InfFileName
)
4192 self
.Profile
.InfDict
['ArchTBD'].append(ffsInf
.InfFileName
)
4195 self
._GetOptRomOverrides
(ffsInf
)
4197 Obj
.FfsList
.append(ffsInf
)
4200 ## _GetOptRomOverrides() method
4202 # Get overrides for OptROM INF & FILE
4204 # @param self The object pointer
4205 # @param FfsInfObj for whom overrides is got
4207 def _GetOptRomOverrides(self
, Obj
):
4208 if self
._IsToken
('{'):
4209 Overrides
= OverrideAttribs()
4211 if self
._IsKeyword
("PCI_VENDOR_ID"):
4212 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4213 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4214 if not self
._GetNextHexNumber
():
4215 raise Warning.Expected("Hex vendor id", self
.FileName
, self
.CurrentLineNumber
)
4216 Overrides
.PciVendorId
= self
._Token
4219 if self
._IsKeyword
("PCI_CLASS_CODE"):
4220 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4221 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4222 if not self
._GetNextHexNumber
():
4223 raise Warning.Expected("Hex class code", self
.FileName
, self
.CurrentLineNumber
)
4224 Overrides
.PciClassCode
= self
._Token
4227 if self
._IsKeyword
("PCI_DEVICE_ID"):
4228 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4229 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4230 # Get a list of PCI IDs
4231 Overrides
.PciDeviceId
= ""
4232 while (self
._GetNextHexNumber
()):
4233 Overrides
.PciDeviceId
= "{} {}".format(Overrides
.PciDeviceId
, self
._Token
)
4234 if not Overrides
.PciDeviceId
:
4235 raise Warning.Expected("one or more Hex device ids", self
.FileName
, self
.CurrentLineNumber
)
4238 if self
._IsKeyword
("PCI_REVISION"):
4239 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4240 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4241 if not self
._GetNextHexNumber
():
4242 raise Warning.Expected("Hex revision", self
.FileName
, self
.CurrentLineNumber
)
4243 Overrides
.PciRevision
= self
._Token
4246 if self
._IsKeyword
("PCI_COMPRESS"):
4247 if not self
._IsToken
(TAB_EQUAL_SPLIT
):
4248 raise Warning.ExpectedEquals(self
.FileName
, self
.CurrentLineNumber
)
4249 if not self
._GetNextToken
():
4250 raise Warning.Expected("TRUE/FALSE for compress", self
.FileName
, self
.CurrentLineNumber
)
4251 Overrides
.NeedCompress
= self
._Token
.upper() == 'TRUE'
4254 if self
._IsToken
(T_CHAR_BRACE_R
):
4257 EdkLogger
.error("FdfParser", FORMAT_INVALID
, File
=self
.FileName
, Line
=self
.CurrentLineNumber
)
4259 Obj
.OverrideAttribs
= Overrides
4261 ## _GetOptRomFileStatement() method
4263 # Get FILE statements
4265 # @param self The object pointer
4266 # @param Obj for whom FILE statement is got
4267 # @retval True Successfully find FILE statement
4268 # @retval False Not able to find FILE statement
4270 def _GetOptRomFileStatement(self
, Obj
):
4271 if not self
._IsKeyword
("FILE"):
4274 FfsFileObj
= OptRomFileStatement()
4276 if not self
._IsKeyword
("EFI") and not self
._IsKeyword
(BINARY_FILE_TYPE_BIN
):
4277 raise Warning.Expected("Binary type (EFI/BIN)", self
.FileName
, self
.CurrentLineNumber
)
4278 FfsFileObj
.FileType
= self
._Token
4280 if not self
._GetNextToken
():
4281 raise Warning.Expected("File path", self
.FileName
, self
.CurrentLineNumber
)
4282 FfsFileObj
.FileName
= self
._Token
4283 if FfsFileObj
.FileName
.replace(TAB_WORKSPACE
, '').find('$') == -1:
4284 #check for file path
4285 ErrorCode
, ErrorInfo
= PathClass(NormPath(FfsFileObj
.FileName
), GenFdsGlobalVariable
.WorkSpaceDir
).Validate()
4287 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
4289 if FfsFileObj
.FileType
== 'EFI':
4290 self
._GetOptRomOverrides
(FfsFileObj
)
4292 Obj
.FfsList
.append(FfsFileObj
)
4296 ## _GetCapInFd() method
4298 # Get Cap list contained in FD
4300 # @param self The object pointer
4301 # @param FdName FD name
4302 # @retval CapList List of Capsule in FD
4304 def _GetCapInFd (self
, FdName
):
4306 if FdName
.upper() in self
.Profile
.FdDict
:
4307 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4308 for elementRegion
in FdObj
.RegionList
:
4309 if elementRegion
.RegionType
== 'CAPSULE':
4310 for elementRegionData
in elementRegion
.RegionDataList
:
4311 if elementRegionData
.endswith(".cap"):
4313 if elementRegionData
is not None and elementRegionData
.upper() not in CapList
:
4314 CapList
.append(elementRegionData
.upper())
4317 ## _GetReferencedFdCapTuple() method
4319 # Get FV and FD list referenced by a capsule image
4321 # @param self The object pointer
4322 # @param CapObj Capsule section to be searched
4323 # @param RefFdList referenced FD by section
4324 # @param RefFvList referenced FV by section
4326 def _GetReferencedFdCapTuple(self
, CapObj
, RefFdList
= [], RefFvList
= []):
4327 for CapsuleDataObj
in CapObj
.CapsuleDataList
:
4328 if hasattr(CapsuleDataObj
, 'FvName') and CapsuleDataObj
.FvName
is not None and CapsuleDataObj
.FvName
.upper() not in RefFvList
:
4329 RefFvList
.append (CapsuleDataObj
.FvName
.upper())
4330 elif hasattr(CapsuleDataObj
, 'FdName') and CapsuleDataObj
.FdName
is not None and CapsuleDataObj
.FdName
.upper() not in RefFdList
:
4331 RefFdList
.append (CapsuleDataObj
.FdName
.upper())
4332 elif CapsuleDataObj
.Ffs
is not None:
4333 if isinstance(CapsuleDataObj
.Ffs
, FileStatement
):
4334 if CapsuleDataObj
.Ffs
.FvName
is not None and CapsuleDataObj
.Ffs
.FvName
.upper() not in RefFvList
:
4335 RefFvList
.append(CapsuleDataObj
.Ffs
.FvName
.upper())
4336 elif CapsuleDataObj
.Ffs
.FdName
is not None and CapsuleDataObj
.Ffs
.FdName
.upper() not in RefFdList
:
4337 RefFdList
.append(CapsuleDataObj
.Ffs
.FdName
.upper())
4339 self
._GetReferencedFdFvTupleFromSection
(CapsuleDataObj
.Ffs
, RefFdList
, RefFvList
)
4341 ## _GetFvInFd() method
4343 # Get FV list contained in FD
4345 # @param self The object pointer
4346 # @param FdName FD name
4347 # @retval FvList list of FV in FD
4349 def _GetFvInFd (self
, FdName
):
4351 if FdName
.upper() in self
.Profile
.FdDict
:
4352 FdObj
= self
.Profile
.FdDict
[FdName
.upper()]
4353 for elementRegion
in FdObj
.RegionList
:
4354 if elementRegion
.RegionType
== BINARY_FILE_TYPE_FV
:
4355 for elementRegionData
in elementRegion
.RegionDataList
:
4356 if elementRegionData
.endswith(".fv"):
4358 if elementRegionData
is not None and elementRegionData
.upper() not in FvList
:
4359 FvList
.append(elementRegionData
.upper())
4362 ## _GetReferencedFdFvTuple() method
4364 # Get FD and FV list referenced by a FFS file
4366 # @param self The object pointer
4367 # @param FfsFile contains sections to be searched
4368 # @param RefFdList referenced FD by section
4369 # @param RefFvList referenced FV by section
4371 def _GetReferencedFdFvTuple(self
, FvObj
, RefFdList
= [], RefFvList
= []):
4372 for FfsObj
in FvObj
.FfsList
:
4373 if isinstance(FfsObj
, FileStatement
):
4374 if FfsObj
.FvName
is not None and FfsObj
.FvName
.upper() not in RefFvList
:
4375 RefFvList
.append(FfsObj
.FvName
.upper())
4376 elif FfsObj
.FdName
is not None and FfsObj
.FdName
.upper() not in RefFdList
:
4377 RefFdList
.append(FfsObj
.FdName
.upper())
4379 self
._GetReferencedFdFvTupleFromSection
(FfsObj
, RefFdList
, RefFvList
)
4381 ## _GetReferencedFdFvTupleFromSection() method
4383 # Get FD and FV list referenced by a FFS section
4385 # @param self The object pointer
4386 # @param FfsFile contains sections to be searched
4387 # @param FdList referenced FD by section
4388 # @param FvList referenced FV by section
4390 def _GetReferencedFdFvTupleFromSection(self
, FfsFile
, FdList
= [], FvList
= []):
4391 SectionStack
= list(FfsFile
.SectionList
)
4392 while SectionStack
!= []:
4393 SectionObj
= SectionStack
.pop()
4394 if isinstance(SectionObj
, FvImageSection
):
4395 if SectionObj
.FvName
is not None and SectionObj
.FvName
.upper() not in FvList
:
4396 FvList
.append(SectionObj
.FvName
.upper())
4397 if SectionObj
.Fv
is not None and SectionObj
.Fv
.UiFvName
is not None and SectionObj
.Fv
.UiFvName
.upper() not in FvList
:
4398 FvList
.append(SectionObj
.Fv
.UiFvName
.upper())
4399 self
._GetReferencedFdFvTuple
(SectionObj
.Fv
, FdList
, FvList
)
4401 if isinstance(SectionObj
, CompressSection
) or isinstance(SectionObj
, GuidSection
):
4402 SectionStack
.extend(SectionObj
.SectionList
)
4404 ## CycleReferenceCheck() method
4406 # Check whether cycle reference exists in FDF
4408 # @param self The object pointer
4409 # @retval True cycle reference exists
4410 # @retval False Not exists cycle reference
4412 def CycleReferenceCheck(self
):
4414 # Check the cycle between FV and FD image
4416 MaxLength
= len (self
.Profile
.FvDict
)
4417 for FvName
in self
.Profile
.FvDict
:
4418 LogStr
= "\nCycle Reference Checking for FV: %s\n" % FvName
4419 RefFvStack
= set(FvName
)
4420 FdAnalyzedList
= set()
4423 while RefFvStack
and Index
< MaxLength
:
4425 FvNameFromStack
= RefFvStack
.pop()
4426 if FvNameFromStack
.upper() in self
.Profile
.FvDict
:
4427 FvObj
= self
.Profile
.FvDict
[FvNameFromStack
.upper()]
4433 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4435 for RefFdName
in RefFdList
:
4436 if RefFdName
in FdAnalyzedList
:
4439 LogStr
+= "FV %s contains FD %s\n" % (FvNameFromStack
, RefFdName
)
4440 FvInFdList
= self
._GetFvInFd
(RefFdName
)
4441 if FvInFdList
!= []:
4442 for FvNameInFd
in FvInFdList
:
4443 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4444 if FvNameInFd
not in RefFvStack
:
4445 RefFvStack
.add(FvNameInFd
)
4447 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4448 EdkLogger
.info(LogStr
)
4450 FdAnalyzedList
.add(RefFdName
)
4452 for RefFvName
in RefFvList
:
4453 LogStr
+= "FV %s contains FV %s\n" % (FvNameFromStack
, RefFvName
)
4454 if RefFvName
not in RefFvStack
:
4455 RefFvStack
.add(RefFvName
)
4457 if FvName
in RefFvStack
or FvNameFromStack
in RefFvStack
:
4458 EdkLogger
.info(LogStr
)
4462 # Check the cycle between Capsule and FD image
4464 MaxLength
= len (self
.Profile
.CapsuleDict
)
4465 for CapName
in self
.Profile
.CapsuleDict
:
4467 # Capsule image to be checked.
4469 LogStr
= "\n\n\nCycle Reference Checking for Capsule: %s\n" % CapName
4470 RefCapStack
= {CapName}
4471 FdAnalyzedList
= set()
4472 FvAnalyzedList
= set()
4475 while RefCapStack
and Index
< MaxLength
:
4477 CapNameFromStack
= RefCapStack
.pop()
4478 if CapNameFromStack
.upper() in self
.Profile
.CapsuleDict
:
4479 CapObj
= self
.Profile
.CapsuleDict
[CapNameFromStack
.upper()]
4485 self
._GetReferencedFdCapTuple
(CapObj
, RefFdList
, RefFvList
)
4489 while FvListLength
< len (RefFvList
) or FdListLength
< len (RefFdList
):
4490 for RefFdName
in RefFdList
:
4491 if RefFdName
in FdAnalyzedList
:
4494 LogStr
+= "Capsule %s contains FD %s\n" % (CapNameFromStack
, RefFdName
)
4495 for CapNameInFd
in self
._GetCapInFd
(RefFdName
):
4496 LogStr
+= "FD %s contains Capsule %s\n" % (RefFdName
, CapNameInFd
)
4497 if CapNameInFd
not in RefCapStack
:
4498 RefCapStack
.append(CapNameInFd
)
4500 if CapName
in RefCapStack
or CapNameFromStack
in RefCapStack
:
4501 EdkLogger
.info(LogStr
)
4504 for FvNameInFd
in self
._GetFvInFd
(RefFdName
):
4505 LogStr
+= "FD %s contains FV %s\n" % (RefFdName
, FvNameInFd
)
4506 if FvNameInFd
not in RefFvList
:
4507 RefFvList
.append(FvNameInFd
)
4509 FdAnalyzedList
.add(RefFdName
)
4511 # the number of the parsed FV and FD image
4513 FvListLength
= len (RefFvList
)
4514 FdListLength
= len (RefFdList
)
4515 for RefFvName
in RefFvList
:
4516 if RefFvName
in FvAnalyzedList
:
4518 LogStr
+= "Capsule %s contains FV %s\n" % (CapNameFromStack
, RefFvName
)
4519 if RefFvName
.upper() in self
.Profile
.FvDict
:
4520 FvObj
= self
.Profile
.FvDict
[RefFvName
.upper()]
4523 self
._GetReferencedFdFvTuple
(FvObj
, RefFdList
, RefFvList
)
4524 FvAnalyzedList
.add(RefFvName
)
4528 def GetAllIncludedFile (self
):
4529 global AllIncludeFileList
4530 return AllIncludeFileList
4532 if __name__
== "__main__":
4535 test_file
= sys
.argv
[1]
4536 except IndexError as v
:
4537 print("Usage: %s filename" % sys
.argv
[0])
4540 parser
= FdfParser(test_file
)
4543 parser
.CycleReferenceCheck()
4544 except Warning as X
: