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 # This program and the accompanying materials
8 # are licensed and made available under the terms and conditions of the BSD License
9 # which accompanies this distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 from __future__
import absolute_import
21 import Common
.LongFilePathOs
as os
22 from io
import BytesIO
24 from .GenFdsGlobalVariable
import GenFdsGlobalVariable
29 from . import RuleSimpleFile
30 from . import RuleComplexFile
31 from CommonDataClass
.FdfClass
import FfsInfStatementClassObject
32 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
33 from Common
.StringUtils
import *
34 from Common
.Misc
import PathClass
35 from Common
.Misc
import GuidStructureByteArrayToGuidString
36 from Common
.Misc
import ProcessDuplicatedInf
37 from Common
.Misc
import GetVariableOffset
38 from Common
import EdkLogger
39 from Common
.BuildToolError
import *
40 from .GuidSection
import GuidSection
41 from .FvImageSection
import FvImageSection
42 from Common
.Misc
import PeImageClass
43 from AutoGen
.GenDepex
import DependencyExpression
44 from PatchPcdValue
.PatchPcdValue
import PatchBinaryFile
45 from Common
.LongFilePathSupport
import CopyLongFilePath
46 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
47 import Common
.GlobalData
as GlobalData
48 from .DepexSection
import DepexSection
49 from Common
.Misc
import SaveFileOnChange
50 from Common
.Expression
import *
51 from Common
.DataType
import *
53 ## generate FFS from INF
56 class FfsInfStatement(FfsInfStatementClassObject
):
59 # @param self The object pointer
62 FfsInfStatementClassObject
.__init
__(self
)
63 self
.TargetOverrideList
= []
64 self
.ShadowFromInfFile
= None
65 self
.KeepRelocFromRule
= None
68 self
.PiSpecVersion
= '0x00000000'
70 self
.FinalTargetSuffixMap
= {}
71 self
.CurrentLineNum
= None
72 self
.CurrentLineContent
= None
74 self
.InfFileName
= None
75 self
.OverrideGuid
= None
76 self
.PatchedBinFile
= ''
80 ## GetFinalTargetSuffixMap() method
82 # Get final build target list
83 def GetFinalTargetSuffixMap(self
):
84 if not self
.InfModule
or not self
.CurrentArch
:
86 if not self
.FinalTargetSuffixMap
:
87 FinalBuildTargetList
= GenFdsGlobalVariable
.GetModuleCodaTargetList(self
.InfModule
, self
.CurrentArch
)
88 for File
in FinalBuildTargetList
:
89 self
.FinalTargetSuffixMap
.setdefault(os
.path
.splitext(File
)[1], []).append(File
)
91 # Check if current INF module has DEPEX
92 if '.depex' not in self
.FinalTargetSuffixMap
and self
.InfModule
.ModuleType
!= SUP_MODULE_USER_DEFINED \
93 and not self
.InfModule
.DxsFile
and not self
.InfModule
.LibraryClass
:
94 ModuleType
= self
.InfModule
.ModuleType
95 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
97 if ModuleType
!= DataType
.SUP_MODULE_USER_DEFINED
:
98 for LibraryClass
in PlatformDataBase
.LibraryClasses
.GetKeys():
99 if LibraryClass
.startswith("NULL") and PlatformDataBase
.LibraryClasses
[LibraryClass
, ModuleType
]:
100 self
.InfModule
.LibraryClasses
[LibraryClass
] = PlatformDataBase
.LibraryClasses
[LibraryClass
, ModuleType
]
102 StrModule
= str(self
.InfModule
)
103 PlatformModule
= None
104 if StrModule
in PlatformDataBase
.Modules
:
105 PlatformModule
= PlatformDataBase
.Modules
[StrModule
]
106 for LibraryClass
in PlatformModule
.LibraryClasses
:
107 if LibraryClass
.startswith("NULL"):
108 self
.InfModule
.LibraryClasses
[LibraryClass
] = PlatformModule
.LibraryClasses
[LibraryClass
]
110 DependencyList
= [self
.InfModule
]
113 while len(DependencyList
) > 0:
114 Module
= DependencyList
.pop(0)
117 for Dep
in Module
.Depex
[self
.CurrentArch
, ModuleType
]:
119 DepexList
.append('AND')
120 DepexList
.append('(')
121 DepexList
.extend(Dep
)
122 if DepexList
[-1] == 'END': # no need of a END at this time
124 DepexList
.append(')')
125 if 'BEFORE' in DepexList
or 'AFTER' in DepexList
:
127 for LibName
in Module
.LibraryClasses
:
128 if LibName
in LibraryInstance
:
130 if PlatformModule
and LibName
in PlatformModule
.LibraryClasses
:
131 LibraryPath
= PlatformModule
.LibraryClasses
[LibName
]
133 LibraryPath
= PlatformDataBase
.LibraryClasses
[LibName
, ModuleType
]
135 LibraryPath
= Module
.LibraryClasses
[LibName
]
138 LibraryModule
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[LibraryPath
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
139 LibraryInstance
[LibName
] = LibraryModule
140 DependencyList
.append(LibraryModule
)
142 Dpx
= DependencyExpression(DepexList
, ModuleType
, True)
143 if len(Dpx
.PostfixNotation
) != 0:
144 # It means this module has DEPEX
145 self
.FinalTargetSuffixMap
['.depex'] = [os
.path
.join(self
.EfiOutputPath
, self
.BaseName
) + '.depex']
146 return self
.FinalTargetSuffixMap
148 ## __InfParse() method
150 # Parse inf file to get module information
152 # @param self The object pointer
153 # @param Dict dictionary contains macro and value pair
155 def __InfParse__(self
, Dict
= {}):
157 GenFdsGlobalVariable
.VerboseLogger( " Begine parsing INf file : %s" %self
.InfFileName
)
159 self
.InfFileName
= self
.InfFileName
.replace('$(WORKSPACE)', '')
160 if len(self
.InfFileName
) > 1 and self
.InfFileName
[0] == '\\' and self
.InfFileName
[1] == '\\':
162 elif self
.InfFileName
[0] == '\\' or self
.InfFileName
[0] == '/' :
163 self
.InfFileName
= self
.InfFileName
[1:]
165 if self
.InfFileName
.find('$') == -1:
166 InfPath
= NormPath(self
.InfFileName
)
167 if not os
.path
.exists(InfPath
):
168 InfPath
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(InfPath
)
169 if not os
.path
.exists(InfPath
):
170 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Non-existant Module %s !" % (self
.InfFileName
))
172 self
.CurrentArch
= self
.GetCurrentArch()
174 # Get the InfClass object
177 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
178 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
180 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
183 # Cache lower case version of INF path before processing FILE_GUID override
185 InfLowerPath
= str(PathClassObj
).lower()
186 if self
.OverrideGuid
:
187 PathClassObj
= ProcessDuplicatedInf(PathClassObj
, self
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
)
188 if self
.CurrentArch
is not None:
190 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
192 # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath
194 self
.BaseName
= Inf
.BaseName
195 self
.ModuleGuid
= Inf
.Guid
196 self
.ModuleType
= Inf
.ModuleType
197 if Inf
.Specification
is not None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
198 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
199 if Inf
.AutoGenVersion
< 0x00010005:
200 self
.ModuleType
= Inf
.ComponentType
201 self
.VersionString
= Inf
.Version
202 self
.BinFileList
= Inf
.Binaries
203 self
.SourceFileList
= Inf
.Sources
204 if self
.KeepReloc
is None and Inf
.Shadow
:
205 self
.ShadowFromInfFile
= Inf
.Shadow
208 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, TAB_COMMON
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
209 self
.BaseName
= Inf
.BaseName
210 self
.ModuleGuid
= Inf
.Guid
211 self
.ModuleType
= Inf
.ModuleType
212 if Inf
.Specification
is not None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
213 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
214 self
.VersionString
= Inf
.Version
215 self
.BinFileList
= Inf
.Binaries
216 self
.SourceFileList
= Inf
.Sources
217 if self
.BinFileList
== []:
218 EdkLogger
.error("GenFds", GENFDS_ERROR
,
219 "INF %s specified in FDF could not be found in build ARCH %s!" \
220 % (self
.InfFileName
, GenFdsGlobalVariable
.ArchList
))
222 if self
.OverrideGuid
:
223 self
.ModuleGuid
= self
.OverrideGuid
225 if len(self
.SourceFileList
) != 0 and not self
.InDsc
:
226 EdkLogger
.warn("GenFds", GENFDS_ERROR
, "Module %s NOT found in DSC file; Is it really a binary module?" % (self
.InfFileName
))
228 if self
.ModuleType
== SUP_MODULE_SMM_CORE
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
229 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
)
231 if self
.ModuleType
== SUP_MODULE_MM_CORE_STANDALONE
and int(self
.PiSpecVersion
, 16) < 0x00010032:
232 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
)
234 if Inf
._Defs
is not None and len(Inf
._Defs
) > 0:
235 self
.OptRomDefs
.update(Inf
._Defs
)
239 Platform
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
240 FdfPcdDict
= GenFdsGlobalVariable
.FdfParser
.Profile
.PcdDict
241 PlatformPcds
= Platform
.Pcds
243 # Workaround here: both build and GenFds tool convert the workspace path to lower case
244 # But INF file path in FDF and DSC file may have real case characters.
245 # Try to convert the path to lower case to see if PCDs value are override by DSC.
247 for DscModule
in Platform
.Modules
:
248 DscModules
[str(DscModule
).lower()] = Platform
.Modules
[DscModule
]
249 for PcdKey
in InfPcds
:
250 Pcd
= InfPcds
[PcdKey
]
251 if not hasattr(Pcd
, 'Offset'):
253 if Pcd
.Type
!= TAB_PCDS_PATCHABLE_IN_MODULE
:
255 # Override Patchable PCD value by the value from DSC
257 if InfLowerPath
in DscModules
and PcdKey
in DscModules
[InfLowerPath
].Pcds
:
258 PatchPcd
= DscModules
[InfLowerPath
].Pcds
[PcdKey
]
259 elif PcdKey
in Platform
.Pcds
:
260 PatchPcd
= Platform
.Pcds
[PcdKey
]
262 if PatchPcd
and Pcd
.Type
== PatchPcd
.Type
:
263 DefaultValue
= PatchPcd
.DefaultValue
266 # Override Patchable PCD value by the value from FDF
268 if PcdKey
in FdfPcdDict
:
269 DefaultValue
= FdfPcdDict
[PcdKey
]
272 # Override Patchable PCD value by the value from Build Option
273 BuildOptionOverride
= False
274 if GlobalData
.BuildOptionPcd
:
275 for pcd
in GlobalData
.BuildOptionPcd
:
276 if PcdKey
== (pcd
[1], pcd
[0]):
279 DefaultValue
= pcd
[3]
280 BuildOptionOverride
= True
283 if not DscOverride
and not FdfOverride
and not BuildOptionOverride
:
286 # Support Flexible PCD format
289 DefaultValue
= ValueExpressionEx(DefaultValue
, Pcd
.DatumType
, Platform
._GuidDict
)(True)
290 except BadExpression
:
291 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'PCD [%s.%s] Value "%s"' %(Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, DefaultValue
), File
=self
.InfFileName
)
293 if Pcd
.InfDefaultValue
:
295 Pcd
.InfDefaultValue
= ValueExpressionEx(Pcd
.InfDefaultValue
, Pcd
.DatumType
, Platform
._GuidDict
)(True)
296 except BadExpression
:
297 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'PCD [%s.%s] Value "%s"' %(Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Pcd
.DefaultValue
), File
=self
.InfFileName
)
299 # Check value, if value are equal, no need to patch
300 if Pcd
.DatumType
== TAB_VOID
:
301 if Pcd
.InfDefaultValue
== DefaultValue
or not DefaultValue
:
303 # Get the string size from FDF or DSC
304 if DefaultValue
[0] == 'L':
305 # Remove L"", but the '\0' must be appended
306 MaxDatumSize
= str((len(DefaultValue
) - 2) * 2)
307 elif DefaultValue
[0] == '{':
308 MaxDatumSize
= str(len(DefaultValue
.split(',')))
310 MaxDatumSize
= str(len(DefaultValue
) - 1)
312 Pcd
.MaxDatumSize
= PatchPcd
.MaxDatumSize
313 # If no defined the maximum size in DSC, try to get current size from INF
314 if not Pcd
.MaxDatumSize
:
315 Pcd
.MaxDatumSize
= str(len(Pcd
.InfDefaultValue
.split(',')))
318 if Pcd
.InfDefaultValue
.upper().startswith('0X'):
320 if DefaultValue
.upper().startswith('0X'):
323 PcdValueInImg
= int(Pcd
.InfDefaultValue
, Base1
)
324 PcdValueInDscOrFdf
= int(DefaultValue
, Base2
)
325 if PcdValueInImg
== PcdValueInDscOrFdf
:
329 # Check the Pcd size and data type
330 if Pcd
.DatumType
== TAB_VOID
:
331 if int(MaxDatumSize
) > int(Pcd
.MaxDatumSize
):
332 EdkLogger
.error("GenFds", GENFDS_ERROR
, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \
333 % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, int(MaxDatumSize
) - int(Pcd
.MaxDatumSize
)))
335 if PcdValueInDscOrFdf
> MAX_VAL_TYPE
[Pcd
.DatumType
] \
336 or PcdValueInImg
> MAX_VAL_TYPE
[Pcd
.DatumType
]:
337 EdkLogger
.error("GenFds", GENFDS_ERROR
, "The size of %s type PCD '%s.%s' doesn't match its data type." \
338 % (Pcd
.DatumType
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
339 self
.PatchPcds
.append((Pcd
, DefaultValue
))
342 self
.PcdIsDriver
= Inf
.PcdIsDriver
343 self
.IsBinaryModule
= Inf
.IsBinaryModule
345 Inf
._GetDepexExpression
()
346 if len(Inf
._Depex
.data
) > 0 and len(Inf
._DepexExpression
.data
) > 0:
349 GenFdsGlobalVariable
.VerboseLogger("BaseName : %s" % self
.BaseName
)
350 GenFdsGlobalVariable
.VerboseLogger("ModuleGuid : %s" % self
.ModuleGuid
)
351 GenFdsGlobalVariable
.VerboseLogger("ModuleType : %s" % self
.ModuleType
)
352 GenFdsGlobalVariable
.VerboseLogger("VersionString : %s" % self
.VersionString
)
353 GenFdsGlobalVariable
.VerboseLogger("InfFileName :%s" % self
.InfFileName
)
356 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\
359 self
.OutputPath
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, \
360 self
.ModuleGuid
+ self
.BaseName
)
361 if not os
.path
.exists(self
.OutputPath
) :
362 os
.makedirs(self
.OutputPath
)
364 self
.EfiOutputPath
, self
.EfiDebugPath
= self
.__GetEFIOutPutPath
__()
365 GenFdsGlobalVariable
.VerboseLogger( "ModuelEFIPath: " + self
.EfiOutputPath
)
369 # Patch EFI file with patch PCD
371 # @param EfiFile: EFI file needs to be patched.
372 # @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name
373 # If passed in file does not end with efi, return as is
375 def PatchEfiFile(self
, EfiFile
, FileType
):
377 # If the module does not have any patches, then return path to input file
379 if not self
.PatchPcds
:
383 # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED
385 if FileType
!= BINARY_FILE_TYPE_PE32
and self
.ModuleType
!= SUP_MODULE_USER_DEFINED
:
389 # Generate path to patched output file
391 Basename
= os
.path
.basename(EfiFile
)
392 Output
= os
.path
.normpath (os
.path
.join(self
.OutputPath
, Basename
))
395 # If this file has already been patched, then return the path to the patched file
397 if self
.PatchedBinFile
== Output
:
401 # If a different file from the same module has already been patched, then generate an error
403 if self
.PatchedBinFile
:
404 EdkLogger
.error("GenFds", GENFDS_ERROR
,
405 'Only one binary file can be patched:\n'
406 ' a binary file has been patched: %s\n'
407 ' current file: %s' % (self
.PatchedBinFile
, EfiFile
),
408 File
=self
.InfFileName
)
411 # Copy unpatched file contents to output file location to perform patching
413 CopyLongFilePath(EfiFile
, Output
)
416 # Apply patches to patched output file
418 for Pcd
, Value
in self
.PatchPcds
:
419 RetVal
, RetStr
= PatchBinaryFile(Output
, int(Pcd
.Offset
, 0), Pcd
.DatumType
, Value
, Pcd
.MaxDatumSize
)
421 EdkLogger
.error("GenFds", GENFDS_ERROR
, RetStr
, File
=self
.InfFileName
)
424 # Save the path of the patched output file
426 self
.PatchedBinFile
= Output
429 # Return path to patched output file
437 # @param self The object pointer
438 # @param Dict dictionary contains macro and value pair
439 # @param FvChildAddr Array of the inside FvImage base address
440 # @param FvParentAddr Parent Fv base address
441 # @retval string Generated FFS file name
443 def GenFfs(self
, Dict
= {}, FvChildAddr
= [], FvParentAddr
=None, IsMakefile
=False, FvName
=None):
445 # Parse Inf file get Module related information
448 self
.__InfParse
__(Dict
)
449 Arch
= self
.GetCurrentArch()
450 SrcFile
= mws
.join( GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
);
451 DestFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
454 SrcPath
= os
.path
.dirname(SrcFile
)
455 SrcFileName
= os
.path
.basename(SrcFile
)
456 SrcFileBase
, SrcFileExt
= os
.path
.splitext(SrcFileName
)
457 DestPath
= os
.path
.dirname(DestFile
)
458 DestFileName
= os
.path
.basename(DestFile
)
459 DestFileBase
, DestFileExt
= os
.path
.splitext(DestFileName
)
463 "${s_path}" : SrcPath
,
464 "${s_dir}" : SrcFileDir
,
465 "${s_name}" : SrcFileName
,
466 "${s_base}" : SrcFileBase
,
467 "${s_ext}" : SrcFileExt
,
470 "${d_path}" : DestPath
,
471 "${d_name}" : DestFileName
,
472 "${d_base}" : DestFileBase
,
473 "${d_ext}" : DestFileExt
476 # Allow binary type module not specify override rule in FDF file.
478 if len(self
.BinFileList
) > 0:
479 if self
.Rule
is None or self
.Rule
== "":
482 if not IsMakefile
and GenFdsGlobalVariable
.EnableGenfdsMultiThread
and self
.Rule
!= 'BINARY':
485 # Get the rule of how to generate Ffs file
487 Rule
= self
.__GetRule
__()
488 GenFdsGlobalVariable
.VerboseLogger( "Packing binaries from inf file : %s" %self
.InfFileName
)
490 # Convert Fv File Type for PI1.1 SMM driver.
492 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
493 if Rule
.FvFileType
== 'DRIVER':
494 Rule
.FvFileType
= 'SMM'
496 # Framework SMM Driver has no SMM FV file type
498 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
499 if Rule
.FvFileType
== 'SMM' or Rule
.FvFileType
== SUP_MODULE_SMM_CORE
:
500 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File
=self
.InfFileName
)
502 # For the rule only has simpleFile
505 if self
.IsBinaryModule
:
508 MakefilePath
= self
.InfFileName
, Arch
509 if isinstance (Rule
, RuleSimpleFile
.RuleSimpleFile
):
510 SectionOutputList
= self
.__GenSimpleFileSection
__(Rule
, IsMakefile
=IsMakefile
)
511 FfsOutput
= self
.__GenSimpleFileFfs
__(Rule
, SectionOutputList
, MakefilePath
=MakefilePath
)
514 # For Rule has ComplexFile
516 elif isinstance(Rule
, RuleComplexFile
.RuleComplexFile
):
517 InputSectList
, InputSectAlignments
= self
.__GenComplexFileSection
__(Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
=IsMakefile
)
518 FfsOutput
= self
.__GenComplexFileFfs
__(Rule
, InputSectList
, InputSectAlignments
, MakefilePath
=MakefilePath
)
521 ## __ExtendMacro__() method
523 # Replace macro with its value
525 # @param self The object pointer
526 # @param String The string to be replaced
527 # @retval string Macro replaced string
529 def __ExtendMacro__ (self
, String
):
531 '$(INF_OUTPUT)' : self
.EfiOutputPath
,
532 '$(MODULE_NAME)' : self
.BaseName
,
533 '$(BUILD_NUMBER)': self
.BuildNum
,
534 '$(INF_VERSION)' : self
.VersionString
,
535 '$(NAMED_GUID)' : self
.ModuleGuid
537 String
= GenFdsGlobalVariable
.MacroExtend(String
, MacroDict
)
538 String
= GenFdsGlobalVariable
.MacroExtend(String
, self
.MacroDict
)
541 ## __GetRule__() method
543 # Get correct rule for generating FFS for this INF
545 # @param self The object pointer
546 # @retval Rule Rule object
548 def __GetRule__ (self
) :
550 if self
.CurrentArch
is None:
551 CurrentArchList
= ['common']
553 CurrentArchList
.append(self
.CurrentArch
)
555 for CurrentArch
in CurrentArchList
:
556 RuleName
= 'RULE' + \
558 CurrentArch
.upper() + \
560 self
.ModuleType
.upper()
561 if self
.Rule
is not None:
562 RuleName
= RuleName
+ \
566 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
568 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
571 RuleName
= 'RULE' + \
575 self
.ModuleType
.upper()
577 if self
.Rule
is not None:
578 RuleName
= RuleName
+ \
582 GenFdsGlobalVariable
.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName
, self
.InfFileName
))
584 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
586 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
590 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'Don\'t Find common rule %s for INF %s' \
591 % (RuleName
, self
.InfFileName
))
593 ## __GetPlatformArchList__() method
595 # Get Arch list this INF built under
597 # @param self The object pointer
598 # @retval list Arch list
600 def __GetPlatformArchList__(self
):
602 InfFileKey
= os
.path
.normpath(mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
))
604 for Arch
in GenFdsGlobalVariable
.ArchList
:
605 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
606 if PlatformDataBase
is not None:
607 if InfFileKey
in PlatformDataBase
.Modules
:
608 DscArchList
.append (Arch
)
611 # BaseTools support build same module more than once, the module path with FILE_GUID overridden has
612 # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key,
613 # but the path (self.MetaFile.Path) is the real path
615 for key
in PlatformDataBase
.Modules
:
616 if InfFileKey
== str((PlatformDataBase
.Modules
[key
]).MetaFile
.Path
):
617 DscArchList
.append (Arch
)
622 ## GetCurrentArch() method
624 # Get Arch list of the module from this INF is to be placed into flash
626 # @param self The object pointer
627 # @retval list Arch list
629 def GetCurrentArch(self
) :
631 TargetArchList
= GenFdsGlobalVariable
.ArchList
633 PlatformArchList
= self
.__GetPlatformArchList
__()
635 CurArchList
= TargetArchList
636 if PlatformArchList
!= []:
637 CurArchList
= list(set (TargetArchList
) & set (PlatformArchList
))
638 GenFdsGlobalVariable
.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList
))
641 if self
.KeyStringList
!= []:
642 for Key
in self
.KeyStringList
:
643 Key
= GenFdsGlobalVariable
.MacroExtend(Key
)
644 Target
, Tag
, Arch
= Key
.split('_')
645 if Arch
in CurArchList
:
646 ArchList
.append(Arch
)
647 if Target
not in self
.TargetOverrideList
:
648 self
.TargetOverrideList
.append(Target
)
650 ArchList
= CurArchList
652 UseArchList
= TargetArchList
653 if self
.UseArch
is not None:
655 UseArchList
.append(self
.UseArch
)
656 ArchList
= list(set (UseArchList
) & set (ArchList
))
658 self
.InfFileName
= NormPath(self
.InfFileName
)
659 if len(PlatformArchList
) == 0:
661 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
662 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
664 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
665 if len(ArchList
) == 1:
668 elif len(ArchList
) > 1:
669 if len(PlatformArchList
) == 0:
670 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
))
672 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
))
674 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." \
675 % (self
.InfFileName
, str(PlatformArchList
), GenFdsGlobalVariable
.ActivePlatform
, str(set (UseArchList
) & set (TargetArchList
))))
677 ## __GetEFIOutPutPath__() method
679 # Get the output path for generated files
681 # @param self The object pointer
682 # @retval string Path that output files from this INF go to
684 def __GetEFIOutPutPath__(self
):
688 (ModulePath
, FileName
) = os
.path
.split(self
.InfFileName
)
689 Index
= FileName
.rfind('.')
690 FileName
= FileName
[0:Index
]
691 if self
.OverrideGuid
:
692 FileName
= self
.OverrideGuid
694 if self
.CurrentArch
is not None:
695 Arch
= self
.CurrentArch
697 OutputPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
703 DebugPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
709 OutputPath
= os
.path
.realpath(OutputPath
)
710 DebugPath
= os
.path
.realpath(DebugPath
)
711 return OutputPath
, DebugPath
713 ## __GenSimpleFileSection__() method
715 # Generate section by specified file name or a list of files with file extension
717 # @param self The object pointer
718 # @param Rule The rule object used to generate section
719 # @retval string File name of the generated section file
721 def __GenSimpleFileSection__(self
, Rule
, IsMakefile
= False):
723 # Prepare the parameter of GenSection
727 GenSecInputFile
= None
728 if Rule
.FileName
is not None:
729 GenSecInputFile
= self
.__ExtendMacro
__(Rule
.FileName
)
730 if os
.path
.isabs(GenSecInputFile
):
731 GenSecInputFile
= os
.path
.normpath(GenSecInputFile
)
733 GenSecInputFile
= os
.path
.normpath(os
.path
.join(self
.EfiOutputPath
, GenSecInputFile
))
735 FileList
, IsSect
= Section
.Section
.GetFileList(self
, '', Rule
.FileExtension
)
738 SectionType
= Rule
.SectionType
740 # Convert Fv Section Type for PI1.1 SMM driver.
742 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
743 if SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
:
744 SectionType
= BINARY_FILE_TYPE_SMM_DEPEX
746 # Framework SMM Driver has no SMM_DEPEX section type
748 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
749 if SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
750 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
752 if self
.ModuleType
in (SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
):
753 if self
.KeepReloc
is not None:
754 NoStrip
= self
.KeepReloc
755 elif Rule
.KeepReloc
is not None:
756 NoStrip
= Rule
.KeepReloc
757 elif self
.ShadowFromInfFile
is not None:
758 NoStrip
= self
.ShadowFromInfFile
761 for File
in FileList
:
764 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
765 Ffs
.Ffs
.SectionSuffix
[SectionType
] + SUP_MODULE_SEC
+ SecNum
767 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
768 File
= GenFdsGlobalVariable
.MacroExtend(File
, Dict
, self
.CurrentArch
)
770 #Get PE Section alignment when align is set to AUTO
771 if self
.Alignment
== 'Auto' and (SectionType
== BINARY_FILE_TYPE_PE32
or SectionType
== BINARY_FILE_TYPE_TE
):
772 ImageObj
= PeImageClass (File
)
773 if ImageObj
.SectionAlignment
< 0x400:
774 self
.Alignment
= str (ImageObj
.SectionAlignment
)
775 elif ImageObj
.SectionAlignment
< 0x100000:
776 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
778 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x100000) + 'M'
781 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
782 if not os
.path
.exists(FileBeforeStrip
) or \
783 (os
.path
.getmtime(File
) > os
.path
.getmtime(FileBeforeStrip
)):
784 CopyLongFilePath(File
, FileBeforeStrip
)
785 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
786 GenFdsGlobalVariable
.GenerateFirmwareImage(
790 IsMakefile
=IsMakefile
794 if SectionType
== BINARY_FILE_TYPE_TE
:
795 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
796 GenFdsGlobalVariable
.GenerateFirmwareImage(
800 IsMakefile
=IsMakefile
803 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [File
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
804 OutputFileList
.append(OutputFile
)
807 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
808 Ffs
.Ffs
.SectionSuffix
[SectionType
] + SUP_MODULE_SEC
+ SecNum
809 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
810 GenSecInputFile
= GenFdsGlobalVariable
.MacroExtend(GenSecInputFile
, Dict
, self
.CurrentArch
)
812 #Get PE Section alignment when align is set to AUTO
813 if self
.Alignment
== 'Auto' and (SectionType
== BINARY_FILE_TYPE_PE32
or SectionType
== BINARY_FILE_TYPE_TE
):
814 ImageObj
= PeImageClass (GenSecInputFile
)
815 if ImageObj
.SectionAlignment
< 0x400:
816 self
.Alignment
= str (ImageObj
.SectionAlignment
)
817 elif ImageObj
.SectionAlignment
< 0x100000:
818 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
820 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x100000) + 'M'
823 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
824 if not os
.path
.exists(FileBeforeStrip
) or \
825 (os
.path
.getmtime(GenSecInputFile
) > os
.path
.getmtime(FileBeforeStrip
)):
826 CopyLongFilePath(GenSecInputFile
, FileBeforeStrip
)
828 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
829 GenFdsGlobalVariable
.GenerateFirmwareImage(
833 IsMakefile
=IsMakefile
835 GenSecInputFile
= StrippedFile
837 if SectionType
== BINARY_FILE_TYPE_TE
:
838 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
839 GenFdsGlobalVariable
.GenerateFirmwareImage(
843 IsMakefile
=IsMakefile
845 GenSecInputFile
= TeFile
846 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [GenSecInputFile
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
847 OutputFileList
.append(OutputFile
)
849 return OutputFileList
851 ## __GenSimpleFileFfs__() method
855 # @param self The object pointer
856 # @param Rule The rule object used to generate section
857 # @param InputFileList The output file list from GenSection
858 # @retval string Generated FFS file name
860 def __GenSimpleFileFfs__(self
, Rule
, InputFileList
, MakefilePath
= None):
861 FfsOutput
= self
.OutputPath
+ \
863 self
.__ExtendMacro
__(Rule
.NameGuid
) + \
866 GenFdsGlobalVariable
.VerboseLogger(self
.__ExtendMacro
__(Rule
.NameGuid
))
868 SectionAlignments
= []
869 for InputFile
in InputFileList
:
870 InputSection
.append(InputFile
)
871 SectionAlignments
.append(Rule
.SectAlignment
)
873 if Rule
.NameGuid
is not None and Rule
.NameGuid
.startswith('PCD('):
874 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
875 if len(PcdValue
) == 0:
876 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
878 if PcdValue
.startswith('{'):
879 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
880 RegistryGuidStr
= PcdValue
881 if len(RegistryGuidStr
) == 0:
882 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
884 self
.ModuleGuid
= RegistryGuidStr
886 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputSection
,
887 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
888 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
889 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
890 SectionAlign
=SectionAlignments
,
891 MakefilePath
=MakefilePath
895 ## __GenComplexFileSection__() method
897 # Generate section by sections in Rule
899 # @param self The object pointer
900 # @param Rule The rule object used to generate section
901 # @param FvChildAddr Array of the inside FvImage base address
902 # @param FvParentAddr Parent Fv base address
903 # @retval string File name of the generated section file
905 def __GenComplexFileSection__(self
, Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
= False):
906 if self
.ModuleType
in (SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
):
907 if Rule
.KeepReloc
is not None:
908 self
.KeepRelocFromRule
= Rule
.KeepReloc
912 HasGeneratedFlag
= False
913 if self
.PcdIsDriver
== 'PEI_PCD_DRIVER':
914 if self
.IsBinaryModule
:
915 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "PEIPcdDataBase.raw")
917 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "PEIPcdDataBase.raw")
918 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "PEIPcdDataBaseSec.raw")
919 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
922 IsMakefile
= IsMakefile
924 SectFiles
.append(PcdExDbSecName
)
925 SectAlignments
.append(None)
926 elif self
.PcdIsDriver
== 'DXE_PCD_DRIVER':
927 if self
.IsBinaryModule
:
928 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "DXEPcdDataBase.raw")
930 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "DXEPcdDataBase.raw")
931 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "DXEPcdDataBaseSec.raw")
932 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
935 IsMakefile
= IsMakefile
937 SectFiles
.append(PcdExDbSecName
)
938 SectAlignments
.append(None)
939 for Sect
in Rule
.SectionList
:
940 SecIndex
= '%d' %Index
943 # Convert Fv Section Type for PI1.1 SMM driver.
945 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
946 if Sect
.SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
:
947 Sect
.SectionType
= BINARY_FILE_TYPE_SMM_DEPEX
949 # Framework SMM Driver has no SMM_DEPEX section type
951 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
952 if Sect
.SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
953 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
955 # process the inside FvImage from FvSection or GuidSection
957 if FvChildAddr
!= []:
958 if isinstance(Sect
, FvImageSection
):
959 Sect
.FvAddr
= FvChildAddr
.pop(0)
960 elif isinstance(Sect
, GuidSection
):
961 Sect
.FvAddr
= FvChildAddr
962 if FvParentAddr
is not None and isinstance(Sect
, GuidSection
):
963 Sect
.FvParentAddr
= FvParentAddr
965 if Rule
.KeyStringList
!= []:
966 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, Rule
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
968 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, self
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
970 if not HasGeneratedFlag
:
971 UniVfrOffsetFileSection
= ""
972 ModuleFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
)
973 InfData
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClass(ModuleFileName
), self
.CurrentArch
]
975 # Search the source list in InfData to find if there are .vfr file exist.
978 VfrUniOffsetList
= []
979 for SourceFile
in InfData
.Sources
:
980 if SourceFile
.Type
.upper() == ".VFR" :
982 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
984 VfrUniBaseName
[SourceFile
.BaseName
] = (SourceFile
.BaseName
+ "Bin")
985 if SourceFile
.Type
.upper() == ".UNI" :
987 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
989 VfrUniBaseName
["UniOffsetName"] = (self
.BaseName
+ "Strings")
992 if len(VfrUniBaseName
) > 0:
994 if InfData
.BuildType
!= 'UEFI_HII':
995 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
996 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
997 UniVfrOffsetFileNameList
= []
998 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
999 TrimCmd
= "Trim --Vfr-Uni-Offset -o %s --ModuleName=%s --DebugDir=%s " % (UniVfrOffsetFileName
, self
.BaseName
, self
.EfiDebugPath
)
1000 GenFdsGlobalVariable
.SecCmdList
.append(TrimCmd
)
1001 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
1002 [UniVfrOffsetFileName
],
1007 VfrUniOffsetList
= self
.__GetBuildOutputMapFileVfrUniInfo
(VfrUniBaseName
)
1009 # Generate the Raw data of raw section
1011 if VfrUniOffsetList
:
1012 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
1013 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
1014 FfsInfStatement
.__GenUniVfrOffsetFile
(VfrUniOffsetList
, UniVfrOffsetFileName
)
1015 UniVfrOffsetFileNameList
= []
1016 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
1017 """Call GenSection"""
1019 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
1020 UniVfrOffsetFileNameList
,
1023 #os.remove(UniVfrOffsetFileName)
1024 if UniVfrOffsetFileSection
:
1025 SectList
.append(UniVfrOffsetFileSection
)
1026 HasGeneratedFlag
= True
1028 for SecName
in SectList
:
1029 SectFiles
.append(SecName
)
1030 SectAlignments
.append(Align
)
1032 return SectFiles
, SectAlignments
1034 ## __GenComplexFileFfs__() method
1038 # @param self The object pointer
1039 # @param Rule The rule object used to generate section
1040 # @param InputFileList The output file list from GenSection
1041 # @retval string Generated FFS file name
1043 def __GenComplexFileFfs__(self
, Rule
, InputFile
, Alignments
, MakefilePath
= None):
1045 if Rule
.NameGuid
is not None and Rule
.NameGuid
.startswith('PCD('):
1046 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
1047 if len(PcdValue
) == 0:
1048 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
1050 if PcdValue
.startswith('{'):
1051 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
1052 RegistryGuidStr
= PcdValue
1053 if len(RegistryGuidStr
) == 0:
1054 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
1056 self
.ModuleGuid
= RegistryGuidStr
1058 FfsOutput
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
1059 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputFile
,
1060 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
1061 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
1062 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
1063 SectionAlign
=Alignments
,
1064 MakefilePath
=MakefilePath
1068 ## __GetBuildOutputMapFileVfrUniInfo() method
1070 # Find the offset of UNI/INF object offset in the EFI image file.
1072 # @param self The object pointer
1073 # @param VfrUniBaseName A name list contain the UNI/INF object name.
1074 # @retval RetValue A list contain offset of UNI/INF object.
1076 def __GetBuildOutputMapFileVfrUniInfo(self
, VfrUniBaseName
):
1077 MapFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".map")
1078 EfiFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".efi")
1079 return GetVariableOffset(MapFileName
, EfiFileName
, VfrUniBaseName
.values())
1081 ## __GenUniVfrOffsetFile() method
1083 # Generate the offset file for the module which contain VFR or UNI file.
1085 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
1086 # @param UniVfrOffsetFileName The output offset file name.
1089 def __GenUniVfrOffsetFile(VfrUniOffsetList
, UniVfrOffsetFileName
):
1091 # Use a instance of StringIO to cache data
1092 fStringIO
= BytesIO('')
1094 for Item
in VfrUniOffsetList
:
1095 if (Item
[0].find("Strings") != -1):
1097 # UNI offset in image.
1099 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
1101 UniGuid
= [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
1102 UniGuid
= [chr(ItemGuid
) for ItemGuid
in UniGuid
]
1103 fStringIO
.write(''.join(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
= [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
1113 VfrGuid
= [chr(ItemGuid
) for ItemGuid
in VfrGuid
]
1114 fStringIO
.write(''.join(VfrGuid
))
1116 VfrValue
= pack ('Q', int (Item
[1], 16))
1117 fStringIO
.write (VfrValue
)
1120 # write data into file.
1123 SaveFileOnChange(UniVfrOffsetFileName
, fStringIO
.getvalue())
1125 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)