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
= None, IsGenFfs
=False):
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 Rule
= self
.__GetRule
__()
353 if GlobalData
.gGuidPatternEnd
.match(Rule
.NameGuid
):
354 self
.ModuleGuid
= Rule
.NameGuid
355 self
.OutputPath
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, \
356 self
.ModuleGuid
+ self
.BaseName
)
357 if not os
.path
.exists(self
.OutputPath
) :
358 os
.makedirs(self
.OutputPath
)
360 self
.EfiOutputPath
, self
.EfiDebugPath
= self
.__GetEFIOutPutPath
__()
361 GenFdsGlobalVariable
.VerboseLogger( "ModuelEFIPath: " + self
.EfiOutputPath
)
365 # Patch EFI file with patch PCD
367 # @param EfiFile: EFI file needs to be patched.
368 # @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name
369 # If passed in file does not end with efi, return as is
371 def PatchEfiFile(self
, EfiFile
, FileType
):
373 # If the module does not have any patches, then return path to input file
375 if not self
.PatchPcds
:
379 # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED
381 if FileType
!= BINARY_FILE_TYPE_PE32
and self
.ModuleType
!= SUP_MODULE_USER_DEFINED
:
385 # Generate path to patched output file
387 Basename
= os
.path
.basename(EfiFile
)
388 Output
= os
.path
.normpath (os
.path
.join(self
.OutputPath
, Basename
))
391 # If this file has already been patched, then return the path to the patched file
393 if self
.PatchedBinFile
== Output
:
397 # If a different file from the same module has already been patched, then generate an error
399 if self
.PatchedBinFile
:
400 EdkLogger
.error("GenFds", GENFDS_ERROR
,
401 'Only one binary file can be patched:\n'
402 ' a binary file has been patched: %s\n'
403 ' current file: %s' % (self
.PatchedBinFile
, EfiFile
),
404 File
=self
.InfFileName
)
407 # Copy unpatched file contents to output file location to perform patching
409 CopyLongFilePath(EfiFile
, Output
)
412 # Apply patches to patched output file
414 for Pcd
, Value
in self
.PatchPcds
:
415 RetVal
, RetStr
= PatchBinaryFile(Output
, int(Pcd
.Offset
, 0), Pcd
.DatumType
, Value
, Pcd
.MaxDatumSize
)
417 EdkLogger
.error("GenFds", GENFDS_ERROR
, RetStr
, File
=self
.InfFileName
)
420 # Save the path of the patched output file
422 self
.PatchedBinFile
= Output
425 # Return path to patched output file
433 # @param self The object pointer
434 # @param Dict dictionary contains macro and value pair
435 # @param FvChildAddr Array of the inside FvImage base address
436 # @param FvParentAddr Parent Fv base address
437 # @retval string Generated FFS file name
439 def GenFfs(self
, Dict
= {}, FvChildAddr
= [], FvParentAddr
=None, IsMakefile
=False, FvName
=None):
441 # Parse Inf file get Module related information
444 self
.__InfParse
__(Dict
, IsGenFfs
=True)
445 Arch
= self
.GetCurrentArch()
446 SrcFile
= mws
.join( GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
);
447 DestFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
450 SrcPath
= os
.path
.dirname(SrcFile
)
451 SrcFileName
= os
.path
.basename(SrcFile
)
452 SrcFileBase
, SrcFileExt
= os
.path
.splitext(SrcFileName
)
453 DestPath
= os
.path
.dirname(DestFile
)
454 DestFileName
= os
.path
.basename(DestFile
)
455 DestFileBase
, DestFileExt
= os
.path
.splitext(DestFileName
)
459 "${s_path}" : SrcPath
,
460 "${s_dir}" : SrcFileDir
,
461 "${s_name}" : SrcFileName
,
462 "${s_base}" : SrcFileBase
,
463 "${s_ext}" : SrcFileExt
,
466 "${d_path}" : DestPath
,
467 "${d_name}" : DestFileName
,
468 "${d_base}" : DestFileBase
,
469 "${d_ext}" : DestFileExt
472 # Allow binary type module not specify override rule in FDF file.
474 if len(self
.BinFileList
) > 0:
475 if self
.Rule
is None or self
.Rule
== "":
478 if not IsMakefile
and GenFdsGlobalVariable
.EnableGenfdsMultiThread
and self
.Rule
!= 'BINARY':
481 # Get the rule of how to generate Ffs file
483 Rule
= self
.__GetRule
__()
484 GenFdsGlobalVariable
.VerboseLogger( "Packing binaries from inf file : %s" %self
.InfFileName
)
486 # Convert Fv File Type for PI1.1 SMM driver.
488 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
489 if Rule
.FvFileType
== 'DRIVER':
490 Rule
.FvFileType
= 'SMM'
492 # Framework SMM Driver has no SMM FV file type
494 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
495 if Rule
.FvFileType
== 'SMM' or Rule
.FvFileType
== SUP_MODULE_SMM_CORE
:
496 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File
=self
.InfFileName
)
498 # For the rule only has simpleFile
501 if self
.IsBinaryModule
:
504 MakefilePath
= self
.InfFileName
, Arch
505 if isinstance (Rule
, RuleSimpleFile
.RuleSimpleFile
):
506 SectionOutputList
= self
.__GenSimpleFileSection
__(Rule
, IsMakefile
=IsMakefile
)
507 FfsOutput
= self
.__GenSimpleFileFfs
__(Rule
, SectionOutputList
, MakefilePath
=MakefilePath
)
510 # For Rule has ComplexFile
512 elif isinstance(Rule
, RuleComplexFile
.RuleComplexFile
):
513 InputSectList
, InputSectAlignments
= self
.__GenComplexFileSection
__(Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
=IsMakefile
)
514 FfsOutput
= self
.__GenComplexFileFfs
__(Rule
, InputSectList
, InputSectAlignments
, MakefilePath
=MakefilePath
)
517 ## __ExtendMacro__() method
519 # Replace macro with its value
521 # @param self The object pointer
522 # @param String The string to be replaced
523 # @retval string Macro replaced string
525 def __ExtendMacro__ (self
, String
):
527 '$(INF_OUTPUT)' : self
.EfiOutputPath
,
528 '$(MODULE_NAME)' : self
.BaseName
,
529 '$(BUILD_NUMBER)': self
.BuildNum
,
530 '$(INF_VERSION)' : self
.VersionString
,
531 '$(NAMED_GUID)' : self
.ModuleGuid
533 String
= GenFdsGlobalVariable
.MacroExtend(String
, MacroDict
)
534 String
= GenFdsGlobalVariable
.MacroExtend(String
, self
.MacroDict
)
537 ## __GetRule__() method
539 # Get correct rule for generating FFS for this INF
541 # @param self The object pointer
542 # @retval Rule Rule object
544 def __GetRule__ (self
) :
546 if self
.CurrentArch
is None:
547 CurrentArchList
= ['common']
549 CurrentArchList
.append(self
.CurrentArch
)
551 for CurrentArch
in CurrentArchList
:
552 RuleName
= 'RULE' + \
554 CurrentArch
.upper() + \
556 self
.ModuleType
.upper()
557 if self
.Rule
is not None:
558 RuleName
= RuleName
+ \
562 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
564 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
567 RuleName
= 'RULE' + \
571 self
.ModuleType
.upper()
573 if self
.Rule
is not None:
574 RuleName
= RuleName
+ \
578 GenFdsGlobalVariable
.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName
, self
.InfFileName
))
580 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
582 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
586 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'Don\'t Find common rule %s for INF %s' \
587 % (RuleName
, self
.InfFileName
))
589 ## __GetPlatformArchList__() method
591 # Get Arch list this INF built under
593 # @param self The object pointer
594 # @retval list Arch list
596 def __GetPlatformArchList__(self
):
598 InfFileKey
= os
.path
.normpath(mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
))
600 for Arch
in GenFdsGlobalVariable
.ArchList
:
601 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
602 if PlatformDataBase
is not None:
603 if InfFileKey
in PlatformDataBase
.Modules
:
604 DscArchList
.append (Arch
)
607 # BaseTools support build same module more than once, the module path with FILE_GUID overridden has
608 # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key,
609 # but the path (self.MetaFile.Path) is the real path
611 for key
in PlatformDataBase
.Modules
:
612 if InfFileKey
== str((PlatformDataBase
.Modules
[key
]).MetaFile
.Path
):
613 DscArchList
.append (Arch
)
618 ## GetCurrentArch() method
620 # Get Arch list of the module from this INF is to be placed into flash
622 # @param self The object pointer
623 # @retval list Arch list
625 def GetCurrentArch(self
) :
627 TargetArchList
= GenFdsGlobalVariable
.ArchList
629 PlatformArchList
= self
.__GetPlatformArchList
__()
631 CurArchList
= TargetArchList
632 if PlatformArchList
!= []:
633 CurArchList
= list(set (TargetArchList
) & set (PlatformArchList
))
634 GenFdsGlobalVariable
.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList
))
637 if self
.KeyStringList
!= []:
638 for Key
in self
.KeyStringList
:
639 Key
= GenFdsGlobalVariable
.MacroExtend(Key
)
640 Target
, Tag
, Arch
= Key
.split('_')
641 if Arch
in CurArchList
:
642 ArchList
.append(Arch
)
643 if Target
not in self
.TargetOverrideList
:
644 self
.TargetOverrideList
.append(Target
)
646 ArchList
= CurArchList
648 UseArchList
= TargetArchList
649 if self
.UseArch
is not None:
651 UseArchList
.append(self
.UseArch
)
652 ArchList
= list(set (UseArchList
) & set (ArchList
))
654 self
.InfFileName
= NormPath(self
.InfFileName
)
655 if len(PlatformArchList
) == 0:
657 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
658 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
660 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
661 if len(ArchList
) == 1:
664 elif len(ArchList
) > 1:
665 if len(PlatformArchList
) == 0:
666 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
))
668 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
))
670 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." \
671 % (self
.InfFileName
, str(PlatformArchList
), GenFdsGlobalVariable
.ActivePlatform
, str(set (UseArchList
) & set (TargetArchList
))))
673 ## __GetEFIOutPutPath__() method
675 # Get the output path for generated files
677 # @param self The object pointer
678 # @retval string Path that output files from this INF go to
680 def __GetEFIOutPutPath__(self
):
684 (ModulePath
, FileName
) = os
.path
.split(self
.InfFileName
)
685 Index
= FileName
.rfind('.')
686 FileName
= FileName
[0:Index
]
687 if self
.OverrideGuid
:
688 FileName
= self
.OverrideGuid
690 if self
.CurrentArch
is not None:
691 Arch
= self
.CurrentArch
693 OutputPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
699 DebugPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
705 OutputPath
= os
.path
.realpath(OutputPath
)
706 DebugPath
= os
.path
.realpath(DebugPath
)
707 return OutputPath
, DebugPath
709 ## __GenSimpleFileSection__() method
711 # Generate section by specified file name or a list of files with file extension
713 # @param self The object pointer
714 # @param Rule The rule object used to generate section
715 # @retval string File name of the generated section file
717 def __GenSimpleFileSection__(self
, Rule
, IsMakefile
= False):
719 # Prepare the parameter of GenSection
723 GenSecInputFile
= None
724 if Rule
.FileName
is not None:
725 GenSecInputFile
= self
.__ExtendMacro
__(Rule
.FileName
)
726 if os
.path
.isabs(GenSecInputFile
):
727 GenSecInputFile
= os
.path
.normpath(GenSecInputFile
)
729 GenSecInputFile
= os
.path
.normpath(os
.path
.join(self
.EfiOutputPath
, GenSecInputFile
))
731 FileList
, IsSect
= Section
.Section
.GetFileList(self
, '', Rule
.FileExtension
)
734 SectionType
= Rule
.SectionType
736 # Convert Fv Section Type for PI1.1 SMM driver.
738 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
739 if SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
:
740 SectionType
= BINARY_FILE_TYPE_SMM_DEPEX
742 # Framework SMM Driver has no SMM_DEPEX section type
744 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
745 if SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
746 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
748 if self
.ModuleType
in (SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
):
749 if self
.KeepReloc
is not None:
750 NoStrip
= self
.KeepReloc
751 elif Rule
.KeepReloc
is not None:
752 NoStrip
= Rule
.KeepReloc
753 elif self
.ShadowFromInfFile
is not None:
754 NoStrip
= self
.ShadowFromInfFile
757 for File
in FileList
:
760 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
761 SectionSuffix
[SectionType
] + SUP_MODULE_SEC
+ SecNum
763 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
764 File
= GenFdsGlobalVariable
.MacroExtend(File
, Dict
, self
.CurrentArch
)
766 #Get PE Section alignment when align is set to AUTO
767 if self
.Alignment
== 'Auto' and (SectionType
== BINARY_FILE_TYPE_PE32
or SectionType
== BINARY_FILE_TYPE_TE
):
768 ImageObj
= PeImageClass (File
)
769 if ImageObj
.SectionAlignment
< 0x400:
770 self
.Alignment
= str (ImageObj
.SectionAlignment
)
771 elif ImageObj
.SectionAlignment
< 0x100000:
772 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x400) + 'K'
774 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x100000) + 'M'
777 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
778 if not os
.path
.exists(FileBeforeStrip
) or \
779 (os
.path
.getmtime(File
) > os
.path
.getmtime(FileBeforeStrip
)):
780 CopyLongFilePath(File
, FileBeforeStrip
)
781 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
782 GenFdsGlobalVariable
.GenerateFirmwareImage(
786 IsMakefile
=IsMakefile
790 if SectionType
== BINARY_FILE_TYPE_TE
:
791 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
792 GenFdsGlobalVariable
.GenerateFirmwareImage(
796 IsMakefile
=IsMakefile
799 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [File
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
800 OutputFileList
.append(OutputFile
)
803 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
804 SectionSuffix
[SectionType
] + SUP_MODULE_SEC
+ SecNum
805 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
806 GenSecInputFile
= GenFdsGlobalVariable
.MacroExtend(GenSecInputFile
, Dict
, self
.CurrentArch
)
808 #Get PE Section alignment when align is set to AUTO
809 if self
.Alignment
== 'Auto' and (SectionType
== BINARY_FILE_TYPE_PE32
or SectionType
== BINARY_FILE_TYPE_TE
):
810 ImageObj
= PeImageClass (GenSecInputFile
)
811 if ImageObj
.SectionAlignment
< 0x400:
812 self
.Alignment
= str (ImageObj
.SectionAlignment
)
813 elif ImageObj
.SectionAlignment
< 0x100000:
814 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x400) + 'K'
816 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x100000) + 'M'
819 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
820 if not os
.path
.exists(FileBeforeStrip
) or \
821 (os
.path
.getmtime(GenSecInputFile
) > os
.path
.getmtime(FileBeforeStrip
)):
822 CopyLongFilePath(GenSecInputFile
, FileBeforeStrip
)
824 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
825 GenFdsGlobalVariable
.GenerateFirmwareImage(
829 IsMakefile
=IsMakefile
831 GenSecInputFile
= StrippedFile
833 if SectionType
== BINARY_FILE_TYPE_TE
:
834 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
835 GenFdsGlobalVariable
.GenerateFirmwareImage(
839 IsMakefile
=IsMakefile
841 GenSecInputFile
= TeFile
842 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [GenSecInputFile
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
843 OutputFileList
.append(OutputFile
)
845 return OutputFileList
847 ## __GenSimpleFileFfs__() method
851 # @param self The object pointer
852 # @param Rule The rule object used to generate section
853 # @param InputFileList The output file list from GenSection
854 # @retval string Generated FFS file name
856 def __GenSimpleFileFfs__(self
, Rule
, InputFileList
, MakefilePath
= None):
857 FfsOutput
= self
.OutputPath
+ \
859 self
.__ExtendMacro
__(Rule
.NameGuid
) + \
862 GenFdsGlobalVariable
.VerboseLogger(self
.__ExtendMacro
__(Rule
.NameGuid
))
864 SectionAlignments
= []
865 for InputFile
in InputFileList
:
866 InputSection
.append(InputFile
)
867 SectionAlignments
.append(Rule
.SectAlignment
)
869 if Rule
.NameGuid
is not None and Rule
.NameGuid
.startswith('PCD('):
870 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
871 if len(PcdValue
) == 0:
872 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
874 if PcdValue
.startswith('{'):
875 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
876 RegistryGuidStr
= PcdValue
877 if len(RegistryGuidStr
) == 0:
878 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
880 self
.ModuleGuid
= RegistryGuidStr
882 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputSection
,
883 FdfFvFileTypeToFileType
[Rule
.FvFileType
],
884 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
885 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
886 SectionAlign
=SectionAlignments
,
887 MakefilePath
=MakefilePath
891 ## __GenComplexFileSection__() method
893 # Generate section by sections in Rule
895 # @param self The object pointer
896 # @param Rule The rule object used to generate section
897 # @param FvChildAddr Array of the inside FvImage base address
898 # @param FvParentAddr Parent Fv base address
899 # @retval string File name of the generated section file
901 def __GenComplexFileSection__(self
, Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
= False):
902 if self
.ModuleType
in (SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
, SUP_MODULE_MM_CORE_STANDALONE
):
903 if Rule
.KeepReloc
is not None:
904 self
.KeepRelocFromRule
= Rule
.KeepReloc
908 HasGeneratedFlag
= False
909 if self
.PcdIsDriver
== 'PEI_PCD_DRIVER':
910 if self
.IsBinaryModule
:
911 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "PEIPcdDataBase.raw")
913 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "PEIPcdDataBase.raw")
914 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "PEIPcdDataBaseSec.raw")
915 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
918 IsMakefile
= IsMakefile
920 SectFiles
.append(PcdExDbSecName
)
921 SectAlignments
.append(None)
922 elif self
.PcdIsDriver
== 'DXE_PCD_DRIVER':
923 if self
.IsBinaryModule
:
924 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "DXEPcdDataBase.raw")
926 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "DXEPcdDataBase.raw")
927 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "DXEPcdDataBaseSec.raw")
928 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
931 IsMakefile
= IsMakefile
933 SectFiles
.append(PcdExDbSecName
)
934 SectAlignments
.append(None)
935 for Sect
in Rule
.SectionList
:
936 SecIndex
= '%d' %Index
939 # Convert Fv Section Type for PI1.1 SMM driver.
941 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
942 if Sect
.SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
:
943 Sect
.SectionType
= BINARY_FILE_TYPE_SMM_DEPEX
945 # Framework SMM Driver has no SMM_DEPEX section type
947 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
948 if Sect
.SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
949 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
951 # process the inside FvImage from FvSection or GuidSection
953 if FvChildAddr
!= []:
954 if isinstance(Sect
, FvImageSection
):
955 Sect
.FvAddr
= FvChildAddr
.pop(0)
956 elif isinstance(Sect
, GuidSection
):
957 Sect
.FvAddr
= FvChildAddr
958 if FvParentAddr
is not None and isinstance(Sect
, GuidSection
):
959 Sect
.FvParentAddr
= FvParentAddr
961 if Rule
.KeyStringList
!= []:
962 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, Rule
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
964 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, self
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
966 if not HasGeneratedFlag
:
967 UniVfrOffsetFileSection
= ""
968 ModuleFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
)
969 InfData
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClass(ModuleFileName
), self
.CurrentArch
]
971 # Search the source list in InfData to find if there are .vfr file exist.
974 VfrUniOffsetList
= []
975 for SourceFile
in InfData
.Sources
:
976 if SourceFile
.Type
.upper() == ".VFR" :
978 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
980 VfrUniBaseName
[SourceFile
.BaseName
] = (SourceFile
.BaseName
+ "Bin")
981 if SourceFile
.Type
.upper() == ".UNI" :
983 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
985 VfrUniBaseName
["UniOffsetName"] = (self
.BaseName
+ "Strings")
988 if len(VfrUniBaseName
) > 0:
990 if InfData
.BuildType
!= 'UEFI_HII':
991 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
992 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
993 UniVfrOffsetFileNameList
= []
994 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
995 TrimCmd
= "Trim --Vfr-Uni-Offset -o %s --ModuleName=%s --DebugDir=%s " % (UniVfrOffsetFileName
, self
.BaseName
, self
.EfiDebugPath
)
996 GenFdsGlobalVariable
.SecCmdList
.append(TrimCmd
)
997 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
998 [UniVfrOffsetFileName
],
1003 VfrUniOffsetList
= self
.__GetBuildOutputMapFileVfrUniInfo
(VfrUniBaseName
)
1005 # Generate the Raw data of raw section
1007 if VfrUniOffsetList
:
1008 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
1009 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
1010 FfsInfStatement
.__GenUniVfrOffsetFile
(VfrUniOffsetList
, UniVfrOffsetFileName
)
1011 UniVfrOffsetFileNameList
= []
1012 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
1013 """Call GenSection"""
1015 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
1016 UniVfrOffsetFileNameList
,
1019 #os.remove(UniVfrOffsetFileName)
1020 if UniVfrOffsetFileSection
:
1021 SectList
.append(UniVfrOffsetFileSection
)
1022 HasGeneratedFlag
= True
1024 for SecName
in SectList
:
1025 SectFiles
.append(SecName
)
1026 SectAlignments
.append(Align
)
1028 return SectFiles
, SectAlignments
1030 ## __GenComplexFileFfs__() method
1034 # @param self The object pointer
1035 # @param Rule The rule object used to generate section
1036 # @param InputFileList The output file list from GenSection
1037 # @retval string Generated FFS file name
1039 def __GenComplexFileFfs__(self
, Rule
, InputFile
, Alignments
, MakefilePath
= None):
1041 if Rule
.NameGuid
is not None and Rule
.NameGuid
.startswith('PCD('):
1042 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
1043 if len(PcdValue
) == 0:
1044 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
1046 if PcdValue
.startswith('{'):
1047 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
1048 RegistryGuidStr
= PcdValue
1049 if len(RegistryGuidStr
) == 0:
1050 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
1052 self
.ModuleGuid
= RegistryGuidStr
1054 FfsOutput
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
1055 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputFile
,
1056 FdfFvFileTypeToFileType
[Rule
.FvFileType
],
1057 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
1058 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
1059 SectionAlign
=Alignments
,
1060 MakefilePath
=MakefilePath
1064 ## __GetBuildOutputMapFileVfrUniInfo() method
1066 # Find the offset of UNI/INF object offset in the EFI image file.
1068 # @param self The object pointer
1069 # @param VfrUniBaseName A name list contain the UNI/INF object name.
1070 # @retval RetValue A list contain offset of UNI/INF object.
1072 def __GetBuildOutputMapFileVfrUniInfo(self
, VfrUniBaseName
):
1073 MapFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".map")
1074 EfiFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".efi")
1075 return GetVariableOffset(MapFileName
, EfiFileName
, list(VfrUniBaseName
.values()))
1077 ## __GenUniVfrOffsetFile() method
1079 # Generate the offset file for the module which contain VFR or UNI file.
1081 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
1082 # @param UniVfrOffsetFileName The output offset file name.
1085 def __GenUniVfrOffsetFile(VfrUniOffsetList
, UniVfrOffsetFileName
):
1087 # Use a instance of StringIO to cache data
1088 fStringIO
= BytesIO()
1090 for Item
in VfrUniOffsetList
:
1091 if (Item
[0].find("Strings") != -1):
1093 # UNI offset in image.
1095 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
1097 UniGuid
= b
'\xe0\xc5\x13\x89\xf63\x86M\x9b\xf1C\xef\x89\xfc\x06f'
1098 fStringIO
.write(UniGuid
)
1099 UniValue
= pack ('Q', int (Item
[1], 16))
1100 fStringIO
.write (UniValue
)
1103 # VFR binary offset in image.
1105 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
1107 VfrGuid
= b
'\xb4|\xbc\xd0Gj_I\xaa\x11q\x07F\xda\x06\xa2'
1108 fStringIO
.write(VfrGuid
)
1110 VfrValue
= pack ('Q', int (Item
[1], 16))
1111 fStringIO
.write (VfrValue
)
1114 # write data into file.
1117 SaveFileOnChange(UniVfrOffsetFileName
, fStringIO
.getvalue())
1119 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)