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.
20 import Common
.LongFilePathOs
as os
23 from GenFdsGlobalVariable
import GenFdsGlobalVariable
29 import RuleComplexFile
30 from CommonDataClass
.FdfClass
import FfsInfStatementClassObject
31 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
32 from Common
.String
import *
33 from Common
.Misc
import PathClass
34 from Common
.Misc
import GuidStructureByteArrayToGuidString
35 from Common
.Misc
import ProcessDuplicatedInf
36 from Common
.Misc
import GetVariableOffset
37 from Common
import EdkLogger
38 from Common
.BuildToolError
import *
39 from GuidSection
import GuidSection
40 from FvImageSection
import FvImageSection
41 from Common
.Misc
import PeImageClass
42 from AutoGen
.GenDepex
import DependencyExpression
43 from PatchPcdValue
.PatchPcdValue
import PatchBinaryFile
44 from Common
.LongFilePathSupport
import CopyLongFilePath
45 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
46 import Common
.GlobalData
as GlobalData
47 from DepexSection
import DepexSection
48 from Common
.Misc
import SaveFileOnChange
49 from Common
.Expression
import *
50 from Common
.DataType
import *
52 ## generate FFS from INF
55 class FfsInfStatement(FfsInfStatementClassObject
):
58 # @param self The object pointer
61 FfsInfStatementClassObject
.__init
__(self
)
62 self
.TargetOverrideList
= []
63 self
.ShadowFromInfFile
= None
64 self
.KeepRelocFromRule
= None
67 self
.PiSpecVersion
= '0x00000000'
69 self
.FinalTargetSuffixMap
= {}
70 self
.CurrentLineNum
= None
71 self
.CurrentLineContent
= None
73 self
.InfFileName
= None
74 self
.OverrideGuid
= None
75 self
.PatchedBinFile
= ''
79 ## GetFinalTargetSuffixMap() method
81 # Get final build target list
82 def GetFinalTargetSuffixMap(self
):
83 if not self
.InfModule
or not self
.CurrentArch
:
85 if not self
.FinalTargetSuffixMap
:
86 FinalBuildTargetList
= GenFdsGlobalVariable
.GetModuleCodaTargetList(self
.InfModule
, self
.CurrentArch
)
87 for File
in FinalBuildTargetList
:
88 self
.FinalTargetSuffixMap
.setdefault(os
.path
.splitext(File
)[1], []).append(File
)
90 # Check if current INF module has DEPEX
91 if '.depex' not in self
.FinalTargetSuffixMap
and self
.InfModule
.ModuleType
!= SUP_MODULE_USER_DEFINED \
92 and not self
.InfModule
.DxsFile
and not self
.InfModule
.LibraryClass
:
93 ModuleType
= self
.InfModule
.ModuleType
94 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
96 if ModuleType
!= DataType
.SUP_MODULE_USER_DEFINED
:
97 for LibraryClass
in PlatformDataBase
.LibraryClasses
.GetKeys():
98 if LibraryClass
.startswith("NULL") and PlatformDataBase
.LibraryClasses
[LibraryClass
, ModuleType
]:
99 self
.InfModule
.LibraryClasses
[LibraryClass
] = PlatformDataBase
.LibraryClasses
[LibraryClass
, ModuleType
]
101 StrModule
= str(self
.InfModule
)
102 PlatformModule
= None
103 if StrModule
in PlatformDataBase
.Modules
:
104 PlatformModule
= PlatformDataBase
.Modules
[StrModule
]
105 for LibraryClass
in PlatformModule
.LibraryClasses
:
106 if LibraryClass
.startswith("NULL"):
107 self
.InfModule
.LibraryClasses
[LibraryClass
] = PlatformModule
.LibraryClasses
[LibraryClass
]
109 DependencyList
= [self
.InfModule
]
112 while len(DependencyList
) > 0:
113 Module
= DependencyList
.pop(0)
116 for Dep
in Module
.Depex
[self
.CurrentArch
, ModuleType
]:
118 DepexList
.append('AND')
119 DepexList
.append('(')
120 DepexList
.extend(Dep
)
121 if DepexList
[-1] == 'END': # no need of a END at this time
123 DepexList
.append(')')
124 if 'BEFORE' in DepexList
or 'AFTER' in DepexList
:
126 for LibName
in Module
.LibraryClasses
:
127 if LibName
in LibraryInstance
:
129 if PlatformModule
and LibName
in PlatformModule
.LibraryClasses
:
130 LibraryPath
= PlatformModule
.LibraryClasses
[LibName
]
132 LibraryPath
= PlatformDataBase
.LibraryClasses
[LibName
, ModuleType
]
134 LibraryPath
= Module
.LibraryClasses
[LibName
]
137 LibraryModule
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[LibraryPath
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
138 LibraryInstance
[LibName
] = LibraryModule
139 DependencyList
.append(LibraryModule
)
141 Dpx
= DependencyExpression(DepexList
, ModuleType
, True)
142 if len(Dpx
.PostfixNotation
) != 0:
143 # It means this module has DEPEX
144 self
.FinalTargetSuffixMap
['.depex'] = [os
.path
.join(self
.EfiOutputPath
, self
.BaseName
) + '.depex']
145 return self
.FinalTargetSuffixMap
147 ## __InfParse() method
149 # Parse inf file to get module information
151 # @param self The object pointer
152 # @param Dict dictionary contains macro and value pair
154 def __InfParse__(self
, Dict
= {}):
156 GenFdsGlobalVariable
.VerboseLogger( " Begine parsing INf file : %s" %self
.InfFileName
)
158 self
.InfFileName
= self
.InfFileName
.replace('$(WORKSPACE)', '')
159 if len(self
.InfFileName
) > 1 and self
.InfFileName
[0] == '\\' and self
.InfFileName
[1] == '\\':
161 elif self
.InfFileName
[0] == '\\' or self
.InfFileName
[0] == '/' :
162 self
.InfFileName
= self
.InfFileName
[1:]
164 if self
.InfFileName
.find('$') == -1:
165 InfPath
= NormPath(self
.InfFileName
)
166 if not os
.path
.exists(InfPath
):
167 InfPath
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(InfPath
)
168 if not os
.path
.exists(InfPath
):
169 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Non-existant Module %s !" % (self
.InfFileName
))
171 self
.CurrentArch
= self
.GetCurrentArch()
173 # Get the InfClass object
176 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
177 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
179 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
182 # Cache lower case version of INF path before processing FILE_GUID override
184 InfLowerPath
= str(PathClassObj
).lower()
185 if self
.OverrideGuid
:
186 PathClassObj
= ProcessDuplicatedInf(PathClassObj
, self
.OverrideGuid
, GenFdsGlobalVariable
.WorkSpaceDir
)
187 if self
.CurrentArch
is not None:
189 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
191 # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath
193 self
.BaseName
= Inf
.BaseName
194 self
.ModuleGuid
= Inf
.Guid
195 self
.ModuleType
= Inf
.ModuleType
196 if Inf
.Specification
is not None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
197 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
198 if Inf
.AutoGenVersion
< 0x00010005:
199 self
.ModuleType
= Inf
.ComponentType
200 self
.VersionString
= Inf
.Version
201 self
.BinFileList
= Inf
.Binaries
202 self
.SourceFileList
= Inf
.Sources
203 if self
.KeepReloc
is None and Inf
.Shadow
:
204 self
.ShadowFromInfFile
= Inf
.Shadow
207 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, TAB_COMMON
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
208 self
.BaseName
= Inf
.BaseName
209 self
.ModuleGuid
= Inf
.Guid
210 self
.ModuleType
= Inf
.ModuleType
211 if Inf
.Specification
is not None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
212 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
213 self
.VersionString
= Inf
.Version
214 self
.BinFileList
= Inf
.Binaries
215 self
.SourceFileList
= Inf
.Sources
216 if self
.BinFileList
== []:
217 EdkLogger
.error("GenFds", GENFDS_ERROR
,
218 "INF %s specified in FDF could not be found in build ARCH %s!" \
219 % (self
.InfFileName
, GenFdsGlobalVariable
.ArchList
))
221 if self
.OverrideGuid
:
222 self
.ModuleGuid
= self
.OverrideGuid
224 if len(self
.SourceFileList
) != 0 and not self
.InDsc
:
225 EdkLogger
.warn("GenFds", GENFDS_ERROR
, "Module %s NOT found in DSC file; Is it really a binary module?" % (self
.InfFileName
))
227 if self
.ModuleType
== SUP_MODULE_SMM_CORE
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
228 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
)
230 if self
.ModuleType
== SUP_MODULE_MM_CORE_STANDALONE
and int(self
.PiSpecVersion
, 16) < 0x00010032:
231 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
)
233 if Inf
._Defs
is not None and len(Inf
._Defs
) > 0:
234 self
.OptRomDefs
.update(Inf
._Defs
)
238 Platform
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
239 FdfPcdDict
= GenFdsGlobalVariable
.FdfParser
.Profile
.PcdDict
240 PlatformPcds
= Platform
.Pcds
242 # Workaround here: both build and GenFds tool convert the workspace path to lower case
243 # But INF file path in FDF and DSC file may have real case characters.
244 # Try to convert the path to lower case to see if PCDs value are override by DSC.
246 for DscModule
in Platform
.Modules
:
247 DscModules
[str(DscModule
).lower()] = Platform
.Modules
[DscModule
]
248 for PcdKey
in InfPcds
:
249 Pcd
= InfPcds
[PcdKey
]
250 if not hasattr(Pcd
, 'Offset'):
252 if Pcd
.Type
!= TAB_PCDS_PATCHABLE_IN_MODULE
:
254 # Override Patchable PCD value by the value from DSC
256 if InfLowerPath
in DscModules
and PcdKey
in DscModules
[InfLowerPath
].Pcds
:
257 PatchPcd
= DscModules
[InfLowerPath
].Pcds
[PcdKey
]
258 elif PcdKey
in Platform
.Pcds
:
259 PatchPcd
= Platform
.Pcds
[PcdKey
]
261 if PatchPcd
and Pcd
.Type
== PatchPcd
.Type
:
262 DefaultValue
= PatchPcd
.DefaultValue
265 # Override Patchable PCD value by the value from FDF
267 if PcdKey
in FdfPcdDict
:
268 DefaultValue
= FdfPcdDict
[PcdKey
]
271 # Override Patchable PCD value by the value from Build Option
272 BuildOptionOverride
= False
273 if GlobalData
.BuildOptionPcd
:
274 for pcd
in GlobalData
.BuildOptionPcd
:
275 if PcdKey
== (pcd
[1], pcd
[0]):
278 DefaultValue
= pcd
[3]
279 BuildOptionOverride
= True
282 if not DscOverride
and not FdfOverride
and not BuildOptionOverride
:
285 # Support Flexible PCD format
288 DefaultValue
= ValueExpressionEx(DefaultValue
, Pcd
.DatumType
, Platform
._GuidDict
)(True)
289 except BadExpression
:
290 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'PCD [%s.%s] Value "%s"' %(Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, DefaultValue
), File
=self
.InfFileName
)
292 if Pcd
.InfDefaultValue
:
294 Pcd
.InfDefaultValue
= ValueExpressionEx(Pcd
.InfDefaultValue
, Pcd
.DatumType
, Platform
._GuidDict
)(True)
295 except BadExpression
:
296 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'PCD [%s.%s] Value "%s"' %(Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Pcd
.DefaultValue
),File
=self
.InfFileName
)
298 # Check value, if value are equal, no need to patch
299 if Pcd
.DatumType
== TAB_VOID
:
300 if Pcd
.InfDefaultValue
== DefaultValue
or DefaultValue
in [None, '']:
302 # Get the string size from FDF or DSC
303 if DefaultValue
[0] == 'L':
304 # Remove L"", but the '\0' must be appended
305 MaxDatumSize
= str((len(DefaultValue
) - 2) * 2)
306 elif DefaultValue
[0] == '{':
307 MaxDatumSize
= str(len(DefaultValue
.split(',')))
309 MaxDatumSize
= str(len(DefaultValue
) - 1)
311 Pcd
.MaxDatumSize
= PatchPcd
.MaxDatumSize
312 # If no defined the maximum size in DSC, try to get current size from INF
313 if Pcd
.MaxDatumSize
in ['', None]:
314 Pcd
.MaxDatumSize
= str(len(Pcd
.InfDefaultValue
.split(',')))
317 if Pcd
.InfDefaultValue
.upper().startswith('0X'):
319 if DefaultValue
.upper().startswith('0X'):
322 PcdValueInImg
= int(Pcd
.InfDefaultValue
, Base1
)
323 PcdValueInDscOrFdf
= int(DefaultValue
, Base2
)
324 if PcdValueInImg
== PcdValueInDscOrFdf
:
328 # Check the Pcd size and data type
329 if Pcd
.DatumType
== TAB_VOID
:
330 if int(MaxDatumSize
) > int(Pcd
.MaxDatumSize
):
331 EdkLogger
.error("GenFds", GENFDS_ERROR
, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \
332 % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, int(MaxDatumSize
) - int(Pcd
.MaxDatumSize
)))
334 if PcdValueInDscOrFdf
> MAX_VAL_TYPE
[Pcd
.DatumType
] \
335 or PcdValueInImg
> MAX_VAL_TYPE
[Pcd
.DatumType
]:
336 EdkLogger
.error("GenFds", GENFDS_ERROR
, "The size of %s type PCD '%s.%s' doesn't match its data type." \
337 % (Pcd
.DatumType
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
338 self
.PatchPcds
.append((Pcd
, DefaultValue
))
341 self
.PcdIsDriver
= Inf
.PcdIsDriver
342 self
.IsBinaryModule
= Inf
.IsBinaryModule
344 Inf
._GetDepexExpression
()
345 if len(Inf
._Depex
.data
) > 0 and len(Inf
._DepexExpression
.data
) > 0:
348 GenFdsGlobalVariable
.VerboseLogger("BaseName : %s" % self
.BaseName
)
349 GenFdsGlobalVariable
.VerboseLogger("ModuleGuid : %s" % self
.ModuleGuid
)
350 GenFdsGlobalVariable
.VerboseLogger("ModuleType : %s" % self
.ModuleType
)
351 GenFdsGlobalVariable
.VerboseLogger("VersionString : %s" % self
.VersionString
)
352 GenFdsGlobalVariable
.VerboseLogger("InfFileName :%s" % self
.InfFileName
)
355 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\
358 self
.OutputPath
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, \
359 self
.ModuleGuid
+ self
.BaseName
)
360 if not os
.path
.exists(self
.OutputPath
) :
361 os
.makedirs(self
.OutputPath
)
363 self
.EfiOutputPath
, self
.EfiDebugPath
= self
.__GetEFIOutPutPath
__()
364 GenFdsGlobalVariable
.VerboseLogger( "ModuelEFIPath: " + self
.EfiOutputPath
)
368 # Patch EFI file with patch PCD
370 # @param EfiFile: EFI file needs to be patched.
371 # @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name
372 # If passed in file does not end with efi, return as is
374 def PatchEfiFile(self
, EfiFile
, FileType
):
376 # If the module does not have any patches, then return path to input file
378 if not self
.PatchPcds
:
382 # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED
384 if FileType
!= BINARY_FILE_TYPE_PE32
and self
.ModuleType
!= SUP_MODULE_USER_DEFINED
:
388 # Generate path to patched output file
390 Basename
= os
.path
.basename(EfiFile
)
391 Output
= os
.path
.normpath (os
.path
.join(self
.OutputPath
, Basename
))
394 # If this file has already been patched, then return the path to the patched file
396 if self
.PatchedBinFile
== Output
:
400 # If a different file from the same module has already been patched, then generate an error
402 if self
.PatchedBinFile
:
403 EdkLogger
.error("GenFds", GENFDS_ERROR
,
404 'Only one binary file can be patched:\n'
405 ' a binary file has been patched: %s\n'
406 ' current file: %s' % (self
.PatchedBinFile
, EfiFile
),
407 File
=self
.InfFileName
)
410 # Copy unpatched file contents to output file location to perform patching
412 CopyLongFilePath(EfiFile
, Output
)
415 # Apply patches to patched output file
417 for Pcd
, Value
in self
.PatchPcds
:
418 RetVal
, RetStr
= PatchBinaryFile(Output
, int(Pcd
.Offset
, 0), Pcd
.DatumType
, Value
, Pcd
.MaxDatumSize
)
420 EdkLogger
.error("GenFds", GENFDS_ERROR
, RetStr
, File
=self
.InfFileName
)
423 # Save the path of the patched output file
425 self
.PatchedBinFile
= Output
428 # Return path to patched output file
436 # @param self The object pointer
437 # @param Dict dictionary contains macro and value pair
438 # @param FvChildAddr Array of the inside FvImage base address
439 # @param FvParentAddr Parent Fv base address
440 # @retval string Generated FFS file name
442 def GenFfs(self
, Dict
= {}, FvChildAddr
= [], FvParentAddr
=None, IsMakefile
=False, FvName
=None):
444 # Parse Inf file get Module related information
447 self
.__InfParse
__(Dict
)
448 Arch
= self
.GetCurrentArch()
449 SrcFile
= mws
.join( GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
);
450 DestFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
453 SrcPath
= os
.path
.dirname(SrcFile
)
454 SrcFileName
= os
.path
.basename(SrcFile
)
455 SrcFileBase
, SrcFileExt
= os
.path
.splitext(SrcFileName
)
456 DestPath
= os
.path
.dirname(DestFile
)
457 DestFileName
= os
.path
.basename(DestFile
)
458 DestFileBase
, DestFileExt
= os
.path
.splitext(DestFileName
)
462 "${s_path}" : SrcPath
,
463 "${s_dir}" : SrcFileDir
,
464 "${s_name}" : SrcFileName
,
465 "${s_base}" : SrcFileBase
,
466 "${s_ext}" : SrcFileExt
,
469 "${d_path}" : DestPath
,
470 "${d_name}" : DestFileName
,
471 "${d_base}" : DestFileBase
,
472 "${d_ext}" : DestFileExt
475 # Allow binary type module not specify override rule in FDF file.
477 if len(self
.BinFileList
) > 0:
478 if self
.Rule
is None or self
.Rule
== "":
481 if not IsMakefile
and GenFdsGlobalVariable
.EnableGenfdsMultiThread
and self
.Rule
!= 'BINARY':
484 # Get the rule of how to generate Ffs file
486 Rule
= self
.__GetRule
__()
487 GenFdsGlobalVariable
.VerboseLogger( "Packing binaries from inf file : %s" %self
.InfFileName
)
489 # Convert Fv File Type for PI1.1 SMM driver.
491 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
492 if Rule
.FvFileType
== 'DRIVER':
493 Rule
.FvFileType
= 'SMM'
495 # Framework SMM Driver has no SMM FV file type
497 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
498 if Rule
.FvFileType
== 'SMM' or Rule
.FvFileType
== SUP_MODULE_SMM_CORE
:
499 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File
=self
.InfFileName
)
501 # For the rule only has simpleFile
504 if self
.IsBinaryModule
:
507 MakefilePath
= self
.InfFileName
, Arch
508 if isinstance (Rule
, RuleSimpleFile
.RuleSimpleFile
):
509 SectionOutputList
= self
.__GenSimpleFileSection
__(Rule
, IsMakefile
=IsMakefile
)
510 FfsOutput
= self
.__GenSimpleFileFfs
__(Rule
, SectionOutputList
, MakefilePath
=MakefilePath
)
513 # For Rule has ComplexFile
515 elif isinstance(Rule
, RuleComplexFile
.RuleComplexFile
):
516 InputSectList
, InputSectAlignments
= self
.__GenComplexFileSection
__(Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
=IsMakefile
)
517 FfsOutput
= self
.__GenComplexFileFfs
__(Rule
, InputSectList
, InputSectAlignments
, MakefilePath
=MakefilePath
)
520 ## __ExtendMacro__() method
522 # Replace macro with its value
524 # @param self The object pointer
525 # @param String The string to be replaced
526 # @retval string Macro replaced string
528 def __ExtendMacro__ (self
, String
):
530 '$(INF_OUTPUT)' : self
.EfiOutputPath
,
531 '$(MODULE_NAME)' : self
.BaseName
,
532 '$(BUILD_NUMBER)': self
.BuildNum
,
533 '$(INF_VERSION)' : self
.VersionString
,
534 '$(NAMED_GUID)' : self
.ModuleGuid
536 String
= GenFdsGlobalVariable
.MacroExtend(String
, MacroDict
)
537 String
= GenFdsGlobalVariable
.MacroExtend(String
, self
.MacroDict
)
540 ## __GetRule__() method
542 # Get correct rule for generating FFS for this INF
544 # @param self The object pointer
545 # @retval Rule Rule object
547 def __GetRule__ (self
) :
549 if self
.CurrentArch
is None:
550 CurrentArchList
= ['common']
552 CurrentArchList
.append(self
.CurrentArch
)
554 for CurrentArch
in CurrentArchList
:
555 RuleName
= 'RULE' + \
557 CurrentArch
.upper() + \
559 self
.ModuleType
.upper()
560 if self
.Rule
is not None:
561 RuleName
= RuleName
+ \
565 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
567 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
570 RuleName
= 'RULE' + \
574 self
.ModuleType
.upper()
576 if self
.Rule
is not None:
577 RuleName
= RuleName
+ \
581 GenFdsGlobalVariable
.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName
, self
.InfFileName
))
583 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
585 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
589 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'Don\'t Find common rule %s for INF %s' \
590 % (RuleName
, self
.InfFileName
))
592 ## __GetPlatformArchList__() method
594 # Get Arch list this INF built under
596 # @param self The object pointer
597 # @retval list Arch list
599 def __GetPlatformArchList__(self
):
601 InfFileKey
= os
.path
.normpath(mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
))
603 for Arch
in GenFdsGlobalVariable
.ArchList
:
604 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
605 if PlatformDataBase
is not None:
606 if InfFileKey
in PlatformDataBase
.Modules
:
607 DscArchList
.append (Arch
)
610 # BaseTools support build same module more than once, the module path with FILE_GUID overridden has
611 # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key,
612 # but the path (self.MetaFile.Path) is the real path
614 for key
in PlatformDataBase
.Modules
:
615 if InfFileKey
== str((PlatformDataBase
.Modules
[key
]).MetaFile
.Path
):
616 DscArchList
.append (Arch
)
621 ## GetCurrentArch() method
623 # Get Arch list of the module from this INF is to be placed into flash
625 # @param self The object pointer
626 # @retval list Arch list
628 def GetCurrentArch(self
) :
630 TargetArchList
= GenFdsGlobalVariable
.ArchList
632 PlatformArchList
= self
.__GetPlatformArchList
__()
634 CurArchList
= TargetArchList
635 if PlatformArchList
!= []:
636 CurArchList
= list(set (TargetArchList
) & set (PlatformArchList
))
637 GenFdsGlobalVariable
.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList
))
640 if self
.KeyStringList
!= []:
641 for Key
in self
.KeyStringList
:
642 Key
= GenFdsGlobalVariable
.MacroExtend(Key
)
643 Target
, Tag
, Arch
= Key
.split('_')
644 if Arch
in CurArchList
:
645 ArchList
.append(Arch
)
646 if Target
not in self
.TargetOverrideList
:
647 self
.TargetOverrideList
.append(Target
)
649 ArchList
= CurArchList
651 UseArchList
= TargetArchList
652 if self
.UseArch
is not None:
654 UseArchList
.append(self
.UseArch
)
655 ArchList
= list(set (UseArchList
) & set (ArchList
))
657 self
.InfFileName
= NormPath(self
.InfFileName
)
658 if len(PlatformArchList
) == 0:
660 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
661 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
663 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
664 if len(ArchList
) == 1:
667 elif len(ArchList
) > 1:
668 if len(PlatformArchList
) == 0:
669 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
))
671 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
))
673 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." \
674 % (self
.InfFileName
, str(PlatformArchList
), GenFdsGlobalVariable
.ActivePlatform
, str(set (UseArchList
) & set (TargetArchList
))))
676 ## __GetEFIOutPutPath__() method
678 # Get the output path for generated files
680 # @param self The object pointer
681 # @retval string Path that output files from this INF go to
683 def __GetEFIOutPutPath__(self
):
687 (ModulePath
, FileName
) = os
.path
.split(self
.InfFileName
)
688 Index
= FileName
.rfind('.')
689 FileName
= FileName
[0:Index
]
690 if self
.OverrideGuid
:
691 FileName
= self
.OverrideGuid
693 if self
.CurrentArch
is not None:
694 Arch
= self
.CurrentArch
696 OutputPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
702 DebugPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
708 OutputPath
= os
.path
.realpath(OutputPath
)
709 DebugPath
= os
.path
.realpath(DebugPath
)
710 return OutputPath
, DebugPath
712 ## __GenSimpleFileSection__() method
714 # Generate section by specified file name or a list of files with file extension
716 # @param self The object pointer
717 # @param Rule The rule object used to generate section
718 # @retval string File name of the generated section file
720 def __GenSimpleFileSection__(self
, Rule
, IsMakefile
= False):
722 # Prepare the parameter of GenSection
726 GenSecInputFile
= None
727 if Rule
.FileName
is not None:
728 GenSecInputFile
= self
.__ExtendMacro
__(Rule
.FileName
)
729 if os
.path
.isabs(GenSecInputFile
):
730 GenSecInputFile
= os
.path
.normpath(GenSecInputFile
)
732 GenSecInputFile
= os
.path
.normpath(os
.path
.join(self
.EfiOutputPath
, GenSecInputFile
))
734 FileList
, IsSect
= Section
.Section
.GetFileList(self
, '', Rule
.FileExtension
)
737 SectionType
= Rule
.SectionType
739 # Convert Fv Section Type for PI1.1 SMM driver.
741 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
742 if SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
:
743 SectionType
= BINARY_FILE_TYPE_SMM_DEPEX
745 # Framework SMM Driver has no SMM_DEPEX section type
747 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
748 if SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
749 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
751 if self
.ModuleType
in (SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
):
752 if self
.KeepReloc
is not None:
753 NoStrip
= self
.KeepReloc
754 elif Rule
.KeepReloc
is not None:
755 NoStrip
= Rule
.KeepReloc
756 elif self
.ShadowFromInfFile
is not None:
757 NoStrip
= self
.ShadowFromInfFile
760 for File
in FileList
:
763 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
764 Ffs
.Ffs
.SectionSuffix
[SectionType
] + SUP_MODULE_SEC
+ SecNum
766 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
767 File
= GenFdsGlobalVariable
.MacroExtend(File
, Dict
, self
.CurrentArch
)
769 #Get PE Section alignment when align is set to AUTO
770 if self
.Alignment
== 'Auto' and (SectionType
== BINARY_FILE_TYPE_PE32
or SectionType
== BINARY_FILE_TYPE_TE
):
771 ImageObj
= PeImageClass (File
)
772 if ImageObj
.SectionAlignment
< 0x400:
773 self
.Alignment
= str (ImageObj
.SectionAlignment
)
774 elif ImageObj
.SectionAlignment
< 0x100000:
775 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
777 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x100000) + 'M'
780 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
781 if not os
.path
.exists(FileBeforeStrip
) or \
782 (os
.path
.getmtime(File
) > os
.path
.getmtime(FileBeforeStrip
)):
783 CopyLongFilePath(File
, FileBeforeStrip
)
784 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
785 GenFdsGlobalVariable
.GenerateFirmwareImage(
789 IsMakefile
=IsMakefile
793 if SectionType
== BINARY_FILE_TYPE_TE
:
794 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
795 GenFdsGlobalVariable
.GenerateFirmwareImage(
799 IsMakefile
=IsMakefile
802 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [File
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
803 OutputFileList
.append(OutputFile
)
806 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
807 Ffs
.Ffs
.SectionSuffix
[SectionType
] + SUP_MODULE_SEC
+ SecNum
808 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
809 GenSecInputFile
= GenFdsGlobalVariable
.MacroExtend(GenSecInputFile
, Dict
, self
.CurrentArch
)
811 #Get PE Section alignment when align is set to AUTO
812 if self
.Alignment
== 'Auto' and (SectionType
== BINARY_FILE_TYPE_PE32
or SectionType
== BINARY_FILE_TYPE_TE
):
813 ImageObj
= PeImageClass (GenSecInputFile
)
814 if ImageObj
.SectionAlignment
< 0x400:
815 self
.Alignment
= str (ImageObj
.SectionAlignment
)
816 elif ImageObj
.SectionAlignment
< 0x100000:
817 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
819 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x100000) + 'M'
822 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
823 if not os
.path
.exists(FileBeforeStrip
) or \
824 (os
.path
.getmtime(GenSecInputFile
) > os
.path
.getmtime(FileBeforeStrip
)):
825 CopyLongFilePath(GenSecInputFile
, FileBeforeStrip
)
827 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
828 GenFdsGlobalVariable
.GenerateFirmwareImage(
832 IsMakefile
=IsMakefile
834 GenSecInputFile
= StrippedFile
836 if SectionType
== BINARY_FILE_TYPE_TE
:
837 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
838 GenFdsGlobalVariable
.GenerateFirmwareImage(
842 IsMakefile
=IsMakefile
844 GenSecInputFile
= TeFile
845 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [GenSecInputFile
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
846 OutputFileList
.append(OutputFile
)
848 return OutputFileList
850 ## __GenSimpleFileFfs__() method
854 # @param self The object pointer
855 # @param Rule The rule object used to generate section
856 # @param InputFileList The output file list from GenSection
857 # @retval string Generated FFS file name
859 def __GenSimpleFileFfs__(self
, Rule
, InputFileList
, MakefilePath
= None):
860 FfsOutput
= self
.OutputPath
+ \
862 self
.__ExtendMacro
__(Rule
.NameGuid
) + \
865 GenFdsGlobalVariable
.VerboseLogger(self
.__ExtendMacro
__(Rule
.NameGuid
))
867 SectionAlignments
= []
868 for InputFile
in InputFileList
:
869 InputSection
.append(InputFile
)
870 SectionAlignments
.append(Rule
.SectAlignment
)
872 if Rule
.NameGuid
is not None and Rule
.NameGuid
.startswith('PCD('):
873 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
874 if len(PcdValue
) == 0:
875 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
877 if PcdValue
.startswith('{'):
878 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
879 RegistryGuidStr
= PcdValue
880 if len(RegistryGuidStr
) == 0:
881 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
883 self
.ModuleGuid
= RegistryGuidStr
885 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputSection
,
886 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
887 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
888 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
889 SectionAlign
=SectionAlignments
,
890 MakefilePath
=MakefilePath
894 ## __GenComplexFileSection__() method
896 # Generate section by sections in Rule
898 # @param self The object pointer
899 # @param Rule The rule object used to generate section
900 # @param FvChildAddr Array of the inside FvImage base address
901 # @param FvParentAddr Parent Fv base address
902 # @retval string File name of the generated section file
904 def __GenComplexFileSection__(self
, Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
= False):
905 if self
.ModuleType
in (SUP_MODULE_SEC
, SUP_MODULE_PEI_CORE
, SUP_MODULE_PEIM
):
906 if Rule
.KeepReloc
is not None:
907 self
.KeepRelocFromRule
= Rule
.KeepReloc
911 HasGeneratedFlag
= False
912 if self
.PcdIsDriver
== 'PEI_PCD_DRIVER':
913 if self
.IsBinaryModule
:
914 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "PEIPcdDataBase.raw")
916 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "PEIPcdDataBase.raw")
917 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "PEIPcdDataBaseSec.raw")
918 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
921 IsMakefile
= IsMakefile
923 SectFiles
.append(PcdExDbSecName
)
924 SectAlignments
.append(None)
925 elif self
.PcdIsDriver
== 'DXE_PCD_DRIVER':
926 if self
.IsBinaryModule
:
927 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "DXEPcdDataBase.raw")
929 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "DXEPcdDataBase.raw")
930 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "DXEPcdDataBaseSec.raw")
931 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
934 IsMakefile
= IsMakefile
936 SectFiles
.append(PcdExDbSecName
)
937 SectAlignments
.append(None)
938 for Sect
in Rule
.SectionList
:
939 SecIndex
= '%d' %Index
942 # Convert Fv Section Type for PI1.1 SMM driver.
944 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
945 if Sect
.SectionType
== BINARY_FILE_TYPE_DXE_DEPEX
:
946 Sect
.SectionType
= BINARY_FILE_TYPE_SMM_DEPEX
948 # Framework SMM Driver has no SMM_DEPEX section type
950 if self
.ModuleType
== SUP_MODULE_DXE_SMM_DRIVER
and int(self
.PiSpecVersion
, 16) < 0x0001000A:
951 if Sect
.SectionType
== BINARY_FILE_TYPE_SMM_DEPEX
:
952 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
954 # process the inside FvImage from FvSection or GuidSection
956 if FvChildAddr
!= []:
957 if isinstance(Sect
, FvImageSection
):
958 Sect
.FvAddr
= FvChildAddr
.pop(0)
959 elif isinstance(Sect
, GuidSection
):
960 Sect
.FvAddr
= FvChildAddr
961 if FvParentAddr
is not None and isinstance(Sect
, GuidSection
):
962 Sect
.FvParentAddr
= FvParentAddr
964 if Rule
.KeyStringList
!= []:
965 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, Rule
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
967 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, self
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
969 if not HasGeneratedFlag
:
970 UniVfrOffsetFileSection
= ""
971 ModuleFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
)
972 InfData
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClass(ModuleFileName
), self
.CurrentArch
]
974 # Search the source list in InfData to find if there are .vfr file exist.
977 VfrUniOffsetList
= []
978 for SourceFile
in InfData
.Sources
:
979 if SourceFile
.Type
.upper() == ".VFR" :
981 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
983 VfrUniBaseName
[SourceFile
.BaseName
] = (SourceFile
.BaseName
+ "Bin")
984 if SourceFile
.Type
.upper() == ".UNI" :
986 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
988 VfrUniBaseName
["UniOffsetName"] = (self
.BaseName
+ "Strings")
991 if len(VfrUniBaseName
) > 0:
993 if InfData
.BuildType
!= 'UEFI_HII':
994 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
995 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
996 UniVfrOffsetFileNameList
= []
997 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
998 TrimCmd
= "Trim --Vfr-Uni-Offset -o %s --ModuleName=%s --DebugDir=%s " % (UniVfrOffsetFileName
, self
.BaseName
, self
.EfiDebugPath
)
999 GenFdsGlobalVariable
.SecCmdList
.append(TrimCmd
)
1000 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
1001 [UniVfrOffsetFileName
],
1006 VfrUniOffsetList
= self
.__GetBuildOutputMapFileVfrUniInfo
(VfrUniBaseName
)
1008 # Generate the Raw data of raw section
1010 if VfrUniOffsetList
:
1011 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
1012 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
1013 FfsInfStatement
.__GenUniVfrOffsetFile
(VfrUniOffsetList
, UniVfrOffsetFileName
)
1014 UniVfrOffsetFileNameList
= []
1015 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
1016 """Call GenSection"""
1018 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
1019 UniVfrOffsetFileNameList
,
1022 #os.remove(UniVfrOffsetFileName)
1023 if UniVfrOffsetFileSection
:
1024 SectList
.append(UniVfrOffsetFileSection
)
1025 HasGeneratedFlag
= True
1027 for SecName
in SectList
:
1028 SectFiles
.append(SecName
)
1029 SectAlignments
.append(Align
)
1031 return SectFiles
, SectAlignments
1033 ## __GenComplexFileFfs__() method
1037 # @param self The object pointer
1038 # @param Rule The rule object used to generate section
1039 # @param InputFileList The output file list from GenSection
1040 # @retval string Generated FFS file name
1042 def __GenComplexFileFfs__(self
, Rule
, InputFile
, Alignments
, MakefilePath
= None):
1044 if Rule
.NameGuid
is not None and Rule
.NameGuid
.startswith('PCD('):
1045 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
1046 if len(PcdValue
) == 0:
1047 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
1049 if PcdValue
.startswith('{'):
1050 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
1051 RegistryGuidStr
= PcdValue
1052 if len(RegistryGuidStr
) == 0:
1053 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
1055 self
.ModuleGuid
= RegistryGuidStr
1057 FfsOutput
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
1058 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputFile
,
1059 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
1060 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
1061 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
1062 SectionAlign
=Alignments
,
1063 MakefilePath
=MakefilePath
1067 ## __GetBuildOutputMapFileVfrUniInfo() method
1069 # Find the offset of UNI/INF object offset in the EFI image file.
1071 # @param self The object pointer
1072 # @param VfrUniBaseName A name list contain the UNI/INF object name.
1073 # @retval RetValue A list contain offset of UNI/INF object.
1075 def __GetBuildOutputMapFileVfrUniInfo(self
, VfrUniBaseName
):
1076 MapFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".map")
1077 EfiFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".efi")
1078 return GetVariableOffset(MapFileName
, EfiFileName
, VfrUniBaseName
.values())
1080 ## __GenUniVfrOffsetFile() method
1082 # Generate the offset file for the module which contain VFR or UNI file.
1084 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
1085 # @param UniVfrOffsetFileName The output offset file name.
1088 def __GenUniVfrOffsetFile(VfrUniOffsetList
, UniVfrOffsetFileName
):
1090 # Use a instance of StringIO to cache data
1091 fStringIO
= StringIO
.StringIO('')
1093 for Item
in VfrUniOffsetList
:
1094 if (Item
[0].find("Strings") != -1):
1096 # UNI offset in image.
1098 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
1100 UniGuid
= [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
1101 UniGuid
= [chr(ItemGuid
) for ItemGuid
in UniGuid
]
1102 fStringIO
.write(''.join(UniGuid
))
1103 UniValue
= pack ('Q', int (Item
[1], 16))
1104 fStringIO
.write (UniValue
)
1107 # VFR binary offset in image.
1109 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
1111 VfrGuid
= [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
1112 VfrGuid
= [chr(ItemGuid
) for ItemGuid
in VfrGuid
]
1113 fStringIO
.write(''.join(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)