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
= {}, FvChildAddr
= [], FvParentAddr
=None, IsMakefile
=False, FvName
=None):
442 # Parse Inf file get Module related information
445 self
.__InfParse
__(Dict
, IsGenFfs
=True)
446 Arch
= self
.GetCurrentArch()
447 SrcFile
= mws
.join( GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
);
448 DestFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
451 SrcPath
= os
.path
.dirname(SrcFile
)
452 SrcFileName
= os
.path
.basename(SrcFile
)
453 SrcFileBase
, SrcFileExt
= os
.path
.splitext(SrcFileName
)
454 DestPath
= os
.path
.dirname(DestFile
)
455 DestFileName
= os
.path
.basename(DestFile
)
456 DestFileBase
, DestFileExt
= os
.path
.splitext(DestFileName
)
460 "${s_path}" : SrcPath
,
461 "${s_dir}" : SrcFileDir
,
462 "${s_name}" : SrcFileName
,
463 "${s_base}" : SrcFileBase
,
464 "${s_ext}" : SrcFileExt
,
467 "${d_path}" : DestPath
,
468 "${d_name}" : DestFileName
,
469 "${d_base}" : DestFileBase
,
470 "${d_ext}" : DestFileExt
473 # Allow binary type module not specify override rule in FDF file.
475 if len(self
.BinFileList
) > 0:
476 if self
.Rule
is None or self
.Rule
== "":
479 if not IsMakefile
and GenFdsGlobalVariable
.EnableGenfdsMultiThread
and self
.Rule
!= 'BINARY':
482 # Get the rule of how to generate Ffs file
484 Rule
= self
.__GetRule
__()
485 GenFdsGlobalVariable
.VerboseLogger( "Packing binaries from inf file : %s" %self
.InfFileName
)
487 # Convert Fv File Type for PI1.1 SMM driver.
489 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
490 if Rule
.FvFileType
== 'DRIVER':
491 Rule
.FvFileType
= 'SMM'
493 # Framework SMM Driver has no SMM FV file type
495 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
496 if Rule
.FvFileType
== 'SMM' or Rule
.FvFileType
== SUP_MODULE_SMM_CORE
:
497 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File
=self
.InfFileName
)
499 # For the rule only has simpleFile
502 if self
.IsBinaryModule
:
505 MakefilePath
= self
.InfFileName
, Arch
506 if isinstance (Rule
, RuleSimpleFile
.RuleSimpleFile
):
507 SectionOutputList
= self
.__GenSimpleFileSection
__(Rule
, IsMakefile
=IsMakefile
)
508 FfsOutput
= self
.__GenSimpleFileFfs
__(Rule
, SectionOutputList
, MakefilePath
=MakefilePath
)
511 # For Rule has ComplexFile
513 elif isinstance(Rule
, RuleComplexFile
.RuleComplexFile
):
514 InputSectList
, InputSectAlignments
= self
.__GenComplexFileSection
__(Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
=IsMakefile
)
515 FfsOutput
= self
.__GenComplexFileFfs
__(Rule
, InputSectList
, InputSectAlignments
, MakefilePath
=MakefilePath
)
518 ## __ExtendMacro__() method
520 # Replace macro with its value
522 # @param self The object pointer
523 # @param String The string to be replaced
524 # @retval string Macro replaced string
526 def __ExtendMacro__ (self
, String
):
528 '$(INF_OUTPUT)' : self
.EfiOutputPath
,
529 '$(MODULE_NAME)' : self
.BaseName
,
530 '$(BUILD_NUMBER)': self
.BuildNum
,
531 '$(INF_VERSION)' : self
.VersionString
,
532 '$(NAMED_GUID)' : self
.ModuleGuid
534 String
= GenFdsGlobalVariable
.MacroExtend(String
, MacroDict
)
535 String
= GenFdsGlobalVariable
.MacroExtend(String
, self
.MacroDict
)
538 ## __GetRule__() method
540 # Get correct rule for generating FFS for this INF
542 # @param self The object pointer
543 # @retval Rule Rule object
545 def __GetRule__ (self
) :
547 if self
.CurrentArch
is None:
548 CurrentArchList
= ['common']
550 CurrentArchList
.append(self
.CurrentArch
)
552 for CurrentArch
in CurrentArchList
:
553 RuleName
= 'RULE' + \
555 CurrentArch
.upper() + \
557 self
.ModuleType
.upper()
558 if self
.Rule
is not None:
559 RuleName
= RuleName
+ \
563 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
565 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
568 RuleName
= 'RULE' + \
572 self
.ModuleType
.upper()
574 if self
.Rule
is not None:
575 RuleName
= RuleName
+ \
579 GenFdsGlobalVariable
.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName
, self
.InfFileName
))
581 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
583 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
587 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'Don\'t Find common rule %s for INF %s' \
588 % (RuleName
, self
.InfFileName
))
590 ## __GetPlatformArchList__() method
592 # Get Arch list this INF built under
594 # @param self The object pointer
595 # @retval list Arch list
597 def __GetPlatformArchList__(self
):
599 InfFileKey
= os
.path
.normpath(mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
))
601 for Arch
in GenFdsGlobalVariable
.ArchList
:
602 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
603 if PlatformDataBase
is not None:
604 if InfFileKey
in PlatformDataBase
.Modules
:
605 DscArchList
.append (Arch
)
608 # BaseTools support build same module more than once, the module path with FILE_GUID overridden has
609 # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key,
610 # but the path (self.MetaFile.Path) is the real path
612 for key
in PlatformDataBase
.Modules
:
613 if InfFileKey
== str((PlatformDataBase
.Modules
[key
]).MetaFile
.Path
):
614 DscArchList
.append (Arch
)
619 ## GetCurrentArch() method
621 # Get Arch list of the module from this INF is to be placed into flash
623 # @param self The object pointer
624 # @retval list Arch list
626 def GetCurrentArch(self
) :
628 TargetArchList
= GenFdsGlobalVariable
.ArchList
630 PlatformArchList
= self
.__GetPlatformArchList
__()
632 CurArchList
= TargetArchList
633 if PlatformArchList
!= []:
634 CurArchList
= list(set (TargetArchList
) & set (PlatformArchList
))
635 GenFdsGlobalVariable
.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList
))
638 if self
.KeyStringList
!= []:
639 for Key
in self
.KeyStringList
:
640 Key
= GenFdsGlobalVariable
.MacroExtend(Key
)
641 Target
, Tag
, Arch
= Key
.split('_')
642 if Arch
in CurArchList
:
643 ArchList
.append(Arch
)
644 if Target
not in self
.TargetOverrideList
:
645 self
.TargetOverrideList
.append(Target
)
647 ArchList
= CurArchList
649 UseArchList
= TargetArchList
650 if self
.UseArch
is not None:
652 UseArchList
.append(self
.UseArch
)
653 ArchList
= list(set (UseArchList
) & set (ArchList
))
655 self
.InfFileName
= NormPath(self
.InfFileName
)
656 if len(PlatformArchList
) == 0:
658 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
659 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
661 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
662 if len(ArchList
) == 1:
665 elif len(ArchList
) > 1:
666 if len(PlatformArchList
) == 0:
667 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
))
669 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
))
671 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." \
672 % (self
.InfFileName
, str(PlatformArchList
), GenFdsGlobalVariable
.ActivePlatform
, str(set (UseArchList
) & set (TargetArchList
))))
674 ## __GetEFIOutPutPath__() method
676 # Get the output path for generated files
678 # @param self The object pointer
679 # @retval string Path that output files from this INF go to
681 def __GetEFIOutPutPath__(self
):
685 (ModulePath
, FileName
) = os
.path
.split(self
.InfFileName
)
686 Index
= FileName
.rfind('.')
687 FileName
= FileName
[0:Index
]
688 if self
.OverrideGuid
:
689 FileName
= self
.OverrideGuid
691 if self
.CurrentArch
is not None:
692 Arch
= self
.CurrentArch
694 OutputPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
700 DebugPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
706 OutputPath
= os
.path
.realpath(OutputPath
)
707 DebugPath
= os
.path
.realpath(DebugPath
)
708 return OutputPath
, DebugPath
710 ## __GenSimpleFileSection__() method
712 # Generate section by specified file name or a list of files with file extension
714 # @param self The object pointer
715 # @param Rule The rule object used to generate section
716 # @retval string File name of the generated section file
718 def __GenSimpleFileSection__(self
, Rule
, IsMakefile
= False):
720 # Prepare the parameter of GenSection
724 GenSecInputFile
= None
725 if Rule
.FileName
is not None:
726 GenSecInputFile
= self
.__ExtendMacro
__(Rule
.FileName
)
727 if os
.path
.isabs(GenSecInputFile
):
728 GenSecInputFile
= os
.path
.normpath(GenSecInputFile
)
730 GenSecInputFile
= os
.path
.normpath(os
.path
.join(self
.EfiOutputPath
, GenSecInputFile
))
732 FileList
, IsSect
= Section
.Section
.GetFileList(self
, '', Rule
.FileExtension
)
735 SectionType
= Rule
.SectionType
737 # Convert Fv Section Type for PI1.1 SMM driver.
739 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
740 if SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
:
741 SectionType
= BINARY_FILE_TYPE_SMM_DEPEX
743 # Framework SMM Driver has no SMM_DEPEX section type
745 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
746 if SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
747 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
749 if self
.ModuleType
in (SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
):
750 if self
.KeepReloc
is not None:
751 NoStrip
= self
.KeepReloc
752 elif Rule
.KeepReloc
is not None:
753 NoStrip
= Rule
.KeepReloc
754 elif self
.ShadowFromInfFile
is not None:
755 NoStrip
= self
.ShadowFromInfFile
758 for File
in FileList
:
761 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
762 SectionSuffix
[SectionType
] + SUP_MODULE_SEC
+ SecNum
764 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
765 File
= GenFdsGlobalVariable
.MacroExtend(File
, Dict
, self
.CurrentArch
)
767 #Get PE Section alignment when align is set to AUTO
768 if self
.Alignment
== 'Auto' and (SectionType
== BINARY_FILE_TYPE_PE32
or SectionType
== BINARY_FILE_TYPE_TE
):
769 ImageObj
= PeImageClass (File
)
770 if ImageObj
.SectionAlignment
< 0x400:
771 self
.Alignment
= str (ImageObj
.SectionAlignment
)
772 elif ImageObj
.SectionAlignment
< 0x100000:
773 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x400) + 'K'
775 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x100000) + 'M'
778 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
779 if not os
.path
.exists(FileBeforeStrip
) or \
780 (os
.path
.getmtime(File
) > os
.path
.getmtime(FileBeforeStrip
)):
781 CopyLongFilePath(File
, FileBeforeStrip
)
782 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
783 GenFdsGlobalVariable
.GenerateFirmwareImage(
787 IsMakefile
=IsMakefile
791 if SectionType
== BINARY_FILE_TYPE_TE
:
792 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
793 GenFdsGlobalVariable
.GenerateFirmwareImage(
797 IsMakefile
=IsMakefile
800 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [File
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
801 OutputFileList
.append(OutputFile
)
804 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
805 SectionSuffix
[SectionType
] + SUP_MODULE_SEC
+ SecNum
806 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
807 GenSecInputFile
= GenFdsGlobalVariable
.MacroExtend(GenSecInputFile
, Dict
, self
.CurrentArch
)
809 #Get PE Section alignment when align is set to AUTO
810 if self
.Alignment
== 'Auto' and (SectionType
== BINARY_FILE_TYPE_PE32
or SectionType
== BINARY_FILE_TYPE_TE
):
811 ImageObj
= PeImageClass (GenSecInputFile
)
812 if ImageObj
.SectionAlignment
< 0x400:
813 self
.Alignment
= str (ImageObj
.SectionAlignment
)
814 elif ImageObj
.SectionAlignment
< 0x100000:
815 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x400) + 'K'
817 self
.Alignment
= str (ImageObj
.SectionAlignment
// 0x100000) + 'M'
820 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
821 if not os
.path
.exists(FileBeforeStrip
) or \
822 (os
.path
.getmtime(GenSecInputFile
) > os
.path
.getmtime(FileBeforeStrip
)):
823 CopyLongFilePath(GenSecInputFile
, FileBeforeStrip
)
825 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
826 GenFdsGlobalVariable
.GenerateFirmwareImage(
830 IsMakefile
=IsMakefile
832 GenSecInputFile
= StrippedFile
834 if SectionType
== BINARY_FILE_TYPE_TE
:
835 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
836 GenFdsGlobalVariable
.GenerateFirmwareImage(
840 IsMakefile
=IsMakefile
842 GenSecInputFile
= TeFile
843 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [GenSecInputFile
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
844 OutputFileList
.append(OutputFile
)
846 return OutputFileList
848 ## __GenSimpleFileFfs__() method
852 # @param self The object pointer
853 # @param Rule The rule object used to generate section
854 # @param InputFileList The output file list from GenSection
855 # @retval string Generated FFS file name
857 def __GenSimpleFileFfs__(self
, Rule
, InputFileList
, MakefilePath
= None):
858 FfsOutput
= self
.OutputPath
+ \
860 self
.__ExtendMacro
__(Rule
.NameGuid
) + \
863 GenFdsGlobalVariable
.VerboseLogger(self
.__ExtendMacro
__(Rule
.NameGuid
))
865 SectionAlignments
= []
866 for InputFile
in InputFileList
:
867 InputSection
.append(InputFile
)
868 SectionAlignments
.append(Rule
.SectAlignment
)
870 if Rule
.NameGuid
is not None and Rule
.NameGuid
.startswith('PCD('):
871 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
872 if len(PcdValue
) == 0:
873 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
875 if PcdValue
.startswith('{'):
876 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
877 RegistryGuidStr
= PcdValue
878 if len(RegistryGuidStr
) == 0:
879 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
881 self
.ModuleGuid
= RegistryGuidStr
883 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputSection
,
884 FdfFvFileTypeToFileType
[Rule
.FvFileType
],
885 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
886 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
887 SectionAlign
=SectionAlignments
,
888 MakefilePath
=MakefilePath
892 ## __GenComplexFileSection__() method
894 # Generate section by sections in Rule
896 # @param self The object pointer
897 # @param Rule The rule object used to generate section
898 # @param FvChildAddr Array of the inside FvImage base address
899 # @param FvParentAddr Parent Fv base address
900 # @retval string File name of the generated section file
902 def __GenComplexFileSection__(self
, Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
= False):
903 if self
.ModuleType
in (SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
, SUP_MODULE_MM_CORE_STANDALONE
):
904 if Rule
.KeepReloc
is not None:
905 self
.KeepRelocFromRule
= Rule
.KeepReloc
909 HasGeneratedFlag
= False
910 if self
.PcdIsDriver
== 'PEI_PCD_DRIVER':
911 if self
.IsBinaryModule
:
912 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "PEIPcdDataBase.raw")
914 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "PEIPcdDataBase.raw")
915 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "PEIPcdDataBaseSec.raw")
916 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
919 IsMakefile
= IsMakefile
921 SectFiles
.append(PcdExDbSecName
)
922 SectAlignments
.append(None)
923 elif self
.PcdIsDriver
== 'DXE_PCD_DRIVER':
924 if self
.IsBinaryModule
:
925 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "DXEPcdDataBase.raw")
927 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "DXEPcdDataBase.raw")
928 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "DXEPcdDataBaseSec.raw")
929 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
932 IsMakefile
= IsMakefile
934 SectFiles
.append(PcdExDbSecName
)
935 SectAlignments
.append(None)
936 for Sect
in Rule
.SectionList
:
937 SecIndex
= '%d' %Index
940 # Convert Fv Section Type for PI1.1 SMM driver.
942 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
943 if Sect
.SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
:
944 Sect
.SectionType
= BINARY_FILE_TYPE_SMM_DEPEX
946 # Framework SMM Driver has no SMM_DEPEX section type
948 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
949 if Sect
.SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
950 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
952 # process the inside FvImage from FvSection or GuidSection
954 if FvChildAddr
!= []:
955 if isinstance(Sect
, FvImageSection
):
956 Sect
.FvAddr
= FvChildAddr
.pop(0)
957 elif isinstance(Sect
, GuidSection
):
958 Sect
.FvAddr
= FvChildAddr
959 if FvParentAddr
is not None and isinstance(Sect
, GuidSection
):
960 Sect
.FvParentAddr
= FvParentAddr
962 if Rule
.KeyStringList
!= []:
963 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, Rule
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
965 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, self
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
967 if not HasGeneratedFlag
:
968 UniVfrOffsetFileSection
= ""
969 ModuleFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
)
970 InfData
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClass(ModuleFileName
), self
.CurrentArch
]
972 # Search the source list in InfData to find if there are .vfr file exist.
975 VfrUniOffsetList
= []
976 for SourceFile
in InfData
.Sources
:
977 if SourceFile
.Type
.upper() == ".VFR" :
979 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
981 VfrUniBaseName
[SourceFile
.BaseName
] = (SourceFile
.BaseName
+ "Bin")
982 if SourceFile
.Type
.upper() == ".UNI" :
984 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
986 VfrUniBaseName
["UniOffsetName"] = (self
.BaseName
+ "Strings")
989 if len(VfrUniBaseName
) > 0:
991 if InfData
.BuildType
!= 'UEFI_HII':
992 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
993 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
994 UniVfrOffsetFileNameList
= []
995 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
996 TrimCmd
= "Trim --Vfr-Uni-Offset -o %s --ModuleName=%s --DebugDir=%s " % (UniVfrOffsetFileName
, self
.BaseName
, self
.EfiDebugPath
)
997 GenFdsGlobalVariable
.SecCmdList
.append(TrimCmd
)
998 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
999 [UniVfrOffsetFileName
],
1004 VfrUniOffsetList
= self
.__GetBuildOutputMapFileVfrUniInfo
(VfrUniBaseName
)
1006 # Generate the Raw data of raw section
1008 if VfrUniOffsetList
:
1009 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
1010 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
1011 FfsInfStatement
.__GenUniVfrOffsetFile
(VfrUniOffsetList
, UniVfrOffsetFileName
)
1012 UniVfrOffsetFileNameList
= []
1013 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
1014 """Call GenSection"""
1016 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
1017 UniVfrOffsetFileNameList
,
1020 #os.remove(UniVfrOffsetFileName)
1021 if UniVfrOffsetFileSection
:
1022 SectList
.append(UniVfrOffsetFileSection
)
1023 HasGeneratedFlag
= True
1025 for SecName
in SectList
:
1026 SectFiles
.append(SecName
)
1027 SectAlignments
.append(Align
)
1029 return SectFiles
, SectAlignments
1031 ## __GenComplexFileFfs__() method
1035 # @param self The object pointer
1036 # @param Rule The rule object used to generate section
1037 # @param InputFileList The output file list from GenSection
1038 # @retval string Generated FFS file name
1040 def __GenComplexFileFfs__(self
, Rule
, InputFile
, Alignments
, MakefilePath
= None):
1042 if Rule
.NameGuid
is not None and Rule
.NameGuid
.startswith('PCD('):
1043 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
1044 if len(PcdValue
) == 0:
1045 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
1047 if PcdValue
.startswith('{'):
1048 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
1049 RegistryGuidStr
= PcdValue
1050 if len(RegistryGuidStr
) == 0:
1051 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
1053 self
.ModuleGuid
= RegistryGuidStr
1055 FfsOutput
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
1056 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputFile
,
1057 FdfFvFileTypeToFileType
[Rule
.FvFileType
],
1058 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
1059 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
1060 SectionAlign
=Alignments
,
1061 MakefilePath
=MakefilePath
1065 ## __GetBuildOutputMapFileVfrUniInfo() method
1067 # Find the offset of UNI/INF object offset in the EFI image file.
1069 # @param self The object pointer
1070 # @param VfrUniBaseName A name list contain the UNI/INF object name.
1071 # @retval RetValue A list contain offset of UNI/INF object.
1073 def __GetBuildOutputMapFileVfrUniInfo(self
, VfrUniBaseName
):
1074 MapFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".map")
1075 EfiFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".efi")
1076 return GetVariableOffset(MapFileName
, EfiFileName
, list(VfrUniBaseName
.values()))
1078 ## __GenUniVfrOffsetFile() method
1080 # Generate the offset file for the module which contain VFR or UNI file.
1082 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
1083 # @param UniVfrOffsetFileName The output offset file name.
1086 def __GenUniVfrOffsetFile(VfrUniOffsetList
, UniVfrOffsetFileName
):
1088 # Use a instance of StringIO to cache data
1089 fStringIO
= BytesIO()
1091 for Item
in VfrUniOffsetList
:
1092 if (Item
[0].find("Strings") != -1):
1094 # UNI offset in image.
1096 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
1098 UniGuid
= b
'\xe0\xc5\x13\x89\xf63\x86M\x9b\xf1C\xef\x89\xfc\x06f'
1099 fStringIO
.write(UniGuid
)
1100 UniValue
= pack ('Q', int (Item
[1], 16))
1101 fStringIO
.write (UniValue
)
1104 # VFR binary offset in image.
1106 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
1108 VfrGuid
= b
'\xb4|\xbc\xd0Gj_I\xaa\x11q\x07F\xda\x06\xa2'
1109 fStringIO
.write(VfrGuid
)
1111 VfrValue
= pack ('Q', int (Item
[1], 16))
1112 fStringIO
.write (VfrValue
)
1115 # write data into file.
1118 SaveFileOnChange(UniVfrOffsetFileName
, fStringIO
.getvalue())
1120 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)