2 # process FFS generation from INF statement
4 # Copyright (c) 2007 - 2017, 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]):
277 DefaultValue
= pcd
[2]
278 BuildOptionOverride
= True
281 if not DscOverride
and not FdfOverride
and not BuildOptionOverride
:
284 # Support Flexible PCD format
287 DefaultValue
= ValueExpressionEx(DefaultValue
, Pcd
.DatumType
, Platform
._GuidDict
)(True)
288 except BadExpression
:
289 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'PCD [%s.%s] Value "%s"' %(Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, DefaultValue
), File
=self
.InfFileName
)
293 Pcd
.DefaultValue
= ValueExpressionEx(Pcd
.DefaultValue
, Pcd
.DatumType
, Platform
._GuidDict
)(True)
294 except BadExpression
:
295 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'PCD [%s.%s] Value "%s"' %(Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, Pcd
.DefaultValue
),File
=self
.InfFileName
)
297 # Check value, if value are equal, no need to patch
298 if Pcd
.DatumType
== "VOID*":
299 if Pcd
.DefaultValue
== DefaultValue
or DefaultValue
in [None, '']:
301 # Get the string size from FDF or DSC
302 if DefaultValue
[0] == 'L':
303 # Remove L"", but the '\0' must be appended
304 MaxDatumSize
= str((len(DefaultValue
) - 2) * 2)
305 elif DefaultValue
[0] == '{':
306 MaxDatumSize
= str(len(DefaultValue
.split(',')))
308 MaxDatumSize
= str(len(DefaultValue
) - 1)
310 Pcd
.MaxDatumSize
= PatchPcd
.MaxDatumSize
311 # If no defined the maximum size in DSC, try to get current size from INF
312 if Pcd
.MaxDatumSize
in ['', None]:
313 Pcd
.MaxDatumSize
= str(len(Pcd
.DefaultValue
.split(',')))
316 if Pcd
.DefaultValue
.upper().startswith('0X'):
318 if DefaultValue
.upper().startswith('0X'):
321 PcdValueInImg
= int(Pcd
.DefaultValue
, Base1
)
322 PcdValueInDscOrFdf
= int(DefaultValue
, Base2
)
323 if PcdValueInImg
== PcdValueInDscOrFdf
:
327 # Check the Pcd size and data type
328 if Pcd
.DatumType
== "VOID*":
329 if int(MaxDatumSize
) > int(Pcd
.MaxDatumSize
):
330 EdkLogger
.error("GenFds", GENFDS_ERROR
, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \
331 % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, int(MaxDatumSize
) - int(Pcd
.MaxDatumSize
)))
333 if PcdValueInDscOrFdf
> FfsInfStatement
._MAX
_SIZE
_TYPE
[Pcd
.DatumType
] \
334 or PcdValueInImg
> FfsInfStatement
._MAX
_SIZE
_TYPE
[Pcd
.DatumType
]:
335 EdkLogger
.error("GenFds", GENFDS_ERROR
, "The size of %s type PCD '%s.%s' doesn't match its data type." \
336 % (Pcd
.DatumType
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
337 self
.PatchPcds
.append((Pcd
, DefaultValue
))
340 self
.PcdIsDriver
= Inf
.PcdIsDriver
341 self
.IsBinaryModule
= Inf
.IsBinaryModule
343 Inf
._GetDepexExpression
()
344 if len(Inf
._Depex
.data
) > 0 and len(Inf
._DepexExpression
.data
) > 0:
347 GenFdsGlobalVariable
.VerboseLogger("BaseName : %s" % self
.BaseName
)
348 GenFdsGlobalVariable
.VerboseLogger("ModuleGuid : %s" % self
.ModuleGuid
)
349 GenFdsGlobalVariable
.VerboseLogger("ModuleType : %s" % self
.ModuleType
)
350 GenFdsGlobalVariable
.VerboseLogger("VersionString : %s" % self
.VersionString
)
351 GenFdsGlobalVariable
.VerboseLogger("InfFileName :%s" % self
.InfFileName
)
354 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\
357 self
.OutputPath
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, \
358 self
.ModuleGuid
+ self
.BaseName
)
359 if not os
.path
.exists(self
.OutputPath
) :
360 os
.makedirs(self
.OutputPath
)
362 self
.EfiOutputPath
, self
.EfiDebugPath
= self
.__GetEFIOutPutPath
__()
363 GenFdsGlobalVariable
.VerboseLogger( "ModuelEFIPath: " + self
.EfiOutputPath
)
367 # Patch EFI file with patch PCD
369 # @param EfiFile: EFI file needs to be patched.
370 # @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name
371 # If passed in file does not end with efi, return as is
373 def PatchEfiFile(self
, EfiFile
, FileType
):
375 # If the module does not have any patches, then return path to input file
377 if not self
.PatchPcds
:
381 # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED
383 if FileType
!= 'PE32' and self
.ModuleType
!= "USER_DEFINED":
387 # Generate path to patched output file
389 Basename
= os
.path
.basename(EfiFile
)
390 Output
= os
.path
.normpath (os
.path
.join(self
.OutputPath
, Basename
))
393 # If this file has already been patched, then return the path to the patched file
395 if self
.PatchedBinFile
== Output
:
399 # If a different file from the same module has already been patched, then generate an error
401 if self
.PatchedBinFile
:
402 EdkLogger
.error("GenFds", GENFDS_ERROR
,
403 'Only one binary file can be patched:\n'
404 ' a binary file has been patched: %s\n'
405 ' current file: %s' % (self
.PatchedBinFile
, EfiFile
),
406 File
=self
.InfFileName
)
409 # Copy unpatched file contents to output file location to perform patching
411 CopyLongFilePath(EfiFile
, Output
)
414 # Apply patches to patched output file
416 for Pcd
, Value
in self
.PatchPcds
:
417 RetVal
, RetStr
= PatchBinaryFile(Output
, int(Pcd
.Offset
, 0), Pcd
.DatumType
, Value
, Pcd
.MaxDatumSize
)
419 EdkLogger
.error("GenFds", GENFDS_ERROR
, RetStr
, File
=self
.InfFileName
)
422 # Save the path of the patched output file
424 self
.PatchedBinFile
= Output
427 # Return path to patched output file
435 # @param self The object pointer
436 # @param Dict dictionary contains macro and value pair
437 # @param FvChildAddr Array of the inside FvImage base address
438 # @param FvParentAddr Parent Fv base address
439 # @retval string Generated FFS file name
441 def GenFfs(self
, Dict
= {}, FvChildAddr
= [], FvParentAddr
=None, IsMakefile
=False, FvName
=None):
443 # Parse Inf file get Module related information
446 self
.__InfParse
__(Dict
)
447 Arch
= self
.GetCurrentArch()
448 SrcFile
= mws
.join( GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
);
449 DestFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
452 SrcPath
= os
.path
.dirname(SrcFile
)
453 SrcFileName
= os
.path
.basename(SrcFile
)
454 SrcFileBase
, SrcFileExt
= os
.path
.splitext(SrcFileName
)
455 DestPath
= os
.path
.dirname(DestFile
)
456 DestFileName
= os
.path
.basename(DestFile
)
457 DestFileBase
, DestFileExt
= os
.path
.splitext(DestFileName
)
461 "${s_path}" : SrcPath
,
462 "${s_dir}" : SrcFileDir
,
463 "${s_name}" : SrcFileName
,
464 "${s_base}" : SrcFileBase
,
465 "${s_ext}" : SrcFileExt
,
468 "${d_path}" : DestPath
,
469 "${d_name}" : DestFileName
,
470 "${d_base}" : DestFileBase
,
471 "${d_ext}" : DestFileExt
474 # Allow binary type module not specify override rule in FDF file.
476 if len(self
.BinFileList
) > 0:
477 if self
.Rule
== None or self
.Rule
== "":
480 if not IsMakefile
and GenFdsGlobalVariable
.EnableGenfdsMultiThread
and self
.Rule
!= 'BINARY':
483 # Get the rule of how to generate Ffs file
485 Rule
= self
.__GetRule
__()
486 GenFdsGlobalVariable
.VerboseLogger( "Packing binaries from inf file : %s" %self
.InfFileName
)
488 # Convert Fv File Type for PI1.1 SMM driver.
490 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
491 if Rule
.FvFileType
== 'DRIVER':
492 Rule
.FvFileType
= 'SMM'
494 # Framework SMM Driver has no SMM FV file type
496 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
497 if Rule
.FvFileType
== 'SMM' or Rule
.FvFileType
== 'SMM_CORE':
498 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File
=self
.InfFileName
)
500 # For the rule only has simpleFile
504 MakefilePath
= self
.InfFileName
, Arch
505 if isinstance (Rule
, RuleSimpleFile
.RuleSimpleFile
) :
506 SectionOutputList
= self
.__GenSimpleFileSection
__(Rule
, IsMakefile
=IsMakefile
)
507 FfsOutput
= self
.__GenSimpleFileFfs
__(Rule
, SectionOutputList
, MakefilePath
=MakefilePath
)
510 # For Rule has ComplexFile
512 elif isinstance(Rule
, RuleComplexFile
.RuleComplexFile
):
513 InputSectList
, InputSectAlignments
= self
.__GenComplexFileSection
__(Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
=IsMakefile
)
514 FfsOutput
= self
.__GenComplexFileFfs
__(Rule
, InputSectList
, InputSectAlignments
, MakefilePath
=MakefilePath
)
517 ## __ExtendMacro__() method
519 # Replace macro with its value
521 # @param self The object pointer
522 # @param String The string to be replaced
523 # @retval string Macro replaced string
525 def __ExtendMacro__ (self
, String
):
527 '$(INF_OUTPUT)' : self
.EfiOutputPath
,
528 '$(MODULE_NAME)' : self
.BaseName
,
529 '$(BUILD_NUMBER)': self
.BuildNum
,
530 '$(INF_VERSION)' : self
.VersionString
,
531 '$(NAMED_GUID)' : self
.ModuleGuid
533 String
= GenFdsGlobalVariable
.MacroExtend(String
, MacroDict
)
534 String
= GenFdsGlobalVariable
.MacroExtend(String
, self
.MacroDict
)
537 ## __GetRule__() method
539 # Get correct rule for generating FFS for this INF
541 # @param self The object pointer
542 # @retval Rule Rule object
544 def __GetRule__ (self
) :
546 if self
.CurrentArch
== None:
547 CurrentArchList
= ['common']
549 CurrentArchList
.append(self
.CurrentArch
)
551 for CurrentArch
in CurrentArchList
:
552 RuleName
= 'RULE' + \
554 CurrentArch
.upper() + \
556 self
.ModuleType
.upper()
557 if self
.Rule
!= None:
558 RuleName
= RuleName
+ \
562 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
564 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
567 RuleName
= 'RULE' + \
571 self
.ModuleType
.upper()
573 if self
.Rule
!= None:
574 RuleName
= RuleName
+ \
578 GenFdsGlobalVariable
.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName
, self
.InfFileName
))
580 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
582 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
586 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'Don\'t Find common rule %s for INF %s' \
587 % (RuleName
, self
.InfFileName
))
589 ## __GetPlatformArchList__() method
591 # Get Arch list this INF built under
593 # @param self The object pointer
594 # @retval list Arch list
596 def __GetPlatformArchList__(self
):
598 InfFileKey
= os
.path
.normpath(mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
))
600 for Arch
in GenFdsGlobalVariable
.ArchList
:
601 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
602 if PlatformDataBase
!= None:
603 if InfFileKey
in PlatformDataBase
.Modules
:
604 DscArchList
.append (Arch
)
607 # BaseTools support build same module more than once, the module path with FILE_GUID overridden has
608 # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key,
609 # but the path (self.MetaFile.Path) is the real path
611 for key
in PlatformDataBase
.Modules
.keys():
612 if InfFileKey
== str((PlatformDataBase
.Modules
[key
]).MetaFile
.Path
):
613 DscArchList
.append (Arch
)
618 ## GetCurrentArch() method
620 # Get Arch list of the module from this INF is to be placed into flash
622 # @param self The object pointer
623 # @retval list Arch list
625 def GetCurrentArch(self
) :
627 TargetArchList
= GenFdsGlobalVariable
.ArchList
629 PlatformArchList
= self
.__GetPlatformArchList
__()
631 CurArchList
= TargetArchList
632 if PlatformArchList
!= []:
633 CurArchList
= list(set (TargetArchList
) & set (PlatformArchList
))
634 GenFdsGlobalVariable
.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList
))
637 if self
.KeyStringList
!= []:
638 for Key
in self
.KeyStringList
:
639 Key
= GenFdsGlobalVariable
.MacroExtend(Key
)
640 Target
, Tag
, Arch
= Key
.split('_')
641 if Arch
in CurArchList
:
642 ArchList
.append(Arch
)
643 if Target
not in self
.TargetOverrideList
:
644 self
.TargetOverrideList
.append(Target
)
646 ArchList
= CurArchList
648 UseArchList
= TargetArchList
649 if self
.UseArch
!= None:
651 UseArchList
.append(self
.UseArch
)
652 ArchList
= list(set (UseArchList
) & set (ArchList
))
654 self
.InfFileName
= NormPath(self
.InfFileName
)
655 if len(PlatformArchList
) == 0:
657 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
658 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
660 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
661 if len(ArchList
) == 1:
664 elif len(ArchList
) > 1:
665 if len(PlatformArchList
) == 0:
666 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
))
668 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
))
670 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." \
671 % (self
.InfFileName
, str(PlatformArchList
), GenFdsGlobalVariable
.ActivePlatform
, str(set (UseArchList
) & set (TargetArchList
))))
673 ## __GetEFIOutPutPath__() method
675 # Get the output path for generated files
677 # @param self The object pointer
678 # @retval string Path that output files from this INF go to
680 def __GetEFIOutPutPath__(self
):
684 (ModulePath
, FileName
) = os
.path
.split(self
.InfFileName
)
685 Index
= FileName
.rfind('.')
686 FileName
= FileName
[0:Index
]
687 if self
.OverrideGuid
:
688 FileName
= self
.OverrideGuid
690 if self
.CurrentArch
!= None:
691 Arch
= self
.CurrentArch
693 OutputPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
699 DebugPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
705 OutputPath
= os
.path
.realpath(OutputPath
)
706 DebugPath
= os
.path
.realpath(DebugPath
)
707 return OutputPath
, DebugPath
709 ## __GenSimpleFileSection__() method
711 # Generate section by specified file name or a list of files with file extension
713 # @param self The object pointer
714 # @param Rule The rule object used to generate section
715 # @retval string File name of the generated section file
717 def __GenSimpleFileSection__(self
, Rule
, IsMakefile
= False):
719 # Prepare the parameter of GenSection
723 GenSecInputFile
= None
724 if Rule
.FileName
!= None:
725 GenSecInputFile
= self
.__ExtendMacro
__(Rule
.FileName
)
726 if os
.path
.isabs(GenSecInputFile
):
727 GenSecInputFile
= os
.path
.normpath(GenSecInputFile
)
729 GenSecInputFile
= os
.path
.normpath(os
.path
.join(self
.EfiOutputPath
, GenSecInputFile
))
731 FileList
, IsSect
= Section
.Section
.GetFileList(self
, '', Rule
.FileExtension
)
734 SectionType
= Rule
.SectionType
736 # Convert Fv Section Type for PI1.1 SMM driver.
738 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
739 if SectionType
== 'DXE_DEPEX':
740 SectionType
= 'SMM_DEPEX'
742 # Framework SMM Driver has no SMM_DEPEX section type
744 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
745 if SectionType
== 'SMM_DEPEX':
746 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
748 if self
.ModuleType
in ('SEC', 'PEI_CORE', 'PEIM'):
749 if self
.KeepReloc
!= None:
750 NoStrip
= self
.KeepReloc
751 elif Rule
.KeepReloc
!= None:
752 NoStrip
= Rule
.KeepReloc
753 elif self
.ShadowFromInfFile
!= None:
754 NoStrip
= self
.ShadowFromInfFile
757 for File
in FileList
:
760 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
761 Ffs
.Ffs
.SectionSuffix
[SectionType
] + 'SEC' + SecNum
763 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
764 File
= GenFdsGlobalVariable
.MacroExtend(File
, Dict
, self
.CurrentArch
)
766 #Get PE Section alignment when align is set to AUTO
767 if self
.Alignment
== 'Auto' and (SectionType
== 'PE32' or SectionType
== 'TE'):
768 ImageObj
= PeImageClass (File
)
769 if ImageObj
.SectionAlignment
< 0x400:
770 self
.Alignment
= str (ImageObj
.SectionAlignment
)
771 elif ImageObj
.SectionAlignment
< 0x100000:
772 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
774 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x100000) + 'M'
777 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
778 if not os
.path
.exists(FileBeforeStrip
) or \
779 (os
.path
.getmtime(File
) > os
.path
.getmtime(FileBeforeStrip
)):
780 CopyLongFilePath(File
, FileBeforeStrip
)
781 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
782 GenFdsGlobalVariable
.GenerateFirmwareImage(
786 IsMakefile
=IsMakefile
790 if SectionType
== 'TE':
791 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
792 GenFdsGlobalVariable
.GenerateFirmwareImage(
796 IsMakefile
=IsMakefile
799 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [File
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
800 OutputFileList
.append(OutputFile
)
803 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
804 Ffs
.Ffs
.SectionSuffix
[SectionType
] + 'SEC' + SecNum
805 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
806 GenSecInputFile
= GenFdsGlobalVariable
.MacroExtend(GenSecInputFile
, Dict
, self
.CurrentArch
)
808 #Get PE Section alignment when align is set to AUTO
809 if self
.Alignment
== 'Auto' and (SectionType
== 'PE32' or SectionType
== 'TE'):
810 ImageObj
= PeImageClass (GenSecInputFile
)
811 if ImageObj
.SectionAlignment
< 0x400:
812 self
.Alignment
= str (ImageObj
.SectionAlignment
)
813 elif ImageObj
.SectionAlignment
< 0x100000:
814 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
816 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x100000) + 'M'
819 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
820 if not os
.path
.exists(FileBeforeStrip
) or \
821 (os
.path
.getmtime(GenSecInputFile
) > os
.path
.getmtime(FileBeforeStrip
)):
822 CopyLongFilePath(GenSecInputFile
, FileBeforeStrip
)
824 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
825 GenFdsGlobalVariable
.GenerateFirmwareImage(
829 IsMakefile
=IsMakefile
831 GenSecInputFile
= StrippedFile
833 if SectionType
== 'TE':
834 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
835 GenFdsGlobalVariable
.GenerateFirmwareImage(
839 IsMakefile
=IsMakefile
841 GenSecInputFile
= TeFile
842 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [GenSecInputFile
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
843 OutputFileList
.append(OutputFile
)
845 return OutputFileList
847 ## __GenSimpleFileFfs__() method
851 # @param self The object pointer
852 # @param Rule The rule object used to generate section
853 # @param InputFileList The output file list from GenSection
854 # @retval string Generated FFS file name
856 def __GenSimpleFileFfs__(self
, Rule
, InputFileList
, MakefilePath
= None):
857 FfsOutput
= self
.OutputPath
+ \
859 self
.__ExtendMacro
__(Rule
.NameGuid
) + \
862 GenFdsGlobalVariable
.VerboseLogger(self
.__ExtendMacro
__(Rule
.NameGuid
))
864 SectionAlignments
= []
865 for InputFile
in InputFileList
:
866 InputSection
.append(InputFile
)
867 SectionAlignments
.append(Rule
.SectAlignment
)
869 if Rule
.NameGuid
!= None and Rule
.NameGuid
.startswith('PCD('):
870 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
871 if len(PcdValue
) == 0:
872 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
874 if PcdValue
.startswith('{'):
875 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
876 RegistryGuidStr
= PcdValue
877 if len(RegistryGuidStr
) == 0:
878 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
880 self
.ModuleGuid
= RegistryGuidStr
882 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputSection
,
883 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
884 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
885 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
886 SectionAlign
=SectionAlignments
,
887 MakefilePath
=MakefilePath
891 ## __GenComplexFileSection__() method
893 # Generate section by sections in Rule
895 # @param self The object pointer
896 # @param Rule The rule object used to generate section
897 # @param FvChildAddr Array of the inside FvImage base address
898 # @param FvParentAddr Parent Fv base address
899 # @retval string File name of the generated section file
901 def __GenComplexFileSection__(self
, Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
= False):
902 if self
.ModuleType
in ('SEC', 'PEI_CORE', 'PEIM'):
903 if Rule
.KeepReloc
!= None:
904 self
.KeepRelocFromRule
= Rule
.KeepReloc
908 HasGeneratedFlag
= False
909 if self
.PcdIsDriver
== 'PEI_PCD_DRIVER':
910 if self
.IsBinaryModule
:
911 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "PEIPcdDataBase.raw")
913 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "PEIPcdDataBase.raw")
914 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "PEIPcdDataBaseSec.raw")
915 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
918 IsMakefile
= IsMakefile
920 SectFiles
.append(PcdExDbSecName
)
921 SectAlignments
.append(None)
922 elif self
.PcdIsDriver
== 'DXE_PCD_DRIVER':
923 if self
.IsBinaryModule
:
924 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "DXEPcdDataBase.raw")
926 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "DXEPcdDataBase.raw")
927 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "DXEPcdDataBaseSec.raw")
928 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
931 IsMakefile
= IsMakefile
933 SectFiles
.append(PcdExDbSecName
)
934 SectAlignments
.append(None)
935 for Sect
in Rule
.SectionList
:
936 SecIndex
= '%d' %Index
939 # Convert Fv Section Type for PI1.1 SMM driver.
941 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
942 if Sect
.SectionType
== 'DXE_DEPEX':
943 Sect
.SectionType
= 'SMM_DEPEX'
945 # Framework SMM Driver has no SMM_DEPEX section type
947 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
948 if Sect
.SectionType
== 'SMM_DEPEX':
949 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
951 # process the inside FvImage from FvSection or GuidSection
953 if FvChildAddr
!= []:
954 if isinstance(Sect
, FvImageSection
):
955 Sect
.FvAddr
= FvChildAddr
.pop(0)
956 elif isinstance(Sect
, GuidSection
):
957 Sect
.FvAddr
= FvChildAddr
958 if FvParentAddr
!= None and isinstance(Sect
, GuidSection
):
959 Sect
.FvParentAddr
= FvParentAddr
961 if Rule
.KeyStringList
!= []:
962 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, Rule
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
964 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, self
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
966 if not HasGeneratedFlag
:
967 UniVfrOffsetFileSection
= ""
968 ModuleFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
)
969 InfData
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClass(ModuleFileName
), self
.CurrentArch
]
971 # Search the source list in InfData to find if there are .vfr file exist.
974 VfrUniOffsetList
= []
975 for SourceFile
in InfData
.Sources
:
976 if SourceFile
.Type
.upper() == ".VFR" :
978 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
980 VfrUniBaseName
[SourceFile
.BaseName
] = (SourceFile
.BaseName
+ "Bin")
981 if SourceFile
.Type
.upper() == ".UNI" :
983 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
985 VfrUniBaseName
["UniOffsetName"] = (self
.BaseName
+ "Strings")
988 if len(VfrUniBaseName
) > 0:
990 if InfData
.BuildType
!= 'UEFI_HII':
991 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
992 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
993 UniVfrOffsetFileNameList
= []
994 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
995 TrimCmd
= "Trim --Vfr-Uni-Offset -o %s --ModuleName=%s --DebugDir=%s " % (UniVfrOffsetFileName
, self
.BaseName
, self
.EfiDebugPath
)
996 GenFdsGlobalVariable
.SecCmdList
.append(TrimCmd
)
997 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
998 [UniVfrOffsetFileName
],
1003 VfrUniOffsetList
= self
.__GetBuildOutputMapFileVfrUniInfo
(VfrUniBaseName
)
1005 # Generate the Raw data of raw section
1007 if VfrUniOffsetList
:
1008 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
1009 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
1010 self
.__GenUniVfrOffsetFile
(VfrUniOffsetList
, UniVfrOffsetFileName
)
1011 UniVfrOffsetFileNameList
= []
1012 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
1013 """Call GenSection"""
1015 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
1016 UniVfrOffsetFileNameList
,
1019 #os.remove(UniVfrOffsetFileName)
1020 if UniVfrOffsetFileSection
:
1021 SectList
.append(UniVfrOffsetFileSection
)
1022 HasGeneratedFlag
= True
1024 for SecName
in SectList
:
1025 SectFiles
.append(SecName
)
1026 SectAlignments
.append(Align
)
1028 return SectFiles
, SectAlignments
1030 ## __GenComplexFileFfs__() method
1034 # @param self The object pointer
1035 # @param Rule The rule object used to generate section
1036 # @param InputFileList The output file list from GenSection
1037 # @retval string Generated FFS file name
1039 def __GenComplexFileFfs__(self
, Rule
, InputFile
, Alignments
, MakefilePath
= None):
1041 if Rule
.NameGuid
!= None and Rule
.NameGuid
.startswith('PCD('):
1042 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
1043 if len(PcdValue
) == 0:
1044 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
1046 if PcdValue
.startswith('{'):
1047 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
1048 RegistryGuidStr
= PcdValue
1049 if len(RegistryGuidStr
) == 0:
1050 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
1052 self
.ModuleGuid
= RegistryGuidStr
1054 FfsOutput
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
1055 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputFile
,
1056 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
1057 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
1058 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
1059 SectionAlign
=Alignments
,
1060 MakefilePath
=MakefilePath
1064 ## __GetGenFfsCmdParameter__() method
1066 # Create parameter string for GenFfs
1068 # @param self The object pointer
1069 # @param Rule The rule object used to generate section
1070 # @retval tuple (FileType, Fixed, CheckSum, Alignment)
1072 def __GetGenFfsCmdParameter__(self
, Rule
):
1074 result
+= ('-t', Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
])
1075 if Rule
.Fixed
!= False:
1077 if Rule
.CheckSum
!= False:
1080 if Rule
.Alignment
!= None and Rule
.Alignment
!= '':
1081 result
+= ('-a', Rule
.Alignment
)
1085 ## __GetBuildOutputMapFileVfrUniInfo() method
1087 # Find the offset of UNI/INF object offset in the EFI image file.
1089 # @param self The object pointer
1090 # @param VfrUniBaseName A name list contain the UNI/INF object name.
1091 # @retval RetValue A list contain offset of UNI/INF object.
1093 def __GetBuildOutputMapFileVfrUniInfo(self
, VfrUniBaseName
):
1094 MapFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".map")
1095 EfiFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".efi")
1096 return GetVariableOffset(MapFileName
, EfiFileName
, VfrUniBaseName
.values())
1098 ## __GenUniVfrOffsetFile() method
1100 # Generate the offset file for the module which contain VFR or UNI file.
1102 # @param self The object pointer
1103 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
1104 # @param UniVfrOffsetFileName The output offset file name.
1106 def __GenUniVfrOffsetFile(self
, VfrUniOffsetList
, UniVfrOffsetFileName
):
1108 # Use a instance of StringIO to cache data
1109 fStringIO
= StringIO
.StringIO('')
1111 for Item
in VfrUniOffsetList
:
1112 if (Item
[0].find("Strings") != -1):
1114 # UNI offset in image.
1116 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
1118 UniGuid
= [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
1119 UniGuid
= [chr(ItemGuid
) for ItemGuid
in UniGuid
]
1120 fStringIO
.write(''.join(UniGuid
))
1121 UniValue
= pack ('Q', int (Item
[1], 16))
1122 fStringIO
.write (UniValue
)
1125 # VFR binary offset in image.
1127 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
1129 VfrGuid
= [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
1130 VfrGuid
= [chr(ItemGuid
) for ItemGuid
in VfrGuid
]
1131 fStringIO
.write(''.join(VfrGuid
))
1133 VfrValue
= pack ('Q', int (Item
[1], 16))
1134 fStringIO
.write (VfrValue
)
1137 # write data into file.
1140 SaveFileOnChange(UniVfrOffsetFileName
, fStringIO
.getvalue())
1142 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)