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
.DataType
import SUP_MODULE_HOST_APPLICATION
29 from Common
.StringUtils
import *
30 from Common
.Misc
import PathClass
31 from Common
.Misc
import GuidStructureByteArrayToGuidString
32 from Common
.Misc
import ProcessDuplicatedInf
33 from Common
.Misc
import GetVariableOffset
34 from Common
import EdkLogger
35 from Common
.BuildToolError
import *
36 from .GuidSection
import GuidSection
37 from .FvImageSection
import FvImageSection
38 from Common
.Misc
import PeImageClass
39 from AutoGen
.GenDepex
import DependencyExpression
40 from PatchPcdValue
.PatchPcdValue
import PatchBinaryFile
41 from Common
.LongFilePathSupport
import CopyLongFilePath
42 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
43 import Common
.GlobalData
as GlobalData
44 from .DepexSection
import DepexSection
45 from Common
.Misc
import SaveFileOnChange
46 from Common
.Expression
import *
47 from Common
.DataType
import *
49 ## generate FFS from INF
52 class FfsInfStatement(FfsInfStatementClassObject
):
55 # @param self The object pointer
58 FfsInfStatementClassObject
.__init
__(self
)
59 self
.TargetOverrideList
= []
60 self
.ShadowFromInfFile
= None
61 self
.KeepRelocFromRule
= None
64 self
.PiSpecVersion
= '0x00000000'
66 self
.FinalTargetSuffixMap
= {}
67 self
.CurrentLineNum
= None
68 self
.CurrentLineContent
= None
70 self
.InfFileName
= None
71 self
.OverrideGuid
= None
72 self
.PatchedBinFile
= ''
76 ## GetFinalTargetSuffixMap() method
78 # Get final build target list
79 def GetFinalTargetSuffixMap(self
):
80 if not self
.InfModule
or not self
.CurrentArch
:
82 if not self
.FinalTargetSuffixMap
:
83 FinalBuildTargetList
= GenFdsGlobalVariable
.GetModuleCodaTargetList(self
.InfModule
, self
.CurrentArch
)
84 for File
in FinalBuildTargetList
:
85 self
.FinalTargetSuffixMap
.setdefault(os
.path
.splitext(File
)[1], []).append(File
)
87 # Check if current INF module has DEPEX
88 if '.depex' not in self
.FinalTargetSuffixMap
and self
.InfModule
.ModuleType
!= SUP_MODULE_USER_DEFINED
and self
.InfModule
.ModuleType
!= SUP_MODULE_HOST_APPLICATION \
89 and not self
.InfModule
.DxsFile
and not self
.InfModule
.LibraryClass
:
90 ModuleType
= self
.InfModule
.ModuleType
91 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
93 if ModuleType
!= SUP_MODULE_USER_DEFINED
and ModuleType
!= SUP_MODULE_HOST_APPLICATION
:
94 for LibraryClass
in PlatformDataBase
.LibraryClasses
.GetKeys():
95 if LibraryClass
.startswith("NULL") and PlatformDataBase
.LibraryClasses
[LibraryClass
, ModuleType
]:
96 self
.InfModule
.LibraryClasses
[LibraryClass
] = PlatformDataBase
.LibraryClasses
[LibraryClass
, ModuleType
]
98 StrModule
= str(self
.InfModule
)
100 if StrModule
in PlatformDataBase
.Modules
:
101 PlatformModule
= PlatformDataBase
.Modules
[StrModule
]
102 for LibraryClass
in PlatformModule
.LibraryClasses
:
103 if LibraryClass
.startswith("NULL"):
104 self
.InfModule
.LibraryClasses
[LibraryClass
] = PlatformModule
.LibraryClasses
[LibraryClass
]
106 DependencyList
= [self
.InfModule
]
109 while len(DependencyList
) > 0:
110 Module
= DependencyList
.pop(0)
113 for Dep
in Module
.Depex
[self
.CurrentArch
, ModuleType
]:
115 DepexList
.append('AND')
116 DepexList
.append('(')
117 DepexList
.extend(Dep
)
118 if DepexList
[-1] == 'END': # no need of a END at this time
120 DepexList
.append(')')
121 if 'BEFORE' in DepexList
or 'AFTER' in DepexList
:
123 for LibName
in Module
.LibraryClasses
:
124 if LibName
in LibraryInstance
:
126 if PlatformModule
and LibName
in PlatformModule
.LibraryClasses
:
127 LibraryPath
= PlatformModule
.LibraryClasses
[LibName
]
129 LibraryPath
= PlatformDataBase
.LibraryClasses
[LibName
, ModuleType
]
131 LibraryPath
= Module
.LibraryClasses
[LibName
]
134 LibraryModule
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[LibraryPath
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
135 LibraryInstance
[LibName
] = LibraryModule
136 DependencyList
.append(LibraryModule
)
138 Dpx
= DependencyExpression(DepexList
, ModuleType
, True)
139 if len(Dpx
.PostfixNotation
) != 0:
140 # It means this module has DEPEX
141 self
.FinalTargetSuffixMap
['.depex'] = [os
.path
.join(self
.EfiOutputPath
, self
.BaseName
) + '.depex']
142 return self
.FinalTargetSuffixMap
144 ## __InfParse() method
146 # Parse inf file to get module information
148 # @param self The object pointer
149 # @param Dict dictionary contains macro and value pair
151 def __InfParse__(self
, Dict
= None, IsGenFfs
=False):
153 GenFdsGlobalVariable
.VerboseLogger( " Begine parsing INf file : %s" %self
.InfFileName
)
155 self
.InfFileName
= self
.InfFileName
.replace('$(WORKSPACE)', '')
156 if len(self
.InfFileName
) > 1 and self
.InfFileName
[0] == '\\' and self
.InfFileName
[1] == '\\':
158 elif self
.InfFileName
[0] == '\\' or self
.InfFileName
[0] == '/' :
159 self
.InfFileName
= self
.InfFileName
[1:]
161 if self
.InfFileName
.find('$') == -1:
162 InfPath
= NormPath(self
.InfFileName
)
163 if not os
.path
.exists(InfPath
):
164 InfPath
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(InfPath
)
165 if not os
.path
.exists(InfPath
):
166 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Non-existant Module %s !" % (self
.InfFileName
))
168 self
.CurrentArch
= self
.GetCurrentArch()
170 # Get the InfClass object
173 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
174 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
176 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
179 # Cache lower case version of INF path before processing FILE_GUID override
181 InfLowerPath
= str(PathClassObj
).lower()
182 if self
.OverrideGuid
:
183 PathClassObj
= ProcessDuplicatedInf(PathClassObj
, self
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
)
184 if self
.CurrentArch
is not None:
186 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
188 # Set Ffs BaseName, ModuleGuid, ModuleType, Version, OutputPath
190 self
.BaseName
= Inf
.BaseName
191 self
.ModuleGuid
= Inf
.Guid
192 self
.ModuleType
= Inf
.ModuleType
193 if Inf
.Specification
is not None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
194 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
195 if Inf
.AutoGenVersion
< 0x00010005:
196 self
.ModuleType
= Inf
.ComponentType
197 self
.VersionString
= Inf
.Version
198 self
.BinFileList
= Inf
.Binaries
199 self
.SourceFileList
= Inf
.Sources
200 if self
.KeepReloc
is None and Inf
.Shadow
:
201 self
.ShadowFromInfFile
= Inf
.Shadow
204 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, TAB_COMMON
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
205 self
.BaseName
= Inf
.BaseName
206 self
.ModuleGuid
= Inf
.Guid
207 self
.ModuleType
= Inf
.ModuleType
208 if Inf
.Specification
is not None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
209 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
210 self
.VersionString
= Inf
.Version
211 self
.BinFileList
= Inf
.Binaries
212 self
.SourceFileList
= Inf
.Sources
213 if self
.BinFileList
== []:
214 EdkLogger
.error("GenFds", GENFDS_ERROR
,
215 "INF %s specified in FDF could not be found in build ARCH %s!" \
216 % (self
.InfFileName
, GenFdsGlobalVariable
.ArchList
))
218 if self
.OverrideGuid
:
219 self
.ModuleGuid
= self
.OverrideGuid
221 if len(self
.SourceFileList
) != 0 and not self
.InDsc
:
222 EdkLogger
.warn("GenFds", GENFDS_ERROR
, "Module %s NOT found in DSC file; Is it really a binary module?" % (self
.InfFileName
))
224 if self
.ModuleType
== SUP_MODULE_SMM_CORE
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
225 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
)
227 if self
.ModuleType
== SUP_MODULE_MM_CORE_STANDALONE
and int(self
.PiSpecVersion
, 16) < 0x00010032:
228 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
)
230 if Inf
._Defs
is not None and len(Inf
._Defs
) > 0:
231 self
.OptRomDefs
.update(Inf
._Defs
)
235 Platform
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
236 FdfPcdDict
= GenFdsGlobalVariable
.FdfParser
.Profile
.PcdDict
237 PlatformPcds
= Platform
.Pcds
239 # Workaround here: both build and GenFds tool convert the workspace path to lower case
240 # But INF file path in FDF and DSC file may have real case characters.
241 # Try to convert the path to lower case to see if PCDs value are override by DSC.
243 for DscModule
in Platform
.Modules
:
244 DscModules
[str(DscModule
).lower()] = Platform
.Modules
[DscModule
]
245 for PcdKey
in InfPcds
:
246 Pcd
= InfPcds
[PcdKey
]
247 if not hasattr(Pcd
, 'Offset'):
249 if Pcd
.Type
!= TAB_PCDS_PATCHABLE_IN_MODULE
:
251 # Override Patchable PCD value by the value from DSC
253 if InfLowerPath
in DscModules
and PcdKey
in DscModules
[InfLowerPath
].Pcds
:
254 PatchPcd
= DscModules
[InfLowerPath
].Pcds
[PcdKey
]
255 elif PcdKey
in Platform
.Pcds
:
256 PatchPcd
= Platform
.Pcds
[PcdKey
]
258 if PatchPcd
and Pcd
.Type
== PatchPcd
.Type
:
259 DefaultValue
= PatchPcd
.DefaultValue
262 # Override Patchable PCD value by the value from FDF
264 if PcdKey
in FdfPcdDict
:
265 DefaultValue
= FdfPcdDict
[PcdKey
]
268 # Override Patchable PCD value by the value from Build Option
269 BuildOptionOverride
= False
270 if GlobalData
.BuildOptionPcd
:
271 for pcd
in GlobalData
.BuildOptionPcd
:
272 if PcdKey
== (pcd
[1], pcd
[0]):
275 DefaultValue
= pcd
[3]
276 BuildOptionOverride
= True
279 if not DscOverride
and not FdfOverride
and not BuildOptionOverride
:
282 # Support Flexible PCD format
285 DefaultValue
= ValueExpressionEx(DefaultValue
, Pcd
.DatumType
, Platform
._GuidDict
)(True)
286 except BadExpression
:
287 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'PCD [%s.%s] Value "%s"' %(Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, DefaultValue
), File
=self
.InfFileName
)
289 if Pcd
.InfDefaultValue
:
291 Pcd
.InfDefaultValue
= ValueExpressionEx(Pcd
.InfDefaultValue
, Pcd
.DatumType
, Platform
._GuidDict
)(True)
292 except BadExpression
:
293 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'PCD [%s.%s] Value "%s"' %(Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Pcd
.DefaultValue
), File
=self
.InfFileName
)
295 # Check value, if value are equal, no need to patch
296 if Pcd
.DatumType
== TAB_VOID
:
297 if Pcd
.InfDefaultValue
== DefaultValue
or not DefaultValue
:
299 # Get the string size from FDF or DSC
300 if DefaultValue
[0] == 'L':
301 # Remove L"", but the '\0' must be appended
302 MaxDatumSize
= str((len(DefaultValue
) - 2) * 2)
303 elif DefaultValue
[0] == '{':
304 MaxDatumSize
= str(len(DefaultValue
.split(',')))
306 MaxDatumSize
= str(len(DefaultValue
) - 1)
308 Pcd
.MaxDatumSize
= PatchPcd
.MaxDatumSize
309 # If no defined the maximum size in DSC, try to get current size from INF
310 if not Pcd
.MaxDatumSize
:
311 Pcd
.MaxDatumSize
= str(len(Pcd
.InfDefaultValue
.split(',')))
314 if Pcd
.InfDefaultValue
.upper().startswith('0X'):
316 if DefaultValue
.upper().startswith('0X'):
319 PcdValueInImg
= int(Pcd
.InfDefaultValue
, Base1
)
320 PcdValueInDscOrFdf
= int(DefaultValue
, Base2
)
321 if PcdValueInImg
== PcdValueInDscOrFdf
:
325 # Check the Pcd size and data type
326 if Pcd
.DatumType
== TAB_VOID
:
327 if int(MaxDatumSize
) > int(Pcd
.MaxDatumSize
):
328 EdkLogger
.error("GenFds", GENFDS_ERROR
, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \
329 % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, int(MaxDatumSize
) - int(Pcd
.MaxDatumSize
)))
331 if PcdValueInDscOrFdf
> MAX_VAL_TYPE
[Pcd
.DatumType
] \
332 or PcdValueInImg
> MAX_VAL_TYPE
[Pcd
.DatumType
]:
333 EdkLogger
.error("GenFds", GENFDS_ERROR
, "The size of %s type PCD '%s.%s' doesn't match its data type." \
334 % (Pcd
.DatumType
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
335 self
.PatchPcds
.append((Pcd
, DefaultValue
))
338 self
.PcdIsDriver
= Inf
.PcdIsDriver
339 self
.IsBinaryModule
= Inf
.IsBinaryModule
340 if len(Inf
.Depex
.data
) > 0 and len(Inf
.DepexExpression
.data
) > 0:
343 GenFdsGlobalVariable
.VerboseLogger("BaseName : %s" % self
.BaseName
)
344 GenFdsGlobalVariable
.VerboseLogger("ModuleGuid : %s" % self
.ModuleGuid
)
345 GenFdsGlobalVariable
.VerboseLogger("ModuleType : %s" % self
.ModuleType
)
346 GenFdsGlobalVariable
.VerboseLogger("VersionString : %s" % self
.VersionString
)
347 GenFdsGlobalVariable
.VerboseLogger("InfFileName :%s" % self
.InfFileName
)
350 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${ModuleName}\
353 Rule
= self
.__GetRule
__()
354 if GlobalData
.gGuidPatternEnd
.match(Rule
.NameGuid
):
355 self
.ModuleGuid
= Rule
.NameGuid
356 self
.OutputPath
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, \
357 self
.ModuleGuid
+ self
.BaseName
)
358 if not os
.path
.exists(self
.OutputPath
) :
359 os
.makedirs(self
.OutputPath
)
361 self
.EfiOutputPath
, self
.EfiDebugPath
= self
.__GetEFIOutPutPath
__()
362 GenFdsGlobalVariable
.VerboseLogger( "ModuelEFIPath: " + self
.EfiOutputPath
)
366 # Patch EFI file with patch PCD
368 # @param EfiFile: EFI file needs to be patched.
369 # @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name
370 # If passed in file does not end with efi, return as is
372 def PatchEfiFile(self
, EfiFile
, FileType
):
374 # If the module does not have any patches, then return path to input file
376 if not self
.PatchPcds
:
380 # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED
382 if FileType
!= BINARY_FILE_TYPE_PE32
and self
.ModuleType
!= SUP_MODULE_USER_DEFINED
and self
.ModuleType
!= SUP_MODULE_HOST_APPLICATION
:
386 # Generate path to patched output file
388 Basename
= os
.path
.basename(EfiFile
)
389 Output
= os
.path
.normpath (os
.path
.join(self
.OutputPath
, Basename
))
392 # If this file has already been patched, then return the path to the patched file
394 if self
.PatchedBinFile
== Output
:
398 # If a different file from the same module has already been patched, then generate an error
400 if self
.PatchedBinFile
:
401 EdkLogger
.error("GenFds", GENFDS_ERROR
,
402 'Only one binary file can be patched:\n'
403 ' a binary file has been patched: %s\n'
404 ' current file: %s' % (self
.PatchedBinFile
, EfiFile
),
405 File
=self
.InfFileName
)
408 # Copy unpatched file contents to output file location to perform patching
410 CopyLongFilePath(EfiFile
, Output
)
413 # Apply patches to patched output file
415 for Pcd
, Value
in self
.PatchPcds
:
416 RetVal
, RetStr
= PatchBinaryFile(Output
, int(Pcd
.Offset
, 0), Pcd
.DatumType
, Value
, Pcd
.MaxDatumSize
)
418 EdkLogger
.error("GenFds", GENFDS_ERROR
, RetStr
, File
=self
.InfFileName
)
421 # Save the path of the patched output file
423 self
.PatchedBinFile
= Output
426 # Return path to patched output file
434 # @param self The object pointer
435 # @param Dict dictionary contains macro and value pair
436 # @param FvChildAddr Array of the inside FvImage base address
437 # @param FvParentAddr Parent Fv base address
438 # @retval string Generated FFS file name
440 def GenFfs(self
, Dict
= None, FvChildAddr
= [], FvParentAddr
=None, IsMakefile
=False, FvName
=None):
442 # Parse Inf file get Module related information
446 self
.__InfParse
__(Dict
, IsGenFfs
=True)
447 Arch
= self
.GetCurrentArch()
448 SrcFile
= mws
.join( GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
);
449 DestFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
452 SrcPath
= os
.path
.dirname(SrcFile
)
453 SrcFileName
= os
.path
.basename(SrcFile
)
454 SrcFileBase
, SrcFileExt
= os
.path
.splitext(SrcFileName
)
455 DestPath
= os
.path
.dirname(DestFile
)
456 DestFileName
= os
.path
.basename(DestFile
)
457 DestFileBase
, DestFileExt
= os
.path
.splitext(DestFileName
)
461 "${s_path}" : SrcPath
,
462 "${s_dir}" : SrcFileDir
,
463 "${s_name}" : SrcFileName
,
464 "${s_base}" : SrcFileBase
,
465 "${s_ext}" : SrcFileExt
,
468 "${d_path}" : DestPath
,
469 "${d_name}" : DestFileName
,
470 "${d_base}" : DestFileBase
,
471 "${d_ext}" : DestFileExt
474 # Allow binary type module not specify override rule in FDF file.
476 if len(self
.BinFileList
) > 0:
477 if self
.Rule
is None or self
.Rule
== "":
480 if not IsMakefile
and GenFdsGlobalVariable
.EnableGenfdsMultiThread
and self
.Rule
!= 'BINARY':
483 # Get the rule of how to generate Ffs file
485 Rule
= self
.__GetRule
__()
486 GenFdsGlobalVariable
.VerboseLogger( "Packing binaries from inf file : %s" %self
.InfFileName
)
488 # Convert Fv File Type for PI1.1 SMM driver.
490 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
491 if Rule
.FvFileType
== 'DRIVER':
492 Rule
.FvFileType
= 'SMM'
494 # Framework SMM Driver has no SMM FV file type
496 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
497 if Rule
.FvFileType
== 'SMM' or Rule
.FvFileType
== SUP_MODULE_SMM_CORE
:
498 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File
=self
.InfFileName
)
500 # For the rule only has simpleFile
503 if self
.IsBinaryModule
:
506 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
507 if self
.OverrideGuid
:
508 PathClassObj
= ProcessDuplicatedInf(PathClassObj
, self
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
)
509 MakefilePath
= PathClassObj
.Path
, Arch
510 if isinstance (Rule
, RuleSimpleFile
.RuleSimpleFile
):
511 SectionOutputList
= self
.__GenSimpleFileSection
__(Rule
, IsMakefile
=IsMakefile
)
512 FfsOutput
= self
.__GenSimpleFileFfs
__(Rule
, SectionOutputList
, MakefilePath
=MakefilePath
)
515 # For Rule has ComplexFile
517 elif isinstance(Rule
, RuleComplexFile
.RuleComplexFile
):
518 InputSectList
, InputSectAlignments
= self
.__GenComplexFileSection
__(Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
=IsMakefile
)
519 FfsOutput
= self
.__GenComplexFileFfs
__(Rule
, InputSectList
, InputSectAlignments
, MakefilePath
=MakefilePath
)
522 ## __ExtendMacro__() method
524 # Replace macro with its value
526 # @param self The object pointer
527 # @param String The string to be replaced
528 # @retval string Macro replaced string
530 def __ExtendMacro__ (self
, String
):
532 '$(INF_OUTPUT)' : self
.EfiOutputPath
,
533 '$(MODULE_NAME)' : self
.BaseName
,
534 '$(BUILD_NUMBER)': self
.BuildNum
,
535 '$(INF_VERSION)' : self
.VersionString
,
536 '$(NAMED_GUID)' : self
.ModuleGuid
538 String
= GenFdsGlobalVariable
.MacroExtend(String
, MacroDict
)
539 String
= GenFdsGlobalVariable
.MacroExtend(String
, self
.MacroDict
)
542 ## __GetRule__() method
544 # Get correct rule for generating FFS for this INF
546 # @param self The object pointer
547 # @retval Rule Rule object
549 def __GetRule__ (self
) :
551 if self
.CurrentArch
is None:
552 CurrentArchList
= ['common']
554 CurrentArchList
.append(self
.CurrentArch
)
556 for CurrentArch
in CurrentArchList
:
557 RuleName
= 'RULE' + \
559 CurrentArch
.upper() + \
561 self
.ModuleType
.upper()
562 if self
.Rule
is not None:
563 RuleName
= RuleName
+ \
567 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
569 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
572 RuleName
= 'RULE' + \
576 self
.ModuleType
.upper()
578 if self
.Rule
is not None:
579 RuleName
= RuleName
+ \
583 GenFdsGlobalVariable
.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName
, self
.InfFileName
))
585 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
587 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
591 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'Don\'t Find common rule %s for INF %s' \
592 % (RuleName
, self
.InfFileName
))
594 ## __GetPlatformArchList__() method
596 # Get Arch list this INF built under
598 # @param self The object pointer
599 # @retval list Arch list
601 def __GetPlatformArchList__(self
):
603 InfFileKey
= os
.path
.normpath(mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
))
605 for Arch
in GenFdsGlobalVariable
.ArchList
:
606 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
607 if PlatformDataBase
is not None:
608 if InfFileKey
in PlatformDataBase
.Modules
:
609 DscArchList
.append (Arch
)
612 # BaseTools support build same module more than once, the module path with FILE_GUID overridden has
613 # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key,
614 # but the path (self.MetaFile.Path) is the real path
616 for key
in PlatformDataBase
.Modules
:
617 if InfFileKey
== str((PlatformDataBase
.Modules
[key
]).MetaFile
.Path
):
618 DscArchList
.append (Arch
)
623 ## GetCurrentArch() method
625 # Get Arch list of the module from this INF is to be placed into flash
627 # @param self The object pointer
628 # @retval list Arch list
630 def GetCurrentArch(self
) :
632 TargetArchList
= GenFdsGlobalVariable
.ArchList
634 PlatformArchList
= self
.__GetPlatformArchList
__()
636 CurArchList
= TargetArchList
637 if PlatformArchList
!= []:
638 CurArchList
= list(set (TargetArchList
) & set (PlatformArchList
))
639 GenFdsGlobalVariable
.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList
))
642 if self
.KeyStringList
!= []:
643 for Key
in self
.KeyStringList
:
644 Key
= GenFdsGlobalVariable
.MacroExtend(Key
)
645 Target
, Tag
, Arch
= Key
.split('_')
646 if Arch
in CurArchList
:
647 ArchList
.append(Arch
)
648 if Target
not in self
.TargetOverrideList
:
649 self
.TargetOverrideList
.append(Target
)
651 ArchList
= CurArchList
653 UseArchList
= TargetArchList
654 if self
.UseArch
is not None:
656 UseArchList
.append(self
.UseArch
)
657 ArchList
= list(set (UseArchList
) & set (ArchList
))
659 self
.InfFileName
= NormPath(self
.InfFileName
)
660 if len(PlatformArchList
) == 0:
662 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
663 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
665 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
666 if len(ArchList
) == 1:
669 elif len(ArchList
) > 1:
670 if len(PlatformArchList
) == 0:
671 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
))
673 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
))
675 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." \
676 % (self
.InfFileName
, str(PlatformArchList
), GenFdsGlobalVariable
.ActivePlatform
, str(set (UseArchList
) & set (TargetArchList
))))
678 ## __GetEFIOutPutPath__() method
680 # Get the output path for generated files
682 # @param self The object pointer
683 # @retval string Path that output files from this INF go to
685 def __GetEFIOutPutPath__(self
):
689 (ModulePath
, FileName
) = os
.path
.split(self
.InfFileName
)
690 Index
= FileName
.rfind('.')
691 FileName
= FileName
[0:Index
]
692 if self
.OverrideGuid
:
693 FileName
= self
.OverrideGuid
695 if self
.CurrentArch
is not None:
696 Arch
= self
.CurrentArch
698 OutputPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
704 DebugPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
710 OutputPath
= os
.path
.realpath(OutputPath
)
711 DebugPath
= os
.path
.realpath(DebugPath
)
712 return OutputPath
, DebugPath
714 ## __GenSimpleFileSection__() method
716 # Generate section by specified file name or a list of files with file extension
718 # @param self The object pointer
719 # @param Rule The rule object used to generate section
720 # @retval string File name of the generated section file
722 def __GenSimpleFileSection__(self
, Rule
, IsMakefile
= False):
724 # Prepare the parameter of GenSection
728 GenSecInputFile
= None
729 if Rule
.FileName
is not None:
730 GenSecInputFile
= self
.__ExtendMacro
__(Rule
.FileName
)
731 if os
.path
.isabs(GenSecInputFile
):
732 GenSecInputFile
= os
.path
.normpath(GenSecInputFile
)
734 GenSecInputFile
= os
.path
.normpath(os
.path
.join(self
.EfiOutputPath
, GenSecInputFile
))
736 FileList
, IsSect
= Section
.Section
.GetFileList(self
, '', Rule
.FileExtension
)
739 SectionType
= Rule
.SectionType
741 # Convert Fv Section Type for PI1.1 SMM driver.
743 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
744 if SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
:
745 SectionType
= BINARY_FILE_TYPE_SMM_DEPEX
747 # Framework SMM Driver has no SMM_DEPEX section type
749 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
750 if SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
751 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
753 if self
.ModuleType
in (SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
):
754 if self
.KeepReloc
is not None:
755 NoStrip
= self
.KeepReloc
756 elif Rule
.KeepReloc
is not None:
757 NoStrip
= Rule
.KeepReloc
758 elif self
.ShadowFromInfFile
is not None:
759 NoStrip
= self
.ShadowFromInfFile
762 for File
in FileList
:
765 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
766 SectionSuffix
[SectionType
] + SUP_MODULE_SEC
+ SecNum
768 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
769 File
= GenFdsGlobalVariable
.MacroExtend(File
, Dict
, self
.CurrentArch
)
771 #Get PE Section alignment when align is set to AUTO
772 if self
.Alignment
== 'Auto' and (SectionType
== BINARY_FILE_TYPE_PE32
or SectionType
== BINARY_FILE_TYPE_TE
):
773 ImageObj
= PeImageClass (File
)
774 if ImageObj
.SectionAlignment
< 0x400:
775 self
.Alignment
= str (ImageObj
.SectionAlignment
)
776 elif ImageObj
.SectionAlignment
< 0x100000:
777 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x400) + 'K'
779 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x100000) + 'M'
782 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
783 if not os
.path
.exists(FileBeforeStrip
) or \
784 (os
.path
.getmtime(File
) > os
.path
.getmtime(FileBeforeStrip
)):
785 CopyLongFilePath(File
, FileBeforeStrip
)
786 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
787 GenFdsGlobalVariable
.GenerateFirmwareImage(
791 IsMakefile
=IsMakefile
795 if SectionType
== BINARY_FILE_TYPE_TE
:
796 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
797 GenFdsGlobalVariable
.GenerateFirmwareImage(
801 IsMakefile
=IsMakefile
804 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [File
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
805 OutputFileList
.append(OutputFile
)
808 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
809 SectionSuffix
[SectionType
] + SUP_MODULE_SEC
+ SecNum
810 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
811 GenSecInputFile
= GenFdsGlobalVariable
.MacroExtend(GenSecInputFile
, Dict
, self
.CurrentArch
)
813 #Get PE Section alignment when align is set to AUTO
814 if self
.Alignment
== 'Auto' and (SectionType
== BINARY_FILE_TYPE_PE32
or SectionType
== BINARY_FILE_TYPE_TE
):
815 ImageObj
= PeImageClass (GenSecInputFile
)
816 if ImageObj
.SectionAlignment
< 0x400:
817 self
.Alignment
= str (ImageObj
.SectionAlignment
)
818 elif ImageObj
.SectionAlignment
< 0x100000:
819 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x400) + 'K'
821 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x100000) + 'M'
824 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
825 if not os
.path
.exists(FileBeforeStrip
) or \
826 (os
.path
.getmtime(GenSecInputFile
) > os
.path
.getmtime(FileBeforeStrip
)):
827 CopyLongFilePath(GenSecInputFile
, FileBeforeStrip
)
829 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
830 GenFdsGlobalVariable
.GenerateFirmwareImage(
834 IsMakefile
=IsMakefile
836 GenSecInputFile
= StrippedFile
838 if SectionType
== BINARY_FILE_TYPE_TE
:
839 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
840 GenFdsGlobalVariable
.GenerateFirmwareImage(
844 IsMakefile
=IsMakefile
846 GenSecInputFile
= TeFile
847 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [GenSecInputFile
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
848 OutputFileList
.append(OutputFile
)
850 return OutputFileList
852 ## __GenSimpleFileFfs__() method
856 # @param self The object pointer
857 # @param Rule The rule object used to generate section
858 # @param InputFileList The output file list from GenSection
859 # @retval string Generated FFS file name
861 def __GenSimpleFileFfs__(self
, Rule
, InputFileList
, MakefilePath
= None):
862 FfsOutput
= self
.OutputPath
+ \
864 self
.__ExtendMacro
__(Rule
.NameGuid
) + \
867 GenFdsGlobalVariable
.VerboseLogger(self
.__ExtendMacro
__(Rule
.NameGuid
))
869 SectionAlignments
= []
870 for InputFile
in InputFileList
:
871 InputSection
.append(InputFile
)
872 SectionAlignments
.append(Rule
.SectAlignment
)
874 if Rule
.NameGuid
is not None and Rule
.NameGuid
.startswith('PCD('):
875 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
876 if len(PcdValue
) == 0:
877 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
879 if PcdValue
.startswith('{'):
880 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
881 RegistryGuidStr
= PcdValue
882 if len(RegistryGuidStr
) == 0:
883 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
885 self
.ModuleGuid
= RegistryGuidStr
887 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputSection
,
888 FdfFvFileTypeToFileType
[Rule
.FvFileType
],
889 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
890 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
891 SectionAlign
=SectionAlignments
,
892 MakefilePath
=MakefilePath
896 ## __GenComplexFileSection__() method
898 # Generate section by sections in Rule
900 # @param self The object pointer
901 # @param Rule The rule object used to generate section
902 # @param FvChildAddr Array of the inside FvImage base address
903 # @param FvParentAddr Parent Fv base address
904 # @retval string File name of the generated section file
906 def __GenComplexFileSection__(self
, Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
= False):
907 if self
.ModuleType
in (SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
, SUP_MODULE_MM_CORE_STANDALONE
):
908 if Rule
.KeepReloc
is not None:
909 self
.KeepRelocFromRule
= Rule
.KeepReloc
913 HasGeneratedFlag
= False
914 if self
.PcdIsDriver
== 'PEI_PCD_DRIVER':
915 if self
.IsBinaryModule
:
916 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "PEIPcdDataBase.raw")
918 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "PEIPcdDataBase.raw")
919 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "PEIPcdDataBaseSec.raw")
920 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
923 IsMakefile
= IsMakefile
925 SectFiles
.append(PcdExDbSecName
)
926 SectAlignments
.append(None)
927 elif self
.PcdIsDriver
== 'DXE_PCD_DRIVER':
928 if self
.IsBinaryModule
:
929 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "DXEPcdDataBase.raw")
931 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "DXEPcdDataBase.raw")
932 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "DXEPcdDataBaseSec.raw")
933 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
936 IsMakefile
= IsMakefile
938 SectFiles
.append(PcdExDbSecName
)
939 SectAlignments
.append(None)
940 for Sect
in Rule
.SectionList
:
941 SecIndex
= '%d' %Index
944 # Convert Fv Section Type for PI1.1 SMM driver.
946 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
947 if Sect
.SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
:
948 Sect
.SectionType
= BINARY_FILE_TYPE_SMM_DEPEX
950 # Framework SMM Driver has no SMM_DEPEX section type
952 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
953 if Sect
.SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
954 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
956 # process the inside FvImage from FvSection or GuidSection
958 if FvChildAddr
!= []:
959 if isinstance(Sect
, FvImageSection
):
960 Sect
.FvAddr
= FvChildAddr
.pop(0)
961 elif isinstance(Sect
, GuidSection
):
962 Sect
.FvAddr
= FvChildAddr
963 if FvParentAddr
is not None and isinstance(Sect
, GuidSection
):
964 Sect
.FvParentAddr
= FvParentAddr
966 if Rule
.KeyStringList
!= []:
967 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, Rule
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
969 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, self
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
971 if not HasGeneratedFlag
:
972 UniVfrOffsetFileSection
= ""
973 ModuleFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
)
974 InfData
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClass(ModuleFileName
), self
.CurrentArch
]
976 # Search the source list in InfData to find if there are .vfr file exist.
979 VfrUniOffsetList
= []
980 for SourceFile
in InfData
.Sources
:
981 if SourceFile
.Type
.upper() == ".VFR" :
983 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
985 VfrUniBaseName
[SourceFile
.BaseName
] = (SourceFile
.BaseName
+ "Bin")
986 if SourceFile
.Type
.upper() == ".UNI" :
988 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
990 VfrUniBaseName
["UniOffsetName"] = (self
.BaseName
+ "Strings")
993 if len(VfrUniBaseName
) > 0:
995 if InfData
.BuildType
!= 'UEFI_HII':
996 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
997 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
998 UniVfrOffsetFileNameList
= []
999 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
1000 TrimCmd
= "Trim --Vfr-Uni-Offset -o %s --ModuleName=%s --DebugDir=%s " % (UniVfrOffsetFileName
, self
.BaseName
, self
.EfiDebugPath
)
1001 GenFdsGlobalVariable
.SecCmdList
.append(TrimCmd
)
1002 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
1003 [UniVfrOffsetFileName
],
1008 VfrUniOffsetList
= self
.__GetBuildOutputMapFileVfrUniInfo
(VfrUniBaseName
)
1010 # Generate the Raw data of raw section
1012 if VfrUniOffsetList
:
1013 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
1014 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
1015 FfsInfStatement
.__GenUniVfrOffsetFile
(VfrUniOffsetList
, UniVfrOffsetFileName
)
1016 UniVfrOffsetFileNameList
= []
1017 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
1018 """Call GenSection"""
1020 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
1021 UniVfrOffsetFileNameList
,
1024 #os.remove(UniVfrOffsetFileName)
1025 if UniVfrOffsetFileSection
:
1026 SectList
.append(UniVfrOffsetFileSection
)
1027 HasGeneratedFlag
= True
1029 for SecName
in SectList
:
1030 SectFiles
.append(SecName
)
1031 SectAlignments
.append(Align
)
1033 return SectFiles
, SectAlignments
1035 ## __GenComplexFileFfs__() method
1039 # @param self The object pointer
1040 # @param Rule The rule object used to generate section
1041 # @param InputFileList The output file list from GenSection
1042 # @retval string Generated FFS file name
1044 def __GenComplexFileFfs__(self
, Rule
, InputFile
, Alignments
, MakefilePath
= None):
1046 if Rule
.NameGuid
is not None and Rule
.NameGuid
.startswith('PCD('):
1047 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
1048 if len(PcdValue
) == 0:
1049 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
1051 if PcdValue
.startswith('{'):
1052 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
1053 RegistryGuidStr
= PcdValue
1054 if len(RegistryGuidStr
) == 0:
1055 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
1057 self
.ModuleGuid
= RegistryGuidStr
1059 FfsOutput
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
1060 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputFile
,
1061 FdfFvFileTypeToFileType
[Rule
.FvFileType
],
1062 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
1063 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
1064 SectionAlign
=Alignments
,
1065 MakefilePath
=MakefilePath
1069 ## __GetBuildOutputMapFileVfrUniInfo() method
1071 # Find the offset of UNI/INF object offset in the EFI image file.
1073 # @param self The object pointer
1074 # @param VfrUniBaseName A name list contain the UNI/INF object name.
1075 # @retval RetValue A list contain offset of UNI/INF object.
1077 def __GetBuildOutputMapFileVfrUniInfo(self
, VfrUniBaseName
):
1078 MapFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".map")
1079 EfiFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".efi")
1080 return GetVariableOffset(MapFileName
, EfiFileName
, list(VfrUniBaseName
.values()))
1082 ## __GenUniVfrOffsetFile() method
1084 # Generate the offset file for the module which contain VFR or UNI file.
1086 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
1087 # @param UniVfrOffsetFileName The output offset file name.
1090 def __GenUniVfrOffsetFile(VfrUniOffsetList
, UniVfrOffsetFileName
):
1092 # Use a instance of StringIO to cache data
1093 fStringIO
= BytesIO()
1095 for Item
in VfrUniOffsetList
:
1096 if (Item
[0].find("Strings") != -1):
1098 # UNI offset in image.
1100 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
1102 UniGuid
= b
'\xe0\xc5\x13\x89\xf63\x86M\x9b\xf1C\xef\x89\xfc\x06f'
1103 fStringIO
.write(UniGuid
)
1104 UniValue
= pack ('Q', int (Item
[1], 16))
1105 fStringIO
.write (UniValue
)
1108 # VFR binary offset in image.
1110 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
1112 VfrGuid
= b
'\xb4|\xbc\xd0Gj_I\xaa\x11q\x07F\xda\x06\xa2'
1113 fStringIO
.write(VfrGuid
)
1115 VfrValue
= pack ('Q', int (Item
[1], 16))
1116 fStringIO
.write (VfrValue
)
1119 # write data into file.
1122 SaveFileOnChange(UniVfrOffsetFileName
, fStringIO
.getvalue())
1124 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)