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
50 ## generate FFS from INF
53 class FfsInfStatement(FfsInfStatementClassObject
):
54 ## The mapping dictionary from datum type to its maximum number.
55 _MAX_SIZE_TYPE
= {"BOOLEAN":0x01, "UINT8":0xFF, "UINT16":0xFFFF, "UINT32":0xFFFFFFFF, "UINT64":0xFFFFFFFFFFFFFFFF}
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
!= "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
!= 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
!= 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
== None and Inf
.Shadow
:
204 self
.ShadowFromInfFile
= Inf
.Shadow
207 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, 'COMMON', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
208 self
.BaseName
= Inf
.BaseName
209 self
.ModuleGuid
= Inf
.Guid
210 self
.ModuleType
= Inf
.ModuleType
211 if Inf
.Specification
!= 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
== '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
== '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
!= 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
!= 'PatchableInModule':
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]):
276 DefaultValue
= pcd
[2]
277 BuildOptionOverride
= True
280 if not DscOverride
and not FdfOverride
and not BuildOptionOverride
:
282 # Check value, if value are equal, no need to patch
283 if Pcd
.DatumType
== "VOID*":
284 if Pcd
.DefaultValue
== DefaultValue
or DefaultValue
in [None, '']:
286 # Get the string size from FDF or DSC
287 if DefaultValue
[0] == 'L':
288 # Remove L"", but the '\0' must be appended
289 MaxDatumSize
= str((len(DefaultValue
) - 2) * 2)
290 elif DefaultValue
[0] == '{':
291 MaxDatumSize
= str(len(DefaultValue
.split(',')))
293 MaxDatumSize
= str(len(DefaultValue
) - 1)
295 Pcd
.MaxDatumSize
= PatchPcd
.MaxDatumSize
296 # If no defined the maximum size in DSC, try to get current size from INF
297 if Pcd
.MaxDatumSize
in ['', None]:
298 Pcd
.MaxDatumSize
= str(len(Pcd
.DefaultValue
.split(',')))
301 if Pcd
.DefaultValue
.upper().startswith('0X'):
303 if DefaultValue
.upper().startswith('0X'):
306 PcdValueInImg
= int(Pcd
.DefaultValue
, Base1
)
307 PcdValueInDscOrFdf
= int(DefaultValue
, Base2
)
308 if PcdValueInImg
== PcdValueInDscOrFdf
:
312 # Check the Pcd size and data type
313 if Pcd
.DatumType
== "VOID*":
314 if int(MaxDatumSize
) > int(Pcd
.MaxDatumSize
):
315 EdkLogger
.error("GenFds", GENFDS_ERROR
, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \
316 % (Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
, int(MaxDatumSize
) - int(Pcd
.MaxDatumSize
)))
318 if PcdValueInDscOrFdf
> FfsInfStatement
._MAX
_SIZE
_TYPE
[Pcd
.DatumType
] \
319 or PcdValueInImg
> FfsInfStatement
._MAX
_SIZE
_TYPE
[Pcd
.DatumType
]:
320 EdkLogger
.error("GenFds", GENFDS_ERROR
, "The size of %s type PCD '%s.%s' doesn't match its data type." \
321 % (Pcd
.DatumType
, Pcd
.TokenSpaceGuidCName
, Pcd
.TokenCName
))
322 self
.PatchPcds
.append((Pcd
, DefaultValue
))
325 self
.PcdIsDriver
= Inf
.PcdIsDriver
326 self
.IsBinaryModule
= Inf
.IsBinaryModule
328 Inf
._GetDepexExpression
()
329 if len(Inf
._Depex
.data
) > 0 and len(Inf
._DepexExpression
.data
) > 0:
332 GenFdsGlobalVariable
.VerboseLogger("BaseName : %s" % self
.BaseName
)
333 GenFdsGlobalVariable
.VerboseLogger("ModuleGuid : %s" % self
.ModuleGuid
)
334 GenFdsGlobalVariable
.VerboseLogger("ModuleType : %s" % self
.ModuleType
)
335 GenFdsGlobalVariable
.VerboseLogger("VersionString : %s" % self
.VersionString
)
336 GenFdsGlobalVariable
.VerboseLogger("InfFileName :%s" % self
.InfFileName
)
339 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\
342 self
.OutputPath
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, \
343 self
.ModuleGuid
+ self
.BaseName
)
344 if not os
.path
.exists(self
.OutputPath
) :
345 os
.makedirs(self
.OutputPath
)
347 self
.EfiOutputPath
, self
.EfiDebugPath
= self
.__GetEFIOutPutPath
__()
348 GenFdsGlobalVariable
.VerboseLogger( "ModuelEFIPath: " + self
.EfiOutputPath
)
352 # Patch EFI file with patch PCD
354 # @param EfiFile: EFI file needs to be patched.
355 # @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name
356 # If passed in file does not end with efi, return as is
358 def PatchEfiFile(self
, EfiFile
, FileType
):
360 # If the module does not have any patches, then return path to input file
362 if not self
.PatchPcds
:
366 # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED
368 if FileType
!= 'PE32' and self
.ModuleType
!= "USER_DEFINED":
372 # Generate path to patched output file
374 Basename
= os
.path
.basename(EfiFile
)
375 Output
= os
.path
.normpath (os
.path
.join(self
.OutputPath
, Basename
))
378 # If this file has already been patched, then return the path to the patched file
380 if self
.PatchedBinFile
== Output
:
384 # If a different file from the same module has already been patched, then generate an error
386 if self
.PatchedBinFile
:
387 EdkLogger
.error("GenFds", GENFDS_ERROR
,
388 'Only one binary file can be patched:\n'
389 ' a binary file has been patched: %s\n'
390 ' current file: %s' % (self
.PatchedBinFile
, EfiFile
),
391 File
=self
.InfFileName
)
394 # Copy unpatched file contents to output file location to perform patching
396 CopyLongFilePath(EfiFile
, Output
)
399 # Apply patches to patched output file
401 for Pcd
, Value
in self
.PatchPcds
:
402 RetVal
, RetStr
= PatchBinaryFile(Output
, int(Pcd
.Offset
, 0), Pcd
.DatumType
, Value
, Pcd
.MaxDatumSize
)
404 EdkLogger
.error("GenFds", GENFDS_ERROR
, RetStr
, File
=self
.InfFileName
)
407 # Save the path of the patched output file
409 self
.PatchedBinFile
= Output
412 # Return path to patched output file
420 # @param self The object pointer
421 # @param Dict dictionary contains macro and value pair
422 # @param FvChildAddr Array of the inside FvImage base address
423 # @param FvParentAddr Parent Fv base address
424 # @retval string Generated FFS file name
426 def GenFfs(self
, Dict
= {}, FvChildAddr
= [], FvParentAddr
=None, IsMakefile
=False, FvName
=None):
428 # Parse Inf file get Module related information
431 self
.__InfParse
__(Dict
)
432 Arch
= self
.GetCurrentArch()
433 SrcFile
= mws
.join( GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
);
434 DestFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
437 SrcPath
= os
.path
.dirname(SrcFile
)
438 SrcFileName
= os
.path
.basename(SrcFile
)
439 SrcFileBase
, SrcFileExt
= os
.path
.splitext(SrcFileName
)
440 DestPath
= os
.path
.dirname(DestFile
)
441 DestFileName
= os
.path
.basename(DestFile
)
442 DestFileBase
, DestFileExt
= os
.path
.splitext(DestFileName
)
446 "${s_path}" : SrcPath
,
447 "${s_dir}" : SrcFileDir
,
448 "${s_name}" : SrcFileName
,
449 "${s_base}" : SrcFileBase
,
450 "${s_ext}" : SrcFileExt
,
453 "${d_path}" : DestPath
,
454 "${d_name}" : DestFileName
,
455 "${d_base}" : DestFileBase
,
456 "${d_ext}" : DestFileExt
459 # Allow binary type module not specify override rule in FDF file.
461 if len(self
.BinFileList
) > 0:
462 if self
.Rule
== None or self
.Rule
== "":
465 if not IsMakefile
and GenFdsGlobalVariable
.EnableGenfdsMultiThread
and self
.Rule
!= 'BINARY':
468 # Get the rule of how to generate Ffs file
470 Rule
= self
.__GetRule
__()
471 GenFdsGlobalVariable
.VerboseLogger( "Packing binaries from inf file : %s" %self
.InfFileName
)
473 # Convert Fv File Type for PI1.1 SMM driver.
475 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
476 if Rule
.FvFileType
== 'DRIVER':
477 Rule
.FvFileType
= 'SMM'
479 # Framework SMM Driver has no SMM FV file type
481 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
482 if Rule
.FvFileType
== 'SMM' or Rule
.FvFileType
== 'SMM_CORE':
483 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File
=self
.InfFileName
)
485 # For the rule only has simpleFile
489 MakefilePath
= self
.InfFileName
, Arch
490 if isinstance (Rule
, RuleSimpleFile
.RuleSimpleFile
) :
491 SectionOutputList
= self
.__GenSimpleFileSection
__(Rule
, IsMakefile
=IsMakefile
)
492 FfsOutput
= self
.__GenSimpleFileFfs
__(Rule
, SectionOutputList
, MakefilePath
=MakefilePath
)
495 # For Rule has ComplexFile
497 elif isinstance(Rule
, RuleComplexFile
.RuleComplexFile
):
498 InputSectList
, InputSectAlignments
= self
.__GenComplexFileSection
__(Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
=IsMakefile
)
499 FfsOutput
= self
.__GenComplexFileFfs
__(Rule
, InputSectList
, InputSectAlignments
, MakefilePath
=MakefilePath
)
502 ## __ExtendMacro__() method
504 # Replace macro with its value
506 # @param self The object pointer
507 # @param String The string to be replaced
508 # @retval string Macro replaced string
510 def __ExtendMacro__ (self
, String
):
512 '$(INF_OUTPUT)' : self
.EfiOutputPath
,
513 '$(MODULE_NAME)' : self
.BaseName
,
514 '$(BUILD_NUMBER)': self
.BuildNum
,
515 '$(INF_VERSION)' : self
.VersionString
,
516 '$(NAMED_GUID)' : self
.ModuleGuid
518 String
= GenFdsGlobalVariable
.MacroExtend(String
, MacroDict
)
519 String
= GenFdsGlobalVariable
.MacroExtend(String
, self
.MacroDict
)
522 ## __GetRule__() method
524 # Get correct rule for generating FFS for this INF
526 # @param self The object pointer
527 # @retval Rule Rule object
529 def __GetRule__ (self
) :
531 if self
.CurrentArch
== None:
532 CurrentArchList
= ['common']
534 CurrentArchList
.append(self
.CurrentArch
)
536 for CurrentArch
in CurrentArchList
:
537 RuleName
= 'RULE' + \
539 CurrentArch
.upper() + \
541 self
.ModuleType
.upper()
542 if self
.Rule
!= None:
543 RuleName
= RuleName
+ \
547 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
549 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
552 RuleName
= 'RULE' + \
556 self
.ModuleType
.upper()
558 if self
.Rule
!= None:
559 RuleName
= RuleName
+ \
563 GenFdsGlobalVariable
.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName
, self
.InfFileName
))
565 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
567 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
571 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'Don\'t Find common rule %s for INF %s' \
572 % (RuleName
, self
.InfFileName
))
574 ## __GetPlatformArchList__() method
576 # Get Arch list this INF built under
578 # @param self The object pointer
579 # @retval list Arch list
581 def __GetPlatformArchList__(self
):
583 InfFileKey
= os
.path
.normpath(mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
))
585 for Arch
in GenFdsGlobalVariable
.ArchList
:
586 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, Arch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
587 if PlatformDataBase
!= None:
588 if InfFileKey
in PlatformDataBase
.Modules
:
589 DscArchList
.append (Arch
)
592 # BaseTools support build same module more than once, the module path with FILE_GUID overridden has
593 # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key,
594 # but the path (self.MetaFile.Path) is the real path
596 for key
in PlatformDataBase
.Modules
.keys():
597 if InfFileKey
== str((PlatformDataBase
.Modules
[key
]).MetaFile
.Path
):
598 DscArchList
.append (Arch
)
603 ## GetCurrentArch() method
605 # Get Arch list of the module from this INF is to be placed into flash
607 # @param self The object pointer
608 # @retval list Arch list
610 def GetCurrentArch(self
) :
612 TargetArchList
= GenFdsGlobalVariable
.ArchList
614 PlatformArchList
= self
.__GetPlatformArchList
__()
616 CurArchList
= TargetArchList
617 if PlatformArchList
!= []:
618 CurArchList
= list(set (TargetArchList
) & set (PlatformArchList
))
619 GenFdsGlobalVariable
.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList
))
622 if self
.KeyStringList
!= []:
623 for Key
in self
.KeyStringList
:
624 Key
= GenFdsGlobalVariable
.MacroExtend(Key
)
625 Target
, Tag
, Arch
= Key
.split('_')
626 if Arch
in CurArchList
:
627 ArchList
.append(Arch
)
628 if Target
not in self
.TargetOverrideList
:
629 self
.TargetOverrideList
.append(Target
)
631 ArchList
= CurArchList
633 UseArchList
= TargetArchList
634 if self
.UseArch
!= None:
636 UseArchList
.append(self
.UseArch
)
637 ArchList
= list(set (UseArchList
) & set (ArchList
))
639 self
.InfFileName
= NormPath(self
.InfFileName
)
640 if len(PlatformArchList
) == 0:
642 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
643 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
645 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
646 if len(ArchList
) == 1:
649 elif len(ArchList
) > 1:
650 if len(PlatformArchList
) == 0:
651 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
))
653 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
))
655 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." \
656 % (self
.InfFileName
, str(PlatformArchList
), GenFdsGlobalVariable
.ActivePlatform
, str(set (UseArchList
) & set (TargetArchList
))))
658 ## __GetEFIOutPutPath__() method
660 # Get the output path for generated files
662 # @param self The object pointer
663 # @retval string Path that output files from this INF go to
665 def __GetEFIOutPutPath__(self
):
669 (ModulePath
, FileName
) = os
.path
.split(self
.InfFileName
)
670 Index
= FileName
.rfind('.')
671 FileName
= FileName
[0:Index
]
672 if self
.OverrideGuid
:
673 FileName
= self
.OverrideGuid
675 if self
.CurrentArch
!= None:
676 Arch
= self
.CurrentArch
678 OutputPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
684 DebugPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
690 OutputPath
= os
.path
.realpath(OutputPath
)
691 DebugPath
= os
.path
.realpath(DebugPath
)
692 return OutputPath
, DebugPath
694 ## __GenSimpleFileSection__() method
696 # Generate section by specified file name or a list of files with file extension
698 # @param self The object pointer
699 # @param Rule The rule object used to generate section
700 # @retval string File name of the generated section file
702 def __GenSimpleFileSection__(self
, Rule
, IsMakefile
= False):
704 # Prepare the parameter of GenSection
708 GenSecInputFile
= None
709 if Rule
.FileName
!= None:
710 GenSecInputFile
= self
.__ExtendMacro
__(Rule
.FileName
)
711 if os
.path
.isabs(GenSecInputFile
):
712 GenSecInputFile
= os
.path
.normpath(GenSecInputFile
)
714 GenSecInputFile
= os
.path
.normpath(os
.path
.join(self
.EfiOutputPath
, GenSecInputFile
))
716 FileList
, IsSect
= Section
.Section
.GetFileList(self
, '', Rule
.FileExtension
)
719 SectionType
= Rule
.SectionType
721 # Convert Fv Section Type for PI1.1 SMM driver.
723 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
724 if SectionType
== 'DXE_DEPEX':
725 SectionType
= 'SMM_DEPEX'
727 # Framework SMM Driver has no SMM_DEPEX section type
729 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
730 if SectionType
== 'SMM_DEPEX':
731 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
733 if self
.ModuleType
in ('SEC', 'PEI_CORE', 'PEIM'):
734 if self
.KeepReloc
!= None:
735 NoStrip
= self
.KeepReloc
736 elif Rule
.KeepReloc
!= None:
737 NoStrip
= Rule
.KeepReloc
738 elif self
.ShadowFromInfFile
!= None:
739 NoStrip
= self
.ShadowFromInfFile
742 for File
in FileList
:
745 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
746 Ffs
.Ffs
.SectionSuffix
[SectionType
] + 'SEC' + SecNum
748 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
749 File
= GenFdsGlobalVariable
.MacroExtend(File
, Dict
, self
.CurrentArch
)
751 #Get PE Section alignment when align is set to AUTO
752 if self
.Alignment
== 'Auto' and (SectionType
== 'PE32' or SectionType
== 'TE'):
753 ImageObj
= PeImageClass (File
)
754 if ImageObj
.SectionAlignment
< 0x400:
755 self
.Alignment
= str (ImageObj
.SectionAlignment
)
756 elif ImageObj
.SectionAlignment
< 0x100000:
757 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
759 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x100000) + 'M'
762 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
763 if not os
.path
.exists(FileBeforeStrip
) or \
764 (os
.path
.getmtime(File
) > os
.path
.getmtime(FileBeforeStrip
)):
765 CopyLongFilePath(File
, FileBeforeStrip
)
766 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
767 GenFdsGlobalVariable
.GenerateFirmwareImage(
771 IsMakefile
=IsMakefile
775 if SectionType
== 'TE':
776 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
777 GenFdsGlobalVariable
.GenerateFirmwareImage(
781 IsMakefile
=IsMakefile
784 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [File
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
785 OutputFileList
.append(OutputFile
)
788 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
789 Ffs
.Ffs
.SectionSuffix
[SectionType
] + 'SEC' + SecNum
790 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
791 GenSecInputFile
= GenFdsGlobalVariable
.MacroExtend(GenSecInputFile
, Dict
, self
.CurrentArch
)
793 #Get PE Section alignment when align is set to AUTO
794 if self
.Alignment
== 'Auto' and (SectionType
== 'PE32' or SectionType
== 'TE'):
795 ImageObj
= PeImageClass (GenSecInputFile
)
796 if ImageObj
.SectionAlignment
< 0x400:
797 self
.Alignment
= str (ImageObj
.SectionAlignment
)
798 elif ImageObj
.SectionAlignment
< 0x100000:
799 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
801 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x100000) + 'M'
804 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
805 if not os
.path
.exists(FileBeforeStrip
) or \
806 (os
.path
.getmtime(GenSecInputFile
) > os
.path
.getmtime(FileBeforeStrip
)):
807 CopyLongFilePath(GenSecInputFile
, FileBeforeStrip
)
809 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
810 GenFdsGlobalVariable
.GenerateFirmwareImage(
814 IsMakefile
=IsMakefile
816 GenSecInputFile
= StrippedFile
818 if SectionType
== 'TE':
819 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
820 GenFdsGlobalVariable
.GenerateFirmwareImage(
824 IsMakefile
=IsMakefile
826 GenSecInputFile
= TeFile
827 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [GenSecInputFile
], Section
.Section
.SectionType
[SectionType
], IsMakefile
=IsMakefile
)
828 OutputFileList
.append(OutputFile
)
830 return OutputFileList
832 ## __GenSimpleFileFfs__() method
836 # @param self The object pointer
837 # @param Rule The rule object used to generate section
838 # @param InputFileList The output file list from GenSection
839 # @retval string Generated FFS file name
841 def __GenSimpleFileFfs__(self
, Rule
, InputFileList
, MakefilePath
= None):
842 FfsOutput
= self
.OutputPath
+ \
844 self
.__ExtendMacro
__(Rule
.NameGuid
) + \
847 GenFdsGlobalVariable
.VerboseLogger(self
.__ExtendMacro
__(Rule
.NameGuid
))
849 SectionAlignments
= []
850 for InputFile
in InputFileList
:
851 InputSection
.append(InputFile
)
852 SectionAlignments
.append(Rule
.SectAlignment
)
854 if Rule
.NameGuid
!= None and Rule
.NameGuid
.startswith('PCD('):
855 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
856 if len(PcdValue
) == 0:
857 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
859 if PcdValue
.startswith('{'):
860 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
861 RegistryGuidStr
= PcdValue
862 if len(RegistryGuidStr
) == 0:
863 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
865 self
.ModuleGuid
= RegistryGuidStr
867 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputSection
,
868 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
869 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
870 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
871 SectionAlign
=SectionAlignments
,
872 MakefilePath
=MakefilePath
876 ## __GenComplexFileSection__() method
878 # Generate section by sections in Rule
880 # @param self The object pointer
881 # @param Rule The rule object used to generate section
882 # @param FvChildAddr Array of the inside FvImage base address
883 # @param FvParentAddr Parent Fv base address
884 # @retval string File name of the generated section file
886 def __GenComplexFileSection__(self
, Rule
, FvChildAddr
, FvParentAddr
, IsMakefile
= False):
887 if self
.ModuleType
in ('SEC', 'PEI_CORE', 'PEIM'):
888 if Rule
.KeepReloc
!= None:
889 self
.KeepRelocFromRule
= Rule
.KeepReloc
893 HasGeneratedFlag
= False
894 if self
.PcdIsDriver
== 'PEI_PCD_DRIVER':
895 if self
.IsBinaryModule
:
896 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "PEIPcdDataBase.raw")
898 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "PEIPcdDataBase.raw")
899 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "PEIPcdDataBaseSec.raw")
900 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
903 IsMakefile
= IsMakefile
905 SectFiles
.append(PcdExDbSecName
)
906 SectAlignments
.append(None)
907 elif self
.PcdIsDriver
== 'DXE_PCD_DRIVER':
908 if self
.IsBinaryModule
:
909 PcdExDbFileName
= os
.path
.join(GenFdsGlobalVariable
.FvDir
, "DXEPcdDataBase.raw")
911 PcdExDbFileName
= os
.path
.join(self
.EfiOutputPath
, "DXEPcdDataBase.raw")
912 PcdExDbSecName
= os
.path
.join(self
.OutputPath
, "DXEPcdDataBaseSec.raw")
913 GenFdsGlobalVariable
.GenerateSection(PcdExDbSecName
,
916 IsMakefile
= IsMakefile
918 SectFiles
.append(PcdExDbSecName
)
919 SectAlignments
.append(None)
920 for Sect
in Rule
.SectionList
:
921 SecIndex
= '%d' %Index
924 # Convert Fv Section Type for PI1.1 SMM driver.
926 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
927 if Sect
.SectionType
== 'DXE_DEPEX':
928 Sect
.SectionType
= 'SMM_DEPEX'
930 # Framework SMM Driver has no SMM_DEPEX section type
932 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
933 if Sect
.SectionType
== 'SMM_DEPEX':
934 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
936 # process the inside FvImage from FvSection or GuidSection
938 if FvChildAddr
!= []:
939 if isinstance(Sect
, FvImageSection
):
940 Sect
.FvAddr
= FvChildAddr
.pop(0)
941 elif isinstance(Sect
, GuidSection
):
942 Sect
.FvAddr
= FvChildAddr
943 if FvParentAddr
!= None and isinstance(Sect
, GuidSection
):
944 Sect
.FvParentAddr
= FvParentAddr
946 if Rule
.KeyStringList
!= []:
947 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, Rule
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
949 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, self
.KeyStringList
, self
, IsMakefile
= IsMakefile
)
951 if not HasGeneratedFlag
:
952 UniVfrOffsetFileSection
= ""
953 ModuleFileName
= mws
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
)
954 InfData
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClass(ModuleFileName
), self
.CurrentArch
]
956 # Search the source list in InfData to find if there are .vfr file exist.
959 VfrUniOffsetList
= []
960 for SourceFile
in InfData
.Sources
:
961 if SourceFile
.Type
.upper() == ".VFR" :
963 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
965 VfrUniBaseName
[SourceFile
.BaseName
] = (SourceFile
.BaseName
+ "Bin")
966 if SourceFile
.Type
.upper() == ".UNI" :
968 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
970 VfrUniBaseName
["UniOffsetName"] = (self
.BaseName
+ "Strings")
973 if len(VfrUniBaseName
) > 0:
975 if InfData
.BuildType
!= 'UEFI_HII':
976 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
977 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
978 UniVfrOffsetFileNameList
= []
979 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
980 TrimCmd
= "Trim --Vfr-Uni-Offset -o %s --ModuleName=%s --DebugDir=%s " % (UniVfrOffsetFileName
, self
.BaseName
, self
.EfiDebugPath
)
981 GenFdsGlobalVariable
.SecCmdList
.append(TrimCmd
)
982 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
983 [UniVfrOffsetFileName
],
988 VfrUniOffsetList
= self
.__GetBuildOutputMapFileVfrUniInfo
(VfrUniBaseName
)
990 # Generate the Raw data of raw section
993 UniVfrOffsetFileName
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ '.offset')
994 UniVfrOffsetFileSection
= os
.path
.join(self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
995 self
.__GenUniVfrOffsetFile
(VfrUniOffsetList
, UniVfrOffsetFileName
)
996 UniVfrOffsetFileNameList
= []
997 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
998 """Call GenSection"""
1000 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
1001 UniVfrOffsetFileNameList
,
1004 #os.remove(UniVfrOffsetFileName)
1005 if UniVfrOffsetFileSection
:
1006 SectList
.append(UniVfrOffsetFileSection
)
1007 HasGeneratedFlag
= True
1009 for SecName
in SectList
:
1010 SectFiles
.append(SecName
)
1011 SectAlignments
.append(Align
)
1013 return SectFiles
, SectAlignments
1015 ## __GenComplexFileFfs__() method
1019 # @param self The object pointer
1020 # @param Rule The rule object used to generate section
1021 # @param InputFileList The output file list from GenSection
1022 # @retval string Generated FFS file name
1024 def __GenComplexFileFfs__(self
, Rule
, InputFile
, Alignments
, MakefilePath
= None):
1026 if Rule
.NameGuid
!= None and Rule
.NameGuid
.startswith('PCD('):
1027 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
1028 if len(PcdValue
) == 0:
1029 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
1031 if PcdValue
.startswith('{'):
1032 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
1033 RegistryGuidStr
= PcdValue
1034 if len(RegistryGuidStr
) == 0:
1035 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
1037 self
.ModuleGuid
= RegistryGuidStr
1039 FfsOutput
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
1040 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputFile
,
1041 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
1042 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
1043 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
1044 SectionAlign
=Alignments
,
1045 MakefilePath
=MakefilePath
1049 ## __GetGenFfsCmdParameter__() method
1051 # Create parameter string for GenFfs
1053 # @param self The object pointer
1054 # @param Rule The rule object used to generate section
1055 # @retval tuple (FileType, Fixed, CheckSum, Alignment)
1057 def __GetGenFfsCmdParameter__(self
, Rule
):
1059 result
+= ('-t', Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
])
1060 if Rule
.Fixed
!= False:
1062 if Rule
.CheckSum
!= False:
1065 if Rule
.Alignment
!= None and Rule
.Alignment
!= '':
1066 result
+= ('-a', Rule
.Alignment
)
1070 ## __GetBuildOutputMapFileVfrUniInfo() method
1072 # Find the offset of UNI/INF object offset in the EFI image file.
1074 # @param self The object pointer
1075 # @param VfrUniBaseName A name list contain the UNI/INF object name.
1076 # @retval RetValue A list contain offset of UNI/INF object.
1078 def __GetBuildOutputMapFileVfrUniInfo(self
, VfrUniBaseName
):
1079 MapFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".map")
1080 EfiFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".efi")
1081 return GetVariableOffset(MapFileName
, EfiFileName
, VfrUniBaseName
.values())
1083 ## __GenUniVfrOffsetFile() method
1085 # Generate the offset file for the module which contain VFR or UNI file.
1087 # @param self The object pointer
1088 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
1089 # @param UniVfrOffsetFileName The output offset file name.
1091 def __GenUniVfrOffsetFile(self
, VfrUniOffsetList
, UniVfrOffsetFileName
):
1093 # Use a instance of StringIO to cache data
1094 fStringIO
= StringIO
.StringIO('')
1096 for Item
in VfrUniOffsetList
:
1097 if (Item
[0].find("Strings") != -1):
1099 # UNI offset in image.
1101 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
1103 UniGuid
= [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
1104 UniGuid
= [chr(ItemGuid
) for ItemGuid
in UniGuid
]
1105 fStringIO
.write(''.join(UniGuid
))
1106 UniValue
= pack ('Q', int (Item
[1], 16))
1107 fStringIO
.write (UniValue
)
1110 # VFR binary offset in image.
1112 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
1114 VfrGuid
= [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
1115 VfrGuid
= [chr(ItemGuid
) for ItemGuid
in VfrGuid
]
1116 fStringIO
.write(''.join(VfrGuid
))
1118 VfrValue
= pack ('Q', int (Item
[1], 16))
1119 fStringIO
.write (VfrValue
)
1122 # write data into file.
1125 SaveFileOnChange(UniVfrOffsetFileName
, fStringIO
.getvalue())
1127 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)