2 # process FFS generation from INF statement
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 # Copyright (c) 2014-2016 Hewlett-Packard Development Company, L.P.<BR>
7 # SPDX-License-Identifier: BSD-2-Clause-Patent
13 from __future__
import absolute_import
15 import Common
.LongFilePathOs
as os
16 from io
import BytesIO
18 from .GenFdsGlobalVariable
import GenFdsGlobalVariable
19 from .Ffs
import SectionSuffix
,FdfFvFileTypeToFileType
23 from . import RuleSimpleFile
24 from . import RuleComplexFile
25 from CommonDataClass
.FdfClass
import FfsInfStatementClassObject
26 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
27 from Common
.DataType
import SUP_MODULE_USER_DEFINED
28 from Common
.StringUtils
import *
29 from Common
.Misc
import PathClass
30 from Common
.Misc
import GuidStructureByteArrayToGuidString
31 from Common
.Misc
import ProcessDuplicatedInf
32 from Common
.Misc
import GetVariableOffset
33 from Common
import EdkLogger
34 from Common
.BuildToolError
import *
35 from .GuidSection
import GuidSection
36 from .FvImageSection
import FvImageSection
37 from Common
.Misc
import PeImageClass
38 from AutoGen
.GenDepex
import DependencyExpression
39 from PatchPcdValue
.PatchPcdValue
import PatchBinaryFile
40 from Common
.LongFilePathSupport
import CopyLongFilePath
41 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
42 import Common
.GlobalData
as GlobalData
43 from .DepexSection
import DepexSection
44 from Common
.Misc
import SaveFileOnChange
45 from Common
.Expression
import *
46 from Common
.DataType
import *
48 ## generate FFS from INF
51 class FfsInfStatement(FfsInfStatementClassObject
):
54 # @param self The object pointer
57 FfsInfStatementClassObject
.__init
__(self
)
58 self
.TargetOverrideList
= []
59 self
.ShadowFromInfFile
= None
60 self
.KeepRelocFromRule
= None
63 self
.PiSpecVersion
= '0x00000000'
65 self
.FinalTargetSuffixMap
= {}
66 self
.CurrentLineNum
= None
67 self
.CurrentLineContent
= None
69 self
.InfFileName
= None
70 self
.OverrideGuid
= None
71 self
.PatchedBinFile
= ''
75 ## GetFinalTargetSuffixMap() method
77 # Get final build target list
78 def GetFinalTargetSuffixMap(self
):
79 if not self
.InfModule
or not self
.CurrentArch
:
81 if not self
.FinalTargetSuffixMap
:
82 FinalBuildTargetList
= GenFdsGlobalVariable
.GetModuleCodaTargetList(self
.InfModule
, self
.CurrentArch
)
83 for File
in FinalBuildTargetList
:
84 self
.FinalTargetSuffixMap
.setdefault(os
.path
.splitext(File
)[1], []).append(File
)
86 # Check if current INF module has DEPEX
87 if '.depex' not in self
.FinalTargetSuffixMap
and self
.InfModule
.ModuleType
!= SUP_MODULE_USER_DEFINED \
88 and not self
.InfModule
.DxsFile
and not self
.InfModule
.LibraryClass
:
89 ModuleType
= self
.InfModule
.ModuleType
90 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
92 if ModuleType
!= SUP_MODULE_USER_DEFINED
:
93 for LibraryClass
in PlatformDataBase
.LibraryClasses
.GetKeys():
94 if LibraryClass
.startswith("NULL") and PlatformDataBase
.LibraryClasses
[LibraryClass
, ModuleType
]:
95 self
.InfModule
.LibraryClasses
[LibraryClass
] = PlatformDataBase
.LibraryClasses
[LibraryClass
, ModuleType
]
97 StrModule
= str(self
.InfModule
)
99 if StrModule
in PlatformDataBase
.Modules
:
100 PlatformModule
= PlatformDataBase
.Modules
[StrModule
]
101 for LibraryClass
in PlatformModule
.LibraryClasses
:
102 if LibraryClass
.startswith("NULL"):
103 self
.InfModule
.LibraryClasses
[LibraryClass
] = PlatformModule
.LibraryClasses
[LibraryClass
]
105 DependencyList
= [self
.InfModule
]
108 while len(DependencyList
) > 0:
109 Module
= DependencyList
.pop(0)
112 for Dep
in Module
.Depex
[self
.CurrentArch
, ModuleType
]:
114 DepexList
.append('AND')
115 DepexList
.append('(')
116 DepexList
.extend(Dep
)
117 if DepexList
[-1] == 'END': # no need of a END at this time
119 DepexList
.append(')')
120 if 'BEFORE' in DepexList
or 'AFTER' in DepexList
:
122 for LibName
in Module
.LibraryClasses
:
123 if LibName
in LibraryInstance
:
125 if PlatformModule
and LibName
in PlatformModule
.LibraryClasses
:
126 LibraryPath
= PlatformModule
.LibraryClasses
[LibName
]
128 LibraryPath
= PlatformDataBase
.LibraryClasses
[LibName
, ModuleType
]
130 LibraryPath
= Module
.LibraryClasses
[LibName
]
133 LibraryModule
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[LibraryPath
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
134 LibraryInstance
[LibName
] = LibraryModule
135 DependencyList
.append(LibraryModule
)
137 Dpx
= DependencyExpression(DepexList
, ModuleType
, True)
138 if len(Dpx
.PostfixNotation
) != 0:
139 # It means this module has DEPEX
140 self
.FinalTargetSuffixMap
['.depex'] = [os
.path
.join(self
.EfiOutputPath
, self
.BaseName
) + '.depex']
141 return self
.FinalTargetSuffixMap
143 ## __InfParse() method
145 # Parse inf file to get module information
147 # @param self The object pointer
148 # @param Dict dictionary contains macro and value pair
150 def __InfParse__(self
, Dict
= {}):
152 GenFdsGlobalVariable
.VerboseLogger( " Begine parsing INf file : %s" %self
.InfFileName
)
154 self
.InfFileName
= self
.InfFileName
.replace('$(WORKSPACE)', '')
155 if len(self
.InfFileName
) > 1 and self
.InfFileName
[0] == '\\' and self
.InfFileName
[1] == '\\':
157 elif self
.InfFileName
[0] == '\\' or self
.InfFileName
[0] == '/' :
158 self
.InfFileName
= self
.InfFileName
[1:]
160 if self
.InfFileName
.find('$') == -1:
161 InfPath
= NormPath(self
.InfFileName
)
162 if not os
.path
.exists(InfPath
):
163 InfPath
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(InfPath
)
164 if not os
.path
.exists(InfPath
):
165 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Non-existant Module %s !" % (self
.InfFileName
))
167 self
.CurrentArch
= self
.GetCurrentArch()
169 # Get the InfClass object
172 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
173 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
175 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
178 # Cache lower case version of INF path before processing FILE_GUID override
180 InfLowerPath
= str(PathClassObj
).lower()
181 if self
.OverrideGuid
:
182 PathClassObj
= ProcessDuplicatedInf(PathClassObj
, self
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
)
183 if self
.CurrentArch
is not None:
185 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
187 # Set Ffs BaseName, ModuleGuid, ModuleType, Version, OutputPath
189 self
.BaseName
= Inf
.BaseName
190 self
.ModuleGuid
= Inf
.Guid
191 self
.ModuleType
= Inf
.ModuleType
192 if Inf
.Specification
is not None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
193 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
194 if Inf
.AutoGenVersion
< 0x00010005:
195 self
.ModuleType
= Inf
.ComponentType
196 self
.VersionString
= Inf
.Version
197 self
.BinFileList
= Inf
.Binaries
198 self
.SourceFileList
= Inf
.Sources
199 if self
.KeepReloc
is None and Inf
.Shadow
:
200 self
.ShadowFromInfFile
= Inf
.Shadow
203 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, TAB_COMMON
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
204 self
.BaseName
= Inf
.BaseName
205 self
.ModuleGuid
= Inf
.Guid
206 self
.ModuleType
= Inf
.ModuleType
207 if Inf
.Specification
is not None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
208 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
209 self
.VersionString
= Inf
.Version
210 self
.BinFileList
= Inf
.Binaries
211 self
.SourceFileList
= Inf
.Sources
212 if self
.BinFileList
== []:
213 EdkLogger
.error("GenFds", GENFDS_ERROR
,
214 "INF %s specified in FDF could not be found in build ARCH %s!" \
215 % (self
.InfFileName
, GenFdsGlobalVariable
.ArchList
))
217 if self
.OverrideGuid
:
218 self
.ModuleGuid
= self
.OverrideGuid
220 if len(self
.SourceFileList
) != 0 and not self
.InDsc
:
221 EdkLogger
.warn("GenFds", GENFDS_ERROR
, "Module %s NOT found in DSC file; Is it really a binary module?" % (self
.InfFileName
))
223 if self
.ModuleType
== SUP_MODULE_SMM_CORE
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
224 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File
=self
.InfFileName
)
226 if self
.ModuleType
== SUP_MODULE_MM_CORE_STANDALONE
and int(self
.PiSpecVersion
, 16) < 0x00010032:
227 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "MM_CORE_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File
=self
.InfFileName
)
229 if Inf
._Defs
is not None and len(Inf
._Defs
) > 0:
230 self
.OptRomDefs
.update(Inf
._Defs
)
234 Platform
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
235 FdfPcdDict
= GenFdsGlobalVariable
.FdfParser
.Profile
.PcdDict
236 PlatformPcds
= Platform
.Pcds
238 # Workaround here: both build and GenFds tool convert the workspace path to lower case
239 # But INF file path in FDF and DSC file may have real case characters.
240 # Try to convert the path to lower case to see if PCDs value are override by DSC.
242 for DscModule
in Platform
.Modules
:
243 DscModules
[str(DscModule
).lower()] = Platform
.Modules
[DscModule
]
244 for PcdKey
in InfPcds
:
245 Pcd
= InfPcds
[PcdKey
]
246 if not hasattr(Pcd
, 'Offset'):
248 if Pcd
.Type
!= TAB_PCDS_PATCHABLE_IN_MODULE
:
250 # Override Patchable PCD value by the value from DSC
252 if InfLowerPath
in DscModules
and PcdKey
in DscModules
[InfLowerPath
].Pcds
:
253 PatchPcd
= DscModules
[InfLowerPath
].Pcds
[PcdKey
]
254 elif PcdKey
in Platform
.Pcds
:
255 PatchPcd
= Platform
.Pcds
[PcdKey
]
257 if PatchPcd
and Pcd
.Type
== PatchPcd
.Type
:
258 DefaultValue
= PatchPcd
.DefaultValue
261 # Override Patchable PCD value by the value from FDF
263 if PcdKey
in FdfPcdDict
:
264 DefaultValue
= FdfPcdDict
[PcdKey
]
267 # Override Patchable PCD value by the value from Build Option
268 BuildOptionOverride
= False
269 if GlobalData
.BuildOptionPcd
:
270 for pcd
in GlobalData
.BuildOptionPcd
:
271 if PcdKey
== (pcd
[1], pcd
[0]):
274 DefaultValue
= pcd
[3]
275 BuildOptionOverride
= True
278 if not DscOverride
and not FdfOverride
and not BuildOptionOverride
:
281 # Support Flexible PCD format
284 DefaultValue
= ValueExpressionEx(DefaultValue
, Pcd
.DatumType
, Platform
._GuidDict
)(True)
285 except BadExpression
:
286 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'PCD [%s.%s] Value "%s"' %(Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, DefaultValue
), File
=self
.InfFileName
)
288 if Pcd
.InfDefaultValue
:
290 Pcd
.InfDefaultValue
= ValueExpressionEx(Pcd
.InfDefaultValue
, Pcd
.DatumType
, Platform
._GuidDict
)(True)
291 except BadExpression
:
292 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'PCD [%s.%s] Value "%s"' %(Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Pcd
.DefaultValue
), File
=self
.InfFileName
)
294 # Check value, if value are equal, no need to patch
295 if Pcd
.DatumType
== TAB_VOID
:
296 if Pcd
.InfDefaultValue
== DefaultValue
or not DefaultValue
:
298 # Get the string size from FDF or DSC
299 if DefaultValue
[0] == 'L':
300 # Remove L"", but the '\0' must be appended
301 MaxDatumSize
= str((len(DefaultValue
) - 2) * 2)
302 elif DefaultValue
[0] == '{':
303 MaxDatumSize
= str(len(DefaultValue
.split(',')))
305 MaxDatumSize
= str(len(DefaultValue
) - 1)
307 Pcd
.MaxDatumSize
= PatchPcd
.MaxDatumSize
308 # If no defined the maximum size in DSC, try to get current size from INF
309 if not Pcd
.MaxDatumSize
:
310 Pcd
.MaxDatumSize
= str(len(Pcd
.InfDefaultValue
.split(',')))
313 if Pcd
.InfDefaultValue
.upper().startswith('0X'):
315 if DefaultValue
.upper().startswith('0X'):
318 PcdValueInImg
= int(Pcd
.InfDefaultValue
, Base1
)
319 PcdValueInDscOrFdf
= int(DefaultValue
, Base2
)
320 if PcdValueInImg
== PcdValueInDscOrFdf
:
324 # Check the Pcd size and data type
325 if Pcd
.DatumType
== TAB_VOID
:
326 if int(MaxDatumSize
) > int(Pcd
.MaxDatumSize
):
327 EdkLogger
.error("GenFds", GENFDS_ERROR
, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \
328 % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, int(MaxDatumSize
) - int(Pcd
.MaxDatumSize
)))
330 if PcdValueInDscOrFdf
> MAX_VAL_TYPE
[Pcd
.DatumType
] \
331 or PcdValueInImg
> MAX_VAL_TYPE
[Pcd
.DatumType
]:
332 EdkLogger
.error("GenFds", GENFDS_ERROR
, "The size of %s type PCD '%s.%s' doesn't match its data type." \
333 % (Pcd
.DatumType
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
334 self
.PatchPcds
.append((Pcd
, DefaultValue
))
337 self
.PcdIsDriver
= Inf
.PcdIsDriver
338 self
.IsBinaryModule
= Inf
.IsBinaryModule
339 if len(Inf
.Depex
.data
) > 0 and len(Inf
.DepexExpression
.data
) > 0:
342 GenFdsGlobalVariable
.VerboseLogger("BaseName : %s" % self
.BaseName
)
343 GenFdsGlobalVariable
.VerboseLogger("ModuleGuid : %s" % self
.ModuleGuid
)
344 GenFdsGlobalVariable
.VerboseLogger("ModuleType : %s" % self
.ModuleType
)
345 GenFdsGlobalVariable
.VerboseLogger("VersionString : %s" % self
.VersionString
)
346 GenFdsGlobalVariable
.VerboseLogger("InfFileName :%s" % self
.InfFileName
)
349 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${ModuleName}\
352 self
.OutputPath
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, \
353 self
.ModuleGuid
+ self
.BaseName
)
354 if not os
.path
.exists(self
.OutputPath
) :
355 os
.makedirs(self
.OutputPath
)
357 self
.EfiOutputPath
, self
.EfiDebugPath
= self
.__GetEFIOutPutPath
__()
358 GenFdsGlobalVariable
.VerboseLogger( "ModuelEFIPath: " + self
.EfiOutputPath
)
362 # Patch EFI file with patch PCD
364 # @param EfiFile: EFI file needs to be patched.
365 # @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name
366 # If passed in file does not end with efi, return as is
368 def PatchEfiFile(self
, EfiFile
, FileType
):
370 # If the module does not have any patches, then return path to input file
372 if not self
.PatchPcds
:
376 # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED
378 if FileType
!= BINARY_FILE_TYPE_PE32
and self
.ModuleType
!= SUP_MODULE_USER_DEFINED
:
382 # Generate path to patched output file
384 Basename
= os
.path
.basename(EfiFile
)
385 Output
= os
.path
.normpath (os
.path
.join(self
.OutputPath
, Basename
))
388 # If this file has already been patched, then return the path to the patched file
390 if self
.PatchedBinFile
== Output
:
394 # If a different file from the same module has already been patched, then generate an error
396 if self
.PatchedBinFile
:
397 EdkLogger
.error("GenFds", GENFDS_ERROR
,
398 'Only one binary file can be patched:\n'
399 ' a binary file has been patched: %s\n'
400 ' current file: %s' % (self
.PatchedBinFile
, EfiFile
),
401 File
=self
.InfFileName
)
404 # Copy unpatched file contents to output file location to perform patching
406 CopyLongFilePath(EfiFile
, Output
)
409 # Apply patches to patched output file
411 for Pcd
, Value
in self
.PatchPcds
:
412 RetVal
, RetStr
= PatchBinaryFile(Output
, int(Pcd
.Offset
, 0), Pcd
.DatumType
, Value
, Pcd
.MaxDatumSize
)
414 EdkLogger
.error("GenFds", GENFDS_ERROR
, RetStr
, File
=self
.InfFileName
)
417 # Save the path of the patched output file
419 self
.PatchedBinFile
= Output
422 # Return path to patched output file
430 # @param self The object pointer
431 # @param Dict dictionary contains macro and value pair
432 # @param FvChildAddr Array of the inside FvImage base address
433 # @param FvParentAddr Parent Fv base address
434 # @retval string Generated FFS file name
436 def GenFfs(self
, Dict
= {}, FvChildAddr
= [], FvParentAddr
=None, IsMakefile
=False, FvName
=None):
438 # Parse Inf file get Module related information
441 self
.__InfParse
__(Dict
)
442 Arch
= self
.GetCurrentArch()
443 SrcFile
= mws
.join( GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
);
444 DestFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
447 SrcPath
= os
.path
.dirname(SrcFile
)
448 SrcFileName
= os
.path
.basename(SrcFile
)
449 SrcFileBase
, SrcFileExt
= os
.path
.splitext(SrcFileName
)
450 DestPath
= os
.path
.dirname(DestFile
)
451 DestFileName
= os
.path
.basename(DestFile
)
452 DestFileBase
, DestFileExt
= os
.path
.splitext(DestFileName
)
456 "${s_path}" : SrcPath
,
457 "${s_dir}" : SrcFileDir
,
458 "${s_name}" : SrcFileName
,
459 "${s_base}" : SrcFileBase
,
460 "${s_ext}" : SrcFileExt
,
463 "${d_path}" : DestPath
,
464 "${d_name}" : DestFileName
,
465 "${d_base}" : DestFileBase
,
466 "${d_ext}" : DestFileExt
469 # Allow binary type module not specify override rule in FDF file.
471 if len(self
.BinFileList
) > 0:
472 if self
.Rule
is None or self
.Rule
== "":
475 if not IsMakefile
and GenFdsGlobalVariable
.EnableGenfdsMultiThread
and self
.Rule
!= 'BINARY':
478 # Get the rule of how to generate Ffs file
480 Rule
= self
.__GetRule
__()
481 GenFdsGlobalVariable
.VerboseLogger( "Packing binaries from inf file : %s" %self
.InfFileName
)
483 # Convert Fv File Type for PI1.1 SMM driver.
485 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
486 if Rule
.FvFileType
== 'DRIVER':
487 Rule
.FvFileType
= 'SMM'
489 # Framework SMM Driver has no SMM FV file type
491 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
492 if Rule
.FvFileType
== 'SMM' or Rule
.FvFileType
== SUP_MODULE_SMM_CORE
:
493 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File
=self
.InfFileName
)
495 # For the rule only has simpleFile
498 if self
.IsBinaryModule
:
501 MakefilePath
= self
.InfFileName
, Arch
502 if isinstance (Rule
, RuleSimpleFile
.RuleSimpleFile
):
503 SectionOutputList
= self
.__GenSimpleFileSection
__(Rule
, IsMakefile
=IsMakefile
)
504 FfsOutput
= self
.__GenSimpleFileFfs
__(Rule
, SectionOutputList
, MakefilePath
=MakefilePath
)
507 # For Rule has ComplexFile
509 elif isinstance(Rule
, RuleComplexFile
.RuleComplexFile
):
510 InputSectList
, InputSectAlignments
= self
.__GenComplexFileSection
__(Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
=IsMakefile
)
511 FfsOutput
= self
.__GenComplexFileFfs
__(Rule
, InputSectList
, InputSectAlignments
, MakefilePath
=MakefilePath
)
514 ## __ExtendMacro__() method
516 # Replace macro with its value
518 # @param self The object pointer
519 # @param String The string to be replaced
520 # @retval string Macro replaced string
522 def __ExtendMacro__ (self
, String
):
524 '$(INF_OUTPUT)' : self
.EfiOutputPath
,
525 '$(MODULE_NAME)' : self
.BaseName
,
526 '$(BUILD_NUMBER)': self
.BuildNum
,
527 '$(INF_VERSION)' : self
.VersionString
,
528 '$(NAMED_GUID)' : self
.ModuleGuid
530 String
= GenFdsGlobalVariable
.MacroExtend(String
, MacroDict
)
531 String
= GenFdsGlobalVariable
.MacroExtend(String
, self
.MacroDict
)
534 ## __GetRule__() method
536 # Get correct rule for generating FFS for this INF
538 # @param self The object pointer
539 # @retval Rule Rule object
541 def __GetRule__ (self
) :
543 if self
.CurrentArch
is None:
544 CurrentArchList
= ['common']
546 CurrentArchList
.append(self
.CurrentArch
)
548 for CurrentArch
in CurrentArchList
:
549 RuleName
= 'RULE' + \
551 CurrentArch
.upper() + \
553 self
.ModuleType
.upper()
554 if self
.Rule
is not None:
555 RuleName
= RuleName
+ \
559 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
561 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
564 RuleName
= 'RULE' + \
568 self
.ModuleType
.upper()
570 if self
.Rule
is not None:
571 RuleName
= RuleName
+ \
575 GenFdsGlobalVariable
.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName
, self
.InfFileName
))
577 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
579 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
583 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'Don\'t Find common rule %s for INF %s' \
584 % (RuleName
, self
.InfFileName
))
586 ## __GetPlatformArchList__() method
588 # Get Arch list this INF built under
590 # @param self The object pointer
591 # @retval list Arch list
593 def __GetPlatformArchList__(self
):
595 InfFileKey
= os
.path
.normpath(mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
))
597 for Arch
in GenFdsGlobalVariable
.ArchList
:
598 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
599 if PlatformDataBase
is not None:
600 if InfFileKey
in PlatformDataBase
.Modules
:
601 DscArchList
.append (Arch
)
604 # BaseTools support build same module more than once, the module path with FILE_GUID overridden has
605 # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key,
606 # but the path (self.MetaFile.Path) is the real path
608 for key
in PlatformDataBase
.Modules
:
609 if InfFileKey
== str((PlatformDataBase
.Modules
[key
]).MetaFile
.Path
):
610 DscArchList
.append (Arch
)
615 ## GetCurrentArch() method
617 # Get Arch list of the module from this INF is to be placed into flash
619 # @param self The object pointer
620 # @retval list Arch list
622 def GetCurrentArch(self
) :
624 TargetArchList
= GenFdsGlobalVariable
.ArchList
626 PlatformArchList
= self
.__GetPlatformArchList
__()
628 CurArchList
= TargetArchList
629 if PlatformArchList
!= []:
630 CurArchList
= list(set (TargetArchList
) & set (PlatformArchList
))
631 GenFdsGlobalVariable
.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList
))
634 if self
.KeyStringList
!= []:
635 for Key
in self
.KeyStringList
:
636 Key
= GenFdsGlobalVariable
.MacroExtend(Key
)
637 Target
, Tag
, Arch
= Key
.split('_')
638 if Arch
in CurArchList
:
639 ArchList
.append(Arch
)
640 if Target
not in self
.TargetOverrideList
:
641 self
.TargetOverrideList
.append(Target
)
643 ArchList
= CurArchList
645 UseArchList
= TargetArchList
646 if self
.UseArch
is not None:
648 UseArchList
.append(self
.UseArch
)
649 ArchList
= list(set (UseArchList
) & set (ArchList
))
651 self
.InfFileName
= NormPath(self
.InfFileName
)
652 if len(PlatformArchList
) == 0:
654 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
655 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
657 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
658 if len(ArchList
) == 1:
661 elif len(ArchList
) > 1:
662 if len(PlatformArchList
) == 0:
663 EdkLogger
.error("GenFds", GENFDS_ERROR
, "GenFds command line option has multiple ARCHs %s. Not able to determine which ARCH is valid for Module %s !" % (str(ArchList
), self
.InfFileName
))
665 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Module built under multiple ARCHs %s. Not able to determine which output to put into flash for Module %s !" % (str(ArchList
), self
.InfFileName
))
667 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Module %s appears under ARCH %s in platform %s, but current deduced ARCH is %s, so NO build output could be put into flash." \
668 % (self
.InfFileName
, str(PlatformArchList
), GenFdsGlobalVariable
.ActivePlatform
, str(set (UseArchList
) & set (TargetArchList
))))
670 ## __GetEFIOutPutPath__() method
672 # Get the output path for generated files
674 # @param self The object pointer
675 # @retval string Path that output files from this INF go to
677 def __GetEFIOutPutPath__(self
):
681 (ModulePath
, FileName
) = os
.path
.split(self
.InfFileName
)
682 Index
= FileName
.rfind('.')
683 FileName
= FileName
[0:Index
]
684 if self
.OverrideGuid
:
685 FileName
= self
.OverrideGuid
687 if self
.CurrentArch
is not None:
688 Arch
= self
.CurrentArch
690 OutputPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
696 DebugPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
702 OutputPath
= os
.path
.realpath(OutputPath
)
703 DebugPath
= os
.path
.realpath(DebugPath
)
704 return OutputPath
, DebugPath
706 ## __GenSimpleFileSection__() method
708 # Generate section by specified file name or a list of files with file extension
710 # @param self The object pointer
711 # @param Rule The rule object used to generate section
712 # @retval string File name of the generated section file
714 def __GenSimpleFileSection__(self
, Rule
, IsMakefile
= False):
716 # Prepare the parameter of GenSection
720 GenSecInputFile
= None
721 if Rule
.FileName
is not None:
722 GenSecInputFile
= self
.__ExtendMacro
__(Rule
.FileName
)
723 if os
.path
.isabs(GenSecInputFile
):
724 GenSecInputFile
= os
.path
.normpath(GenSecInputFile
)
726 GenSecInputFile
= os
.path
.normpath(os
.path
.join(self
.EfiOutputPath
, GenSecInputFile
))
728 FileList
, IsSect
= Section
.Section
.GetFileList(self
, '', Rule
.FileExtension
)
731 SectionType
= Rule
.SectionType
733 # Convert Fv Section Type for PI1.1 SMM driver.
735 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
736 if SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
:
737 SectionType
= BINARY_FILE_TYPE_SMM_DEPEX
739 # Framework SMM Driver has no SMM_DEPEX section type
741 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
742 if SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
743 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
745 if self
.ModuleType
in (SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
):
746 if self
.KeepReloc
is not None:
747 NoStrip
= self
.KeepReloc
748 elif Rule
.KeepReloc
is not None:
749 NoStrip
= Rule
.KeepReloc
750 elif self
.ShadowFromInfFile
is not None:
751 NoStrip
= self
.ShadowFromInfFile
754 for File
in FileList
:
757 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
758 SectionSuffix
[SectionType
] + SUP_MODULE_SEC
+ SecNum
760 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
761 File
= GenFdsGlobalVariable
.MacroExtend(File
, Dict
, self
.CurrentArch
)
763 #Get PE Section alignment when align is set to AUTO
764 if self
.Alignment
== 'Auto' and (SectionType
== BINARY_FILE_TYPE_PE32
or SectionType
== BINARY_FILE_TYPE_TE
):
765 ImageObj
= PeImageClass (File
)
766 if ImageObj
.SectionAlignment
< 0x400:
767 self
.Alignment
= str (ImageObj
.SectionAlignment
)
768 elif ImageObj
.SectionAlignment
< 0x100000:
769 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x400) + 'K'
771 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x100000) + 'M'
774 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
775 if not os
.path
.exists(FileBeforeStrip
) or \
776 (os
.path
.getmtime(File
) > os
.path
.getmtime(FileBeforeStrip
)):
777 CopyLongFilePath(File
, FileBeforeStrip
)
778 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
779 GenFdsGlobalVariable
.GenerateFirmwareImage(
783 IsMakefile
=IsMakefile
787 if SectionType
== BINARY_FILE_TYPE_TE
:
788 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
789 GenFdsGlobalVariable
.GenerateFirmwareImage(
793 IsMakefile
=IsMakefile
796 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [File
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
797 OutputFileList
.append(OutputFile
)
800 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
801 SectionSuffix
[SectionType
] + SUP_MODULE_SEC
+ SecNum
802 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
803 GenSecInputFile
= GenFdsGlobalVariable
.MacroExtend(GenSecInputFile
, Dict
, self
.CurrentArch
)
805 #Get PE Section alignment when align is set to AUTO
806 if self
.Alignment
== 'Auto' and (SectionType
== BINARY_FILE_TYPE_PE32
or SectionType
== BINARY_FILE_TYPE_TE
):
807 ImageObj
= PeImageClass (GenSecInputFile
)
808 if ImageObj
.SectionAlignment
< 0x400:
809 self
.Alignment
= str (ImageObj
.SectionAlignment
)
810 elif ImageObj
.SectionAlignment
< 0x100000:
811 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x400) + 'K'
813 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x100000) + 'M'
816 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
817 if not os
.path
.exists(FileBeforeStrip
) or \
818 (os
.path
.getmtime(GenSecInputFile
) > os
.path
.getmtime(FileBeforeStrip
)):
819 CopyLongFilePath(GenSecInputFile
, FileBeforeStrip
)
821 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
822 GenFdsGlobalVariable
.GenerateFirmwareImage(
826 IsMakefile
=IsMakefile
828 GenSecInputFile
= StrippedFile
830 if SectionType
== BINARY_FILE_TYPE_TE
:
831 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
832 GenFdsGlobalVariable
.GenerateFirmwareImage(
836 IsMakefile
=IsMakefile
838 GenSecInputFile
= TeFile
839 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [GenSecInputFile
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
840 OutputFileList
.append(OutputFile
)
842 return OutputFileList
844 ## __GenSimpleFileFfs__() method
848 # @param self The object pointer
849 # @param Rule The rule object used to generate section
850 # @param InputFileList The output file list from GenSection
851 # @retval string Generated FFS file name
853 def __GenSimpleFileFfs__(self
, Rule
, InputFileList
, MakefilePath
= None):
854 FfsOutput
= self
.OutputPath
+ \
856 self
.__ExtendMacro
__(Rule
.NameGuid
) + \
859 GenFdsGlobalVariable
.VerboseLogger(self
.__ExtendMacro
__(Rule
.NameGuid
))
861 SectionAlignments
= []
862 for InputFile
in InputFileList
:
863 InputSection
.append(InputFile
)
864 SectionAlignments
.append(Rule
.SectAlignment
)
866 if Rule
.NameGuid
is not None and Rule
.NameGuid
.startswith('PCD('):
867 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
868 if len(PcdValue
) == 0:
869 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
871 if PcdValue
.startswith('{'):
872 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
873 RegistryGuidStr
= PcdValue
874 if len(RegistryGuidStr
) == 0:
875 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
877 self
.ModuleGuid
= RegistryGuidStr
879 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputSection
,
880 FdfFvFileTypeToFileType
[Rule
.FvFileType
],
881 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
882 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
883 SectionAlign
=SectionAlignments
,
884 MakefilePath
=MakefilePath
888 ## __GenComplexFileSection__() method
890 # Generate section by sections in Rule
892 # @param self The object pointer
893 # @param Rule The rule object used to generate section
894 # @param FvChildAddr Array of the inside FvImage base address
895 # @param FvParentAddr Parent Fv base address
896 # @retval string File name of the generated section file
898 def __GenComplexFileSection__(self
, Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
= False):
899 if self
.ModuleType
in (SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
, SUP_MODULE_MM_CORE_STANDALONE
):
900 if Rule
.KeepReloc
is not None:
901 self
.KeepRelocFromRule
= Rule
.KeepReloc
905 HasGeneratedFlag
= False
906 if self
.PcdIsDriver
== 'PEI_PCD_DRIVER':
907 if self
.IsBinaryModule
:
908 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "PEIPcdDataBase.raw")
910 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "PEIPcdDataBase.raw")
911 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "PEIPcdDataBaseSec.raw")
912 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
915 IsMakefile
= IsMakefile
917 SectFiles
.append(PcdExDbSecName
)
918 SectAlignments
.append(None)
919 elif self
.PcdIsDriver
== 'DXE_PCD_DRIVER':
920 if self
.IsBinaryModule
:
921 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "DXEPcdDataBase.raw")
923 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "DXEPcdDataBase.raw")
924 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "DXEPcdDataBaseSec.raw")
925 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
928 IsMakefile
= IsMakefile
930 SectFiles
.append(PcdExDbSecName
)
931 SectAlignments
.append(None)
932 for Sect
in Rule
.SectionList
:
933 SecIndex
= '%d' %Index
936 # Convert Fv Section Type for PI1.1 SMM driver.
938 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
939 if Sect
.SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
:
940 Sect
.SectionType
= BINARY_FILE_TYPE_SMM_DEPEX
942 # Framework SMM Driver has no SMM_DEPEX section type
944 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
945 if Sect
.SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
946 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
948 # process the inside FvImage from FvSection or GuidSection
950 if FvChildAddr
!= []:
951 if isinstance(Sect
, FvImageSection
):
952 Sect
.FvAddr
= FvChildAddr
.pop(0)
953 elif isinstance(Sect
, GuidSection
):
954 Sect
.FvAddr
= FvChildAddr
955 if FvParentAddr
is not None and isinstance(Sect
, GuidSection
):
956 Sect
.FvParentAddr
= FvParentAddr
958 if Rule
.KeyStringList
!= []:
959 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, Rule
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
961 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, self
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
963 if not HasGeneratedFlag
:
964 UniVfrOffsetFileSection
= ""
965 ModuleFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
)
966 InfData
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClass(ModuleFileName
), self
.CurrentArch
]
968 # Search the source list in InfData to find if there are .vfr file exist.
971 VfrUniOffsetList
= []
972 for SourceFile
in InfData
.Sources
:
973 if SourceFile
.Type
.upper() == ".VFR" :
975 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
977 VfrUniBaseName
[SourceFile
.BaseName
] = (SourceFile
.BaseName
+ "Bin")
978 if SourceFile
.Type
.upper() == ".UNI" :
980 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
982 VfrUniBaseName
["UniOffsetName"] = (self
.BaseName
+ "Strings")
985 if len(VfrUniBaseName
) > 0:
987 if InfData
.BuildType
!= 'UEFI_HII':
988 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
989 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
990 UniVfrOffsetFileNameList
= []
991 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
992 TrimCmd
= "Trim --Vfr-Uni-Offset -o %s --ModuleName=%s --DebugDir=%s " % (UniVfrOffsetFileName
, self
.BaseName
, self
.EfiDebugPath
)
993 GenFdsGlobalVariable
.SecCmdList
.append(TrimCmd
)
994 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
995 [UniVfrOffsetFileName
],
1000 VfrUniOffsetList
= self
.__GetBuildOutputMapFileVfrUniInfo
(VfrUniBaseName
)
1002 # Generate the Raw data of raw section
1004 if VfrUniOffsetList
:
1005 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
1006 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
1007 FfsInfStatement
.__GenUniVfrOffsetFile
(VfrUniOffsetList
, UniVfrOffsetFileName
)
1008 UniVfrOffsetFileNameList
= []
1009 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
1010 """Call GenSection"""
1012 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
1013 UniVfrOffsetFileNameList
,
1016 #os.remove(UniVfrOffsetFileName)
1017 if UniVfrOffsetFileSection
:
1018 SectList
.append(UniVfrOffsetFileSection
)
1019 HasGeneratedFlag
= True
1021 for SecName
in SectList
:
1022 SectFiles
.append(SecName
)
1023 SectAlignments
.append(Align
)
1025 return SectFiles
, SectAlignments
1027 ## __GenComplexFileFfs__() method
1031 # @param self The object pointer
1032 # @param Rule The rule object used to generate section
1033 # @param InputFileList The output file list from GenSection
1034 # @retval string Generated FFS file name
1036 def __GenComplexFileFfs__(self
, Rule
, InputFile
, Alignments
, MakefilePath
= None):
1038 if Rule
.NameGuid
is not None and Rule
.NameGuid
.startswith('PCD('):
1039 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
1040 if len(PcdValue
) == 0:
1041 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
1043 if PcdValue
.startswith('{'):
1044 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
1045 RegistryGuidStr
= PcdValue
1046 if len(RegistryGuidStr
) == 0:
1047 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
1049 self
.ModuleGuid
= RegistryGuidStr
1051 FfsOutput
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
1052 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputFile
,
1053 FdfFvFileTypeToFileType
[Rule
.FvFileType
],
1054 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
1055 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
1056 SectionAlign
=Alignments
,
1057 MakefilePath
=MakefilePath
1061 ## __GetBuildOutputMapFileVfrUniInfo() method
1063 # Find the offset of UNI/INF object offset in the EFI image file.
1065 # @param self The object pointer
1066 # @param VfrUniBaseName A name list contain the UNI/INF object name.
1067 # @retval RetValue A list contain offset of UNI/INF object.
1069 def __GetBuildOutputMapFileVfrUniInfo(self
, VfrUniBaseName
):
1070 MapFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".map")
1071 EfiFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".efi")
1072 return GetVariableOffset(MapFileName
, EfiFileName
, list(VfrUniBaseName
.values()))
1074 ## __GenUniVfrOffsetFile() method
1076 # Generate the offset file for the module which contain VFR or UNI file.
1078 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
1079 # @param UniVfrOffsetFileName The output offset file name.
1082 def __GenUniVfrOffsetFile(VfrUniOffsetList
, UniVfrOffsetFileName
):
1084 # Use a instance of StringIO to cache data
1085 fStringIO
= BytesIO()
1087 for Item
in VfrUniOffsetList
:
1088 if (Item
[0].find("Strings") != -1):
1090 # UNI offset in image.
1092 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
1094 UniGuid
= b
'\xe0\xc5\x13\x89\xf63\x86M\x9b\xf1C\xef\x89\xfc\x06f'
1095 fStringIO
.write(UniGuid
)
1096 UniValue
= pack ('Q', int (Item
[1], 16))
1097 fStringIO
.write (UniValue
)
1100 # VFR binary offset in image.
1102 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
1104 VfrGuid
= b
'\xb4|\xbc\xd0Gj_I\xaa\x11q\x07F\xda\x06\xa2'
1105 fStringIO
.write(VfrGuid
)
1107 VfrValue
= pack ('Q', int (Item
[1], 16))
1108 fStringIO
.write (VfrValue
)
1111 # write data into file.
1114 SaveFileOnChange(UniVfrOffsetFileName
, fStringIO
.getvalue())
1116 EdkLogger
.error("GenFds", FILE_WRITE_FAILURE
, "Write data to file %s failed, please check whether the file been locked or using by other applications." %UniVfrOffsetFileName
, None)