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 *
51 ## generate FFS from INF
54 class FfsInfStatement(FfsInfStatementClassObject
):
55 ## The mapping dictionary from datum type to its maximum number.
56 _MAX_SIZE_TYPE
= {"BOOLEAN":0x01, "UINT8":0xFF, "UINT16":0xFFFF, "UINT32":0xFFFFFFFF, "UINT64":0xFFFFFFFFFFFFFFFF}
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
!= "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
!= 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
!= 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
== None and Inf
.Shadow
:
205 self
.ShadowFromInfFile
= Inf
.Shadow
208 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, 'COMMON', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
209 self
.BaseName
= Inf
.BaseName
210 self
.ModuleGuid
= Inf
.Guid
211 self
.ModuleType
= Inf
.ModuleType
212 if Inf
.Specification
!= 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
== '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
== '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
!= 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
!= 'PatchableInModule':
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
== "VOID*":
301 if Pcd
.InfDefaultValue
== DefaultValue
or DefaultValue
in [None, '']:
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 Pcd
.MaxDatumSize
in ['', None]:
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
== "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
> FfsInfStatement
._MAX
_SIZE
_TYPE
[Pcd
.DatumType
] \
336 or PcdValueInImg
> FfsInfStatement
._MAX
_SIZE
_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
!= 'PE32' and self
.ModuleType
!= "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
== 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
== '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
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
499 if Rule
.FvFileType
== 'SMM' or Rule
.FvFileType
== '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
506 MakefilePath
= self
.InfFileName
, Arch
507 if isinstance (Rule
, RuleSimpleFile
.RuleSimpleFile
) :
508 SectionOutputList
= self
.__GenSimpleFileSection
__(Rule
, IsMakefile
=IsMakefile
)
509 FfsOutput
= self
.__GenSimpleFileFfs
__(Rule
, SectionOutputList
, MakefilePath
=MakefilePath
)
512 # For Rule has ComplexFile
514 elif isinstance(Rule
, RuleComplexFile
.RuleComplexFile
):
515 InputSectList
, InputSectAlignments
= self
.__GenComplexFileSection
__(Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
=IsMakefile
)
516 FfsOutput
= self
.__GenComplexFileFfs
__(Rule
, InputSectList
, InputSectAlignments
, MakefilePath
=MakefilePath
)
519 ## __ExtendMacro__() method
521 # Replace macro with its value
523 # @param self The object pointer
524 # @param String The string to be replaced
525 # @retval string Macro replaced string
527 def __ExtendMacro__ (self
, String
):
529 '$(INF_OUTPUT)' : self
.EfiOutputPath
,
530 '$(MODULE_NAME)' : self
.BaseName
,
531 '$(BUILD_NUMBER)': self
.BuildNum
,
532 '$(INF_VERSION)' : self
.VersionString
,
533 '$(NAMED_GUID)' : self
.ModuleGuid
535 String
= GenFdsGlobalVariable
.MacroExtend(String
, MacroDict
)
536 String
= GenFdsGlobalVariable
.MacroExtend(String
, self
.MacroDict
)
539 ## __GetRule__() method
541 # Get correct rule for generating FFS for this INF
543 # @param self The object pointer
544 # @retval Rule Rule object
546 def __GetRule__ (self
) :
548 if self
.CurrentArch
== None:
549 CurrentArchList
= ['common']
551 CurrentArchList
.append(self
.CurrentArch
)
553 for CurrentArch
in CurrentArchList
:
554 RuleName
= 'RULE' + \
556 CurrentArch
.upper() + \
558 self
.ModuleType
.upper()
559 if self
.Rule
!= None:
560 RuleName
= RuleName
+ \
564 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
566 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
569 RuleName
= 'RULE' + \
573 self
.ModuleType
.upper()
575 if self
.Rule
!= None:
576 RuleName
= RuleName
+ \
580 GenFdsGlobalVariable
.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName
, self
.InfFileName
))
582 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
584 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
588 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'Don\'t Find common rule %s for INF %s' \
589 % (RuleName
, self
.InfFileName
))
591 ## __GetPlatformArchList__() method
593 # Get Arch list this INF built under
595 # @param self The object pointer
596 # @retval list Arch list
598 def __GetPlatformArchList__(self
):
600 InfFileKey
= os
.path
.normpath(mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
))
602 for Arch
in GenFdsGlobalVariable
.ArchList
:
603 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
604 if PlatformDataBase
!= None:
605 if InfFileKey
in PlatformDataBase
.Modules
:
606 DscArchList
.append (Arch
)
609 # BaseTools support build same module more than once, the module path with FILE_GUID overridden has
610 # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key,
611 # but the path (self.MetaFile.Path) is the real path
613 for key
in PlatformDataBase
.Modules
.keys():
614 if InfFileKey
== str((PlatformDataBase
.Modules
[key
]).MetaFile
.Path
):
615 DscArchList
.append (Arch
)
620 ## GetCurrentArch() method
622 # Get Arch list of the module from this INF is to be placed into flash
624 # @param self The object pointer
625 # @retval list Arch list
627 def GetCurrentArch(self
) :
629 TargetArchList
= GenFdsGlobalVariable
.ArchList
631 PlatformArchList
= self
.__GetPlatformArchList
__()
633 CurArchList
= TargetArchList
634 if PlatformArchList
!= []:
635 CurArchList
= list(set (TargetArchList
) & set (PlatformArchList
))
636 GenFdsGlobalVariable
.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList
))
639 if self
.KeyStringList
!= []:
640 for Key
in self
.KeyStringList
:
641 Key
= GenFdsGlobalVariable
.MacroExtend(Key
)
642 Target
, Tag
, Arch
= Key
.split('_')
643 if Arch
in CurArchList
:
644 ArchList
.append(Arch
)
645 if Target
not in self
.TargetOverrideList
:
646 self
.TargetOverrideList
.append(Target
)
648 ArchList
= CurArchList
650 UseArchList
= TargetArchList
651 if self
.UseArch
!= None:
653 UseArchList
.append(self
.UseArch
)
654 ArchList
= list(set (UseArchList
) & set (ArchList
))
656 self
.InfFileName
= NormPath(self
.InfFileName
)
657 if len(PlatformArchList
) == 0:
659 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
660 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
662 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
663 if len(ArchList
) == 1:
666 elif len(ArchList
) > 1:
667 if len(PlatformArchList
) == 0:
668 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
))
670 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
))
672 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." \
673 % (self
.InfFileName
, str(PlatformArchList
), GenFdsGlobalVariable
.ActivePlatform
, str(set (UseArchList
) & set (TargetArchList
))))
675 ## __GetEFIOutPutPath__() method
677 # Get the output path for generated files
679 # @param self The object pointer
680 # @retval string Path that output files from this INF go to
682 def __GetEFIOutPutPath__(self
):
686 (ModulePath
, FileName
) = os
.path
.split(self
.InfFileName
)
687 Index
= FileName
.rfind('.')
688 FileName
= FileName
[0:Index
]
689 if self
.OverrideGuid
:
690 FileName
= self
.OverrideGuid
692 if self
.CurrentArch
!= None:
693 Arch
= self
.CurrentArch
695 OutputPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
701 DebugPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
707 OutputPath
= os
.path
.realpath(OutputPath
)
708 DebugPath
= os
.path
.realpath(DebugPath
)
709 return OutputPath
, DebugPath
711 ## __GenSimpleFileSection__() method
713 # Generate section by specified file name or a list of files with file extension
715 # @param self The object pointer
716 # @param Rule The rule object used to generate section
717 # @retval string File name of the generated section file
719 def __GenSimpleFileSection__(self
, Rule
, IsMakefile
= False):
721 # Prepare the parameter of GenSection
725 GenSecInputFile
= None
726 if Rule
.FileName
!= None:
727 GenSecInputFile
= self
.__ExtendMacro
__(Rule
.FileName
)
728 if os
.path
.isabs(GenSecInputFile
):
729 GenSecInputFile
= os
.path
.normpath(GenSecInputFile
)
731 GenSecInputFile
= os
.path
.normpath(os
.path
.join(self
.EfiOutputPath
, GenSecInputFile
))
733 FileList
, IsSect
= Section
.Section
.GetFileList(self
, '', Rule
.FileExtension
)
736 SectionType
= Rule
.SectionType
738 # Convert Fv Section Type for PI1.1 SMM driver.
740 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
741 if SectionType
== 'DXE_DEPEX':
742 SectionType
= 'SMM_DEPEX'
744 # Framework SMM Driver has no SMM_DEPEX section type
746 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
747 if SectionType
== 'SMM_DEPEX':
748 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
750 if self
.ModuleType
in ('SEC', 'PEI_CORE', 'PEIM'):
751 if self
.KeepReloc
!= None:
752 NoStrip
= self
.KeepReloc
753 elif Rule
.KeepReloc
!= None:
754 NoStrip
= Rule
.KeepReloc
755 elif self
.ShadowFromInfFile
!= None:
756 NoStrip
= self
.ShadowFromInfFile
759 for File
in FileList
:
762 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
763 Ffs
.Ffs
.SectionSuffix
[SectionType
] + 'SEC' + SecNum
765 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
766 File
= GenFdsGlobalVariable
.MacroExtend(File
, Dict
, self
.CurrentArch
)
768 #Get PE Section alignment when align is set to AUTO
769 if self
.Alignment
== 'Auto' and (SectionType
== 'PE32' or SectionType
== 'TE'):
770 ImageObj
= PeImageClass (File
)
771 if ImageObj
.SectionAlignment
< 0x400:
772 self
.Alignment
= str (ImageObj
.SectionAlignment
)
773 elif ImageObj
.SectionAlignment
< 0x100000:
774 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
776 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x100000) + 'M'
779 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
780 if not os
.path
.exists(FileBeforeStrip
) or \
781 (os
.path
.getmtime(File
) > os
.path
.getmtime(FileBeforeStrip
)):
782 CopyLongFilePath(File
, FileBeforeStrip
)
783 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
784 GenFdsGlobalVariable
.GenerateFirmwareImage(
788 IsMakefile
=IsMakefile
792 if SectionType
== 'TE':
793 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
794 GenFdsGlobalVariable
.GenerateFirmwareImage(
798 IsMakefile
=IsMakefile
801 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [File
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
802 OutputFileList
.append(OutputFile
)
805 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
806 Ffs
.Ffs
.SectionSuffix
[SectionType
] + 'SEC' + SecNum
807 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
808 GenSecInputFile
= GenFdsGlobalVariable
.MacroExtend(GenSecInputFile
, Dict
, self
.CurrentArch
)
810 #Get PE Section alignment when align is set to AUTO
811 if self
.Alignment
== 'Auto' and (SectionType
== 'PE32' or SectionType
== 'TE'):
812 ImageObj
= PeImageClass (GenSecInputFile
)
813 if ImageObj
.SectionAlignment
< 0x400:
814 self
.Alignment
= str (ImageObj
.SectionAlignment
)
815 elif ImageObj
.SectionAlignment
< 0x100000:
816 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
818 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x100000) + 'M'
821 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
822 if not os
.path
.exists(FileBeforeStrip
) or \
823 (os
.path
.getmtime(GenSecInputFile
) > os
.path
.getmtime(FileBeforeStrip
)):
824 CopyLongFilePath(GenSecInputFile
, FileBeforeStrip
)
826 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
827 GenFdsGlobalVariable
.GenerateFirmwareImage(
831 IsMakefile
=IsMakefile
833 GenSecInputFile
= StrippedFile
835 if SectionType
== 'TE':
836 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
837 GenFdsGlobalVariable
.GenerateFirmwareImage(
841 IsMakefile
=IsMakefile
843 GenSecInputFile
= TeFile
844 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [GenSecInputFile
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
845 OutputFileList
.append(OutputFile
)
847 return OutputFileList
849 ## __GenSimpleFileFfs__() method
853 # @param self The object pointer
854 # @param Rule The rule object used to generate section
855 # @param InputFileList The output file list from GenSection
856 # @retval string Generated FFS file name
858 def __GenSimpleFileFfs__(self
, Rule
, InputFileList
, MakefilePath
= None):
859 FfsOutput
= self
.OutputPath
+ \
861 self
.__ExtendMacro
__(Rule
.NameGuid
) + \
864 GenFdsGlobalVariable
.VerboseLogger(self
.__ExtendMacro
__(Rule
.NameGuid
))
866 SectionAlignments
= []
867 for InputFile
in InputFileList
:
868 InputSection
.append(InputFile
)
869 SectionAlignments
.append(Rule
.SectAlignment
)
871 if Rule
.NameGuid
!= None and Rule
.NameGuid
.startswith('PCD('):
872 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
873 if len(PcdValue
) == 0:
874 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
876 if PcdValue
.startswith('{'):
877 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
878 RegistryGuidStr
= PcdValue
879 if len(RegistryGuidStr
) == 0:
880 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
882 self
.ModuleGuid
= RegistryGuidStr
884 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputSection
,
885 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
886 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
887 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
888 SectionAlign
=SectionAlignments
,
889 MakefilePath
=MakefilePath
893 ## __GenComplexFileSection__() method
895 # Generate section by sections in Rule
897 # @param self The object pointer
898 # @param Rule The rule object used to generate section
899 # @param FvChildAddr Array of the inside FvImage base address
900 # @param FvParentAddr Parent Fv base address
901 # @retval string File name of the generated section file
903 def __GenComplexFileSection__(self
, Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
= False):
904 if self
.ModuleType
in ('SEC', 'PEI_CORE', 'PEIM'):
905 if Rule
.KeepReloc
!= None:
906 self
.KeepRelocFromRule
= Rule
.KeepReloc
910 HasGeneratedFlag
= False
911 if self
.PcdIsDriver
== 'PEI_PCD_DRIVER':
912 if self
.IsBinaryModule
:
913 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "PEIPcdDataBase.raw")
915 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "PEIPcdDataBase.raw")
916 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "PEIPcdDataBaseSec.raw")
917 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
920 IsMakefile
= IsMakefile
922 SectFiles
.append(PcdExDbSecName
)
923 SectAlignments
.append(None)
924 elif self
.PcdIsDriver
== 'DXE_PCD_DRIVER':
925 if self
.IsBinaryModule
:
926 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "DXEPcdDataBase.raw")
928 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "DXEPcdDataBase.raw")
929 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "DXEPcdDataBaseSec.raw")
930 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
933 IsMakefile
= IsMakefile
935 SectFiles
.append(PcdExDbSecName
)
936 SectAlignments
.append(None)
937 for Sect
in Rule
.SectionList
:
938 SecIndex
= '%d' %Index
941 # Convert Fv Section Type for PI1.1 SMM driver.
943 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
944 if Sect
.SectionType
== 'DXE_DEPEX':
945 Sect
.SectionType
= 'SMM_DEPEX'
947 # Framework SMM Driver has no SMM_DEPEX section type
949 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
950 if Sect
.SectionType
== 'SMM_DEPEX':
951 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
953 # process the inside FvImage from FvSection or GuidSection
955 if FvChildAddr
!= []:
956 if isinstance(Sect
, FvImageSection
):
957 Sect
.FvAddr
= FvChildAddr
.pop(0)
958 elif isinstance(Sect
, GuidSection
):
959 Sect
.FvAddr
= FvChildAddr
960 if FvParentAddr
!= None and isinstance(Sect
, GuidSection
):
961 Sect
.FvParentAddr
= FvParentAddr
963 if Rule
.KeyStringList
!= []:
964 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, Rule
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
966 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, self
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
968 if not HasGeneratedFlag
:
969 UniVfrOffsetFileSection
= ""
970 ModuleFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
)
971 InfData
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClass(ModuleFileName
), self
.CurrentArch
]
973 # Search the source list in InfData to find if there are .vfr file exist.
976 VfrUniOffsetList
= []
977 for SourceFile
in InfData
.Sources
:
978 if SourceFile
.Type
.upper() == ".VFR" :
980 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
982 VfrUniBaseName
[SourceFile
.BaseName
] = (SourceFile
.BaseName
+ "Bin")
983 if SourceFile
.Type
.upper() == ".UNI" :
985 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
987 VfrUniBaseName
["UniOffsetName"] = (self
.BaseName
+ "Strings")
990 if len(VfrUniBaseName
) > 0:
992 if InfData
.BuildType
!= 'UEFI_HII':
993 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
994 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
995 UniVfrOffsetFileNameList
= []
996 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
997 TrimCmd
= "Trim --Vfr-Uni-Offset -o %s --ModuleName=%s --DebugDir=%s " % (UniVfrOffsetFileName
, self
.BaseName
, self
.EfiDebugPath
)
998 GenFdsGlobalVariable
.SecCmdList
.append(TrimCmd
)
999 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
1000 [UniVfrOffsetFileName
],
1005 VfrUniOffsetList
= self
.__GetBuildOutputMapFileVfrUniInfo
(VfrUniBaseName
)
1007 # Generate the Raw data of raw section
1009 if VfrUniOffsetList
:
1010 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
1011 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
1012 self
.__GenUniVfrOffsetFile
(VfrUniOffsetList
, UniVfrOffsetFileName
)
1013 UniVfrOffsetFileNameList
= []
1014 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
1015 """Call GenSection"""
1017 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
1018 UniVfrOffsetFileNameList
,
1021 #os.remove(UniVfrOffsetFileName)
1022 if UniVfrOffsetFileSection
:
1023 SectList
.append(UniVfrOffsetFileSection
)
1024 HasGeneratedFlag
= True
1026 for SecName
in SectList
:
1027 SectFiles
.append(SecName
)
1028 SectAlignments
.append(Align
)
1030 return SectFiles
, SectAlignments
1032 ## __GenComplexFileFfs__() method
1036 # @param self The object pointer
1037 # @param Rule The rule object used to generate section
1038 # @param InputFileList The output file list from GenSection
1039 # @retval string Generated FFS file name
1041 def __GenComplexFileFfs__(self
, Rule
, InputFile
, Alignments
, MakefilePath
= None):
1043 if Rule
.NameGuid
!= None and Rule
.NameGuid
.startswith('PCD('):
1044 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
1045 if len(PcdValue
) == 0:
1046 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
1048 if PcdValue
.startswith('{'):
1049 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
1050 RegistryGuidStr
= PcdValue
1051 if len(RegistryGuidStr
) == 0:
1052 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
1054 self
.ModuleGuid
= RegistryGuidStr
1056 FfsOutput
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
1057 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputFile
,
1058 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
1059 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
1060 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
1061 SectionAlign
=Alignments
,
1062 MakefilePath
=MakefilePath
1066 ## __GetGenFfsCmdParameter__() method
1068 # Create parameter string for GenFfs
1070 # @param self The object pointer
1071 # @param Rule The rule object used to generate section
1072 # @retval tuple (FileType, Fixed, CheckSum, Alignment)
1074 def __GetGenFfsCmdParameter__(self
, Rule
):
1076 result
+= ('-t', Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
])
1077 if Rule
.Fixed
!= False:
1079 if Rule
.CheckSum
!= False:
1082 if Rule
.Alignment
!= None and Rule
.Alignment
!= '':
1083 result
+= ('-a', Rule
.Alignment
)
1087 ## __GetBuildOutputMapFileVfrUniInfo() method
1089 # Find the offset of UNI/INF object offset in the EFI image file.
1091 # @param self The object pointer
1092 # @param VfrUniBaseName A name list contain the UNI/INF object name.
1093 # @retval RetValue A list contain offset of UNI/INF object.
1095 def __GetBuildOutputMapFileVfrUniInfo(self
, VfrUniBaseName
):
1096 MapFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".map")
1097 EfiFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".efi")
1098 return GetVariableOffset(MapFileName
, EfiFileName
, VfrUniBaseName
.values())
1100 ## __GenUniVfrOffsetFile() method
1102 # Generate the offset file for the module which contain VFR or UNI file.
1104 # @param self The object pointer
1105 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
1106 # @param UniVfrOffsetFileName The output offset file name.
1108 def __GenUniVfrOffsetFile(self
, VfrUniOffsetList
, UniVfrOffsetFileName
):
1110 # Use a instance of StringIO to cache data
1111 fStringIO
= StringIO
.StringIO('')
1113 for Item
in VfrUniOffsetList
:
1114 if (Item
[0].find("Strings") != -1):
1116 # UNI offset in image.
1118 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
1120 UniGuid
= [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
1121 UniGuid
= [chr(ItemGuid
) for ItemGuid
in UniGuid
]
1122 fStringIO
.write(''.join(UniGuid
))
1123 UniValue
= pack ('Q', int (Item
[1], 16))
1124 fStringIO
.write (UniValue
)
1127 # VFR binary offset in image.
1129 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
1131 VfrGuid
= [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
1132 VfrGuid
= [chr(ItemGuid
) for ItemGuid
in VfrGuid
]
1133 fStringIO
.write(''.join(VfrGuid
))
1135 VfrValue
= pack ('Q', int (Item
[1], 16))
1136 fStringIO
.write (VfrValue
)
1139 # write data into file.
1142 SaveFileOnChange(UniVfrOffsetFileName
, fStringIO
.getvalue())
1144 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)