]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/FfsInfStatement.py
BaseTools: add the support for --pcd feature to patch the binary efi
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FfsInfStatement.py
1 ## @file
2 # process FFS generation from INF statement
3 #
4 # Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
5 # Copyright (c) 2014-2016 Hewlett-Packard Development Company, L.P.<BR>
6 #
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
11 #
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.
14 #
15
16 ##
17 # Import Modules
18 #
19 import Rule
20 import Common.LongFilePathOs as os
21 import StringIO
22 from struct import *
23 from GenFdsGlobalVariable import GenFdsGlobalVariable
24 import Ffs
25 import subprocess
26 import sys
27 import Section
28 import RuleSimpleFile
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
48 ## generate FFS from INF
49 #
50 #
51 class FfsInfStatement(FfsInfStatementClassObject):
52 ## The mapping dictionary from datum type to its maximum number.
53 _MAX_SIZE_TYPE = {"BOOLEAN":0x01, "UINT8":0xFF, "UINT16":0xFFFF, "UINT32":0xFFFFFFFF, "UINT64":0xFFFFFFFFFFFFFFFF}
54 ## The constructor
55 #
56 # @param self The object pointer
57 #
58 def __init__(self):
59 FfsInfStatementClassObject.__init__(self)
60 self.TargetOverrideList = []
61 self.ShadowFromInfFile = None
62 self.KeepRelocFromRule = None
63 self.InDsc = True
64 self.OptRomDefs = {}
65 self.PiSpecVersion = '0x00000000'
66 self.InfModule = None
67 self.FinalTargetSuffixMap = {}
68 self.CurrentLineNum = None
69 self.CurrentLineContent = None
70 self.FileName = None
71 self.InfFileName = None
72 self.OverrideGuid = None
73 self.PatchedBinFile = ''
74 self.MacroDict = {}
75
76 ## GetFinalTargetSuffixMap() method
77 #
78 # Get final build target list
79 def GetFinalTargetSuffixMap(self):
80 if not self.InfModule or not self.CurrentArch:
81 return []
82 if not self.FinalTargetSuffixMap:
83 FinalBuildTargetList = GenFdsGlobalVariable.GetModuleCodaTargetList(self.InfModule, self.CurrentArch)
84 for File in FinalBuildTargetList:
85 self.FinalTargetSuffixMap.setdefault(os.path.splitext(File)[1], []).append(File)
86
87 # Check if current INF module has DEPEX
88 if '.depex' not in self.FinalTargetSuffixMap and self.InfModule.ModuleType != "USER_DEFINED" \
89 and not self.InfModule.DxsFile and not self.InfModule.LibraryClass:
90 ModuleType = self.InfModule.ModuleType
91 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
92
93 if ModuleType != DataType.SUP_MODULE_USER_DEFINED:
94 for LibraryClass in PlatformDataBase.LibraryClasses.GetKeys():
95 if LibraryClass.startswith("NULL") and PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]:
96 self.InfModule.LibraryClasses[LibraryClass] = PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]
97
98 StrModule = str(self.InfModule)
99 PlatformModule = None
100 if StrModule in PlatformDataBase.Modules:
101 PlatformModule = PlatformDataBase.Modules[StrModule]
102 for LibraryClass in PlatformModule.LibraryClasses:
103 if LibraryClass.startswith("NULL"):
104 self.InfModule.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]
105
106 DependencyList = [self.InfModule]
107 LibraryInstance = {}
108 DepexList = []
109 while len(DependencyList) > 0:
110 Module = DependencyList.pop(0)
111 if not Module:
112 continue
113 for Dep in Module.Depex[self.CurrentArch, ModuleType]:
114 if DepexList != []:
115 DepexList.append('AND')
116 DepexList.append('(')
117 DepexList.extend(Dep)
118 if DepexList[-1] == 'END': # no need of a END at this time
119 DepexList.pop()
120 DepexList.append(')')
121 if 'BEFORE' in DepexList or 'AFTER' in DepexList:
122 break
123 for LibName in Module.LibraryClasses:
124 if LibName in LibraryInstance:
125 continue
126 if PlatformModule and LibName in PlatformModule.LibraryClasses:
127 LibraryPath = PlatformModule.LibraryClasses[LibName]
128 else:
129 LibraryPath = PlatformDataBase.LibraryClasses[LibName, ModuleType]
130 if not LibraryPath:
131 LibraryPath = Module.LibraryClasses[LibName]
132 if not LibraryPath:
133 continue
134 LibraryModule = GenFdsGlobalVariable.WorkSpace.BuildObject[LibraryPath, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
135 LibraryInstance[LibName] = LibraryModule
136 DependencyList.append(LibraryModule)
137 if DepexList:
138 Dpx = DependencyExpression(DepexList, ModuleType, True)
139 if len(Dpx.PostfixNotation) != 0:
140 # It means this module has DEPEX
141 self.FinalTargetSuffixMap['.depex'] = [os.path.join(self.EfiOutputPath, self.BaseName) + '.depex']
142 return self.FinalTargetSuffixMap
143
144 ## __InfParse() method
145 #
146 # Parse inf file to get module information
147 #
148 # @param self The object pointer
149 # @param Dict dictionary contains macro and value pair
150 #
151 def __InfParse__(self, Dict = {}):
152
153 GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName)
154
155 self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '')
156 if len(self.InfFileName) > 1 and self.InfFileName[0] == '\\' and self.InfFileName[1] == '\\':
157 pass
158 elif self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' :
159 self.InfFileName = self.InfFileName[1:]
160
161 if self.InfFileName.find('$') == -1:
162 InfPath = NormPath(self.InfFileName)
163 if not os.path.exists(InfPath):
164 InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath)
165 if not os.path.exists(InfPath):
166 EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName))
167
168 self.CurrentArch = self.GetCurrentArch()
169 #
170 # Get the InfClass object
171 #
172
173 PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)
174 ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")
175 if ErrorCode != 0:
176 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
177
178 #
179 # Cache lower case version of INF path before processing FILE_GUID override
180 #
181 InfLowerPath = str(PathClassObj).lower()
182 if self.OverrideGuid:
183 PathClassObj = ProcessDuplicatedInf(PathClassObj, self.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir)
184 if self.CurrentArch != None:
185
186 Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
187 #
188 # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath
189 #
190 self.BaseName = Inf.BaseName
191 self.ModuleGuid = Inf.Guid
192 self.ModuleType = Inf.ModuleType
193 if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:
194 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']
195 if Inf.AutoGenVersion < 0x00010005:
196 self.ModuleType = Inf.ComponentType
197 self.VersionString = Inf.Version
198 self.BinFileList = Inf.Binaries
199 self.SourceFileList = Inf.Sources
200 if self.KeepReloc == None and Inf.Shadow:
201 self.ShadowFromInfFile = Inf.Shadow
202
203 else:
204 Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
205 self.BaseName = Inf.BaseName
206 self.ModuleGuid = Inf.Guid
207 self.ModuleType = Inf.ModuleType
208 if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:
209 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']
210 self.VersionString = Inf.Version
211 self.BinFileList = Inf.Binaries
212 self.SourceFileList = Inf.Sources
213 if self.BinFileList == []:
214 EdkLogger.error("GenFds", GENFDS_ERROR,
215 "INF %s specified in FDF could not be found in build ARCH %s!" \
216 % (self.InfFileName, GenFdsGlobalVariable.ArchList))
217
218 if self.OverrideGuid:
219 self.ModuleGuid = self.OverrideGuid
220
221 if len(self.SourceFileList) != 0 and not self.InDsc:
222 EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName))
223
224 if self.ModuleType == 'SMM_CORE' and int(self.PiSpecVersion, 16) < 0x0001000A:
225 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)
226
227 if Inf._Defs != None and len(Inf._Defs) > 0:
228 self.OptRomDefs.update(Inf._Defs)
229
230 self.PatchPcds = []
231 InfPcds = Inf.Pcds
232 Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
233 FdfPcdDict = GenFdsGlobalVariable.FdfParser.Profile.PcdDict
234
235 # Workaround here: both build and GenFds tool convert the workspace path to lower case
236 # But INF file path in FDF and DSC file may have real case characters.
237 # Try to convert the path to lower case to see if PCDs value are override by DSC.
238 DscModules = {}
239 for DscModule in Platform.Modules:
240 DscModules[str(DscModule).lower()] = Platform.Modules[DscModule]
241 for PcdKey in InfPcds:
242 Pcd = InfPcds[PcdKey]
243 if not hasattr(Pcd, 'Offset'):
244 continue
245 if Pcd.Type != 'PatchableInModule':
246 continue
247 # Override Patchable PCD value by the value from DSC
248 PatchPcd = None
249 if InfLowerPath in DscModules and PcdKey in DscModules[InfLowerPath].Pcds:
250 PatchPcd = DscModules[InfLowerPath].Pcds[PcdKey]
251 elif PcdKey in Platform.Pcds:
252 PatchPcd = Platform.Pcds[PcdKey]
253 DscOverride = False
254 if PatchPcd and Pcd.Type == PatchPcd.Type:
255 DefaultValue = PatchPcd.DefaultValue
256 DscOverride = True
257
258 # Override Patchable PCD value by the value from FDF
259 FdfOverride = False
260 if PcdKey in FdfPcdDict:
261 DefaultValue = FdfPcdDict[PcdKey]
262 FdfOverride = True
263
264 # Override Patchable PCD value by the value from Build Option
265 BuildOptionOverride = False
266 if GlobalData.BuildOptionPcd:
267 for pcd in GlobalData.BuildOptionPcd:
268 if PcdKey == (pcd[1], pcd[0]):
269 DefaultValue = pcd[2]
270 BuildOptionOverride = True
271 break
272
273 if not DscOverride and not FdfOverride and not BuildOptionOverride:
274 continue
275 # Check value, if value are equal, no need to patch
276 if Pcd.DatumType == "VOID*":
277 if Pcd.DefaultValue == DefaultValue or DefaultValue in [None, '']:
278 continue
279 # Get the string size from FDF or DSC
280 if DefaultValue[0] == 'L':
281 # Remove L"", but the '\0' must be appended
282 MaxDatumSize = str((len(DefaultValue) - 2) * 2)
283 elif DefaultValue[0] == '{':
284 MaxDatumSize = str(len(DefaultValue.split(',')))
285 else:
286 MaxDatumSize = str(len(DefaultValue) - 1)
287 if DscOverride:
288 Pcd.MaxDatumSize = PatchPcd.MaxDatumSize
289 # If no defined the maximum size in DSC, try to get current size from INF
290 if Pcd.MaxDatumSize in ['', None]:
291 Pcd.MaxDatumSize = str(len(Pcd.DefaultValue.split(',')))
292 else:
293 Base1 = Base2 = 10
294 if Pcd.DefaultValue.upper().startswith('0X'):
295 Base1 = 16
296 if DefaultValue.upper().startswith('0X'):
297 Base2 = 16
298 try:
299 PcdValueInImg = int(Pcd.DefaultValue, Base1)
300 PcdValueInDscOrFdf = int(DefaultValue, Base2)
301 if PcdValueInImg == PcdValueInDscOrFdf:
302 continue
303 except:
304 continue
305 # Check the Pcd size and data type
306 if Pcd.DatumType == "VOID*":
307 if int(MaxDatumSize) > int(Pcd.MaxDatumSize):
308 EdkLogger.error("GenFds", GENFDS_ERROR, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \
309 % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, int(MaxDatumSize) - int(Pcd.MaxDatumSize)))
310 else:
311 if PcdValueInDscOrFdf > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType] \
312 or PcdValueInImg > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType]:
313 EdkLogger.error("GenFds", GENFDS_ERROR, "The size of %s type PCD '%s.%s' doesn't match its data type." \
314 % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
315 self.PatchPcds.append((Pcd, DefaultValue))
316
317 self.InfModule = Inf
318 self.PcdIsDriver = Inf.PcdIsDriver
319 self.IsBinaryModule = Inf.IsBinaryModule
320 GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName)
321 GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid)
322 GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType)
323 GenFdsGlobalVariable.VerboseLogger("VersionString : %s" % self.VersionString)
324 GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" % self.InfFileName)
325
326 #
327 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\
328 #
329
330 self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \
331 self.ModuleGuid + self.BaseName)
332 if not os.path.exists(self.OutputPath) :
333 os.makedirs(self.OutputPath)
334
335 self.EfiOutputPath = self.__GetEFIOutPutPath__()
336 GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)
337
338 ## PatchEfiFile
339 #
340 # Patch EFI file with patch PCD
341 #
342 # @param EfiFile: EFI file needs to be patched.
343 # @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name
344 # If passed in file does not end with efi, return as is
345 #
346 def PatchEfiFile(self, EfiFile, FileType):
347 #
348 # If the module does not have any patches, then return path to input file
349 #
350 if not self.PatchPcds:
351 return EfiFile
352
353 #
354 # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED
355 #
356 if FileType != 'PE32' and self.ModuleType != "USER_DEFINED":
357 return EfiFile
358
359 #
360 # Generate path to patched output file
361 #
362 Basename = os.path.basename(EfiFile)
363 Output = os.path.normpath (os.path.join(self.OutputPath, Basename))
364
365 #
366 # If this file has already been patched, then return the path to the patched file
367 #
368 if self.PatchedBinFile == Output:
369 return Output
370
371 #
372 # If a different file from the same module has already been patched, then generate an error
373 #
374 if self.PatchedBinFile:
375 EdkLogger.error("GenFds", GENFDS_ERROR,
376 'Only one binary file can be patched:\n'
377 ' a binary file has been patched: %s\n'
378 ' current file: %s' % (self.PatchedBinFile, EfiFile),
379 File=self.InfFileName)
380
381 #
382 # Copy unpatched file contents to output file location to perform patching
383 #
384 CopyLongFilePath(EfiFile, Output)
385
386 #
387 # Apply patches to patched output file
388 #
389 for Pcd, Value in self.PatchPcds:
390 RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Value, Pcd.MaxDatumSize)
391 if RetVal:
392 EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName)
393
394 #
395 # Save the path of the patched output file
396 #
397 self.PatchedBinFile = Output
398
399 #
400 # Return path to patched output file
401 #
402 return Output
403
404 ## GenFfs() method
405 #
406 # Generate FFS
407 #
408 # @param self The object pointer
409 # @param Dict dictionary contains macro and value pair
410 # @param FvChildAddr Array of the inside FvImage base address
411 # @param FvParentAddr Parent Fv base address
412 # @retval string Generated FFS file name
413 #
414 def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None):
415 #
416 # Parse Inf file get Module related information
417 #
418
419 self.__InfParse__(Dict)
420 SrcFile = mws.join( GenFdsGlobalVariable.WorkSpaceDir , self.InfFileName);
421 DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')
422
423 SrcFileDir = "."
424 SrcPath = os.path.dirname(SrcFile)
425 SrcFileName = os.path.basename(SrcFile)
426 SrcFileBase, SrcFileExt = os.path.splitext(SrcFileName)
427 DestPath = os.path.dirname(DestFile)
428 DestFileName = os.path.basename(DestFile)
429 DestFileBase, DestFileExt = os.path.splitext(DestFileName)
430 self.MacroDict = {
431 # source file
432 "${src}" : SrcFile,
433 "${s_path}" : SrcPath,
434 "${s_dir}" : SrcFileDir,
435 "${s_name}" : SrcFileName,
436 "${s_base}" : SrcFileBase,
437 "${s_ext}" : SrcFileExt,
438 # destination file
439 "${dst}" : DestFile,
440 "${d_path}" : DestPath,
441 "${d_name}" : DestFileName,
442 "${d_base}" : DestFileBase,
443 "${d_ext}" : DestFileExt
444 }
445 #
446 # Allow binary type module not specify override rule in FDF file.
447 #
448 if len(self.BinFileList) > 0:
449 if self.Rule == None or self.Rule == "":
450 self.Rule = "BINARY"
451
452 #
453 # Get the rule of how to generate Ffs file
454 #
455 Rule = self.__GetRule__()
456 GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName)
457 #
458 # Convert Fv File Type for PI1.1 SMM driver.
459 #
460 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:
461 if Rule.FvFileType == 'DRIVER':
462 Rule.FvFileType = 'SMM'
463 #
464 # Framework SMM Driver has no SMM FV file type
465 #
466 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:
467 if Rule.FvFileType == 'SMM' or Rule.FvFileType == 'SMM_CORE':
468 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File=self.InfFileName)
469 #
470 # For the rule only has simpleFile
471 #
472 if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) :
473 SectionOutputList = self.__GenSimpleFileSection__(Rule)
474 FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList)
475 return FfsOutput
476 #
477 # For Rule has ComplexFile
478 #
479 elif isinstance(Rule, RuleComplexFile.RuleComplexFile):
480 InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr)
481 FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments)
482
483 return FfsOutput
484
485 ## __ExtendMacro__() method
486 #
487 # Replace macro with its value
488 #
489 # @param self The object pointer
490 # @param String The string to be replaced
491 # @retval string Macro replaced string
492 #
493 def __ExtendMacro__ (self, String):
494 MacroDict = {
495 '$(INF_OUTPUT)' : self.EfiOutputPath,
496 '$(MODULE_NAME)' : self.BaseName,
497 '$(BUILD_NUMBER)': self.BuildNum,
498 '$(INF_VERSION)' : self.VersionString,
499 '$(NAMED_GUID)' : self.ModuleGuid
500 }
501 String = GenFdsGlobalVariable.MacroExtend(String, MacroDict)
502 String = GenFdsGlobalVariable.MacroExtend(String, self.MacroDict)
503 return String
504
505 ## __GetRule__() method
506 #
507 # Get correct rule for generating FFS for this INF
508 #
509 # @param self The object pointer
510 # @retval Rule Rule object
511 #
512 def __GetRule__ (self) :
513 CurrentArchList = []
514 if self.CurrentArch == None:
515 CurrentArchList = ['common']
516 else:
517 CurrentArchList.append(self.CurrentArch)
518
519 for CurrentArch in CurrentArchList:
520 RuleName = 'RULE' + \
521 '.' + \
522 CurrentArch.upper() + \
523 '.' + \
524 self.ModuleType.upper()
525 if self.Rule != None:
526 RuleName = RuleName + \
527 '.' + \
528 self.Rule.upper()
529
530 Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)
531 if Rule != None:
532 GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)
533 return Rule
534
535 RuleName = 'RULE' + \
536 '.' + \
537 'COMMON' + \
538 '.' + \
539 self.ModuleType.upper()
540
541 if self.Rule != None:
542 RuleName = RuleName + \
543 '.' + \
544 self.Rule.upper()
545
546 GenFdsGlobalVariable.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName, self.InfFileName))
547
548 Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)
549 if Rule != None:
550 GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)
551 return Rule
552
553 if Rule == None :
554 EdkLogger.error("GenFds", GENFDS_ERROR, 'Don\'t Find common rule %s for INF %s' \
555 % (RuleName, self.InfFileName))
556
557 ## __GetPlatformArchList__() method
558 #
559 # Get Arch list this INF built under
560 #
561 # @param self The object pointer
562 # @retval list Arch list
563 #
564 def __GetPlatformArchList__(self):
565
566 InfFileKey = os.path.normpath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))
567 DscArchList = []
568 for Arch in GenFdsGlobalVariable.ArchList :
569 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
570 if PlatformDataBase != None:
571 if InfFileKey in PlatformDataBase.Modules:
572 DscArchList.append (Arch)
573
574 return DscArchList
575
576 ## GetCurrentArch() method
577 #
578 # Get Arch list of the module from this INF is to be placed into flash
579 #
580 # @param self The object pointer
581 # @retval list Arch list
582 #
583 def GetCurrentArch(self) :
584
585 TargetArchList = GenFdsGlobalVariable.ArchList
586
587 PlatformArchList = self.__GetPlatformArchList__()
588
589 CurArchList = TargetArchList
590 if PlatformArchList != []:
591 CurArchList = list(set (TargetArchList) & set (PlatformArchList))
592 GenFdsGlobalVariable.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList))
593
594 ArchList = []
595 if self.KeyStringList != []:
596 for Key in self.KeyStringList:
597 Key = GenFdsGlobalVariable.MacroExtend(Key)
598 Target, Tag, Arch = Key.split('_')
599 if Arch in CurArchList:
600 ArchList.append(Arch)
601 if Target not in self.TargetOverrideList:
602 self.TargetOverrideList.append(Target)
603 else:
604 ArchList = CurArchList
605
606 UseArchList = TargetArchList
607 if self.UseArch != None:
608 UseArchList = []
609 UseArchList.append(self.UseArch)
610 ArchList = list(set (UseArchList) & set (ArchList))
611
612 self.InfFileName = NormPath(self.InfFileName)
613 if len(PlatformArchList) == 0:
614 self.InDsc = False
615 PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)
616 ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")
617 if ErrorCode != 0:
618 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
619 if len(ArchList) == 1:
620 Arch = ArchList[0]
621 return Arch
622 elif len(ArchList) > 1:
623 if len(PlatformArchList) == 0:
624 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))
625 else:
626 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))
627 else:
628 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." \
629 % (self.InfFileName, str(PlatformArchList), GenFdsGlobalVariable.ActivePlatform, str(set (UseArchList) & set (TargetArchList))))
630
631 ## __GetEFIOutPutPath__() method
632 #
633 # Get the output path for generated files
634 #
635 # @param self The object pointer
636 # @retval string Path that output files from this INF go to
637 #
638 def __GetEFIOutPutPath__(self):
639 Arch = ''
640 OutputPath = ''
641 (ModulePath, FileName) = os.path.split(self.InfFileName)
642 Index = FileName.rfind('.')
643 FileName = FileName[0:Index]
644 if self.OverrideGuid:
645 FileName = self.OverrideGuid
646 Arch = "NoneArch"
647 if self.CurrentArch != None:
648 Arch = self.CurrentArch
649
650 OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],
651 Arch ,
652 ModulePath,
653 FileName,
654 'OUTPUT'
655 )
656 OutputPath = os.path.realpath(OutputPath)
657 return OutputPath
658
659 ## __GenSimpleFileSection__() method
660 #
661 # Generate section by specified file name or a list of files with file extension
662 #
663 # @param self The object pointer
664 # @param Rule The rule object used to generate section
665 # @retval string File name of the generated section file
666 #
667 def __GenSimpleFileSection__(self, Rule):
668 #
669 # Prepare the parameter of GenSection
670 #
671 FileList = []
672 OutputFileList = []
673 GenSecInputFile = None
674 if Rule.FileName != None:
675 GenSecInputFile = self.__ExtendMacro__(Rule.FileName)
676 if os.path.isabs(GenSecInputFile):
677 GenSecInputFile = os.path.normpath(GenSecInputFile)
678 else:
679 GenSecInputFile = os.path.normpath(os.path.join(self.EfiOutputPath, GenSecInputFile))
680 else:
681 FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension)
682
683 Index = 1
684 SectionType = Rule.SectionType
685 #
686 # Convert Fv Section Type for PI1.1 SMM driver.
687 #
688 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:
689 if SectionType == 'DXE_DEPEX':
690 SectionType = 'SMM_DEPEX'
691 #
692 # Framework SMM Driver has no SMM_DEPEX section type
693 #
694 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:
695 if SectionType == 'SMM_DEPEX':
696 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)
697 NoStrip = True
698 if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):
699 if self.KeepReloc != None:
700 NoStrip = self.KeepReloc
701 elif Rule.KeepReloc != None:
702 NoStrip = Rule.KeepReloc
703 elif self.ShadowFromInfFile != None:
704 NoStrip = self.ShadowFromInfFile
705
706 if FileList != [] :
707 for File in FileList:
708
709 SecNum = '%d' %Index
710 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
711 Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum
712 Index = Index + 1
713 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)
714 File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)
715
716 #Get PE Section alignment when align is set to AUTO
717 if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):
718 ImageObj = PeImageClass (File)
719 if ImageObj.SectionAlignment < 0x400:
720 self.Alignment = str (ImageObj.SectionAlignment)
721 else:
722 self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
723
724 if not NoStrip:
725 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
726 if not os.path.exists(FileBeforeStrip) or \
727 (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
728 CopyLongFilePath(File, FileBeforeStrip)
729 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
730 GenFdsGlobalVariable.GenerateFirmwareImage(
731 StrippedFile,
732 [File],
733 Strip=True
734 )
735 File = StrippedFile
736
737 if SectionType == 'TE':
738 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
739 GenFdsGlobalVariable.GenerateFirmwareImage(
740 TeFile,
741 [File],
742 Type='te'
743 )
744 File = TeFile
745
746 GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType])
747 OutputFileList.append(OutputFile)
748 else:
749 SecNum = '%d' %Index
750 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
751 Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum
752 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)
753 GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch)
754
755 #Get PE Section alignment when align is set to AUTO
756 if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):
757 ImageObj = PeImageClass (GenSecInputFile)
758 if ImageObj.SectionAlignment < 0x400:
759 self.Alignment = str (ImageObj.SectionAlignment)
760 else:
761 self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
762
763 if not NoStrip:
764 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
765 if not os.path.exists(FileBeforeStrip) or \
766 (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)):
767 CopyLongFilePath(GenSecInputFile, FileBeforeStrip)
768
769 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
770 GenFdsGlobalVariable.GenerateFirmwareImage(
771 StrippedFile,
772 [GenSecInputFile],
773 Strip=True
774 )
775 GenSecInputFile = StrippedFile
776
777 if SectionType == 'TE':
778 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
779 GenFdsGlobalVariable.GenerateFirmwareImage(
780 TeFile,
781 [GenSecInputFile],
782 Type='te'
783 )
784 GenSecInputFile = TeFile
785
786 GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType])
787 OutputFileList.append(OutputFile)
788
789 return OutputFileList
790
791 ## __GenSimpleFileFfs__() method
792 #
793 # Generate FFS
794 #
795 # @param self The object pointer
796 # @param Rule The rule object used to generate section
797 # @param InputFileList The output file list from GenSection
798 # @retval string Generated FFS file name
799 #
800 def __GenSimpleFileFfs__(self, Rule, InputFileList):
801 FfsOutput = self.OutputPath + \
802 os.sep + \
803 self.__ExtendMacro__(Rule.NameGuid) + \
804 '.ffs'
805
806 GenFdsGlobalVariable.VerboseLogger(self.__ExtendMacro__(Rule.NameGuid))
807 InputSection = []
808 SectionAlignments = []
809 for InputFile in InputFileList:
810 InputSection.append(InputFile)
811 SectionAlignments.append(Rule.SectAlignment)
812
813 if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):
814 PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
815 if len(PcdValue) == 0:
816 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
817 % (Rule.NameGuid))
818 if PcdValue.startswith('{'):
819 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
820 RegistryGuidStr = PcdValue
821 if len(RegistryGuidStr) == 0:
822 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
823 % (Rule.NameGuid))
824 self.ModuleGuid = RegistryGuidStr
825
826 GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,
827 Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
828 self.ModuleGuid, Fixed=Rule.Fixed,
829 CheckSum=Rule.CheckSum, Align=Rule.Alignment,
830 SectionAlign=SectionAlignments
831 )
832 return FfsOutput
833
834 ## __GenComplexFileSection__() method
835 #
836 # Generate section by sections in Rule
837 #
838 # @param self The object pointer
839 # @param Rule The rule object used to generate section
840 # @param FvChildAddr Array of the inside FvImage base address
841 # @param FvParentAddr Parent Fv base address
842 # @retval string File name of the generated section file
843 #
844 def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr):
845 if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):
846 if Rule.KeepReloc != None:
847 self.KeepRelocFromRule = Rule.KeepReloc
848 SectFiles = []
849 SectAlignments = []
850 Index = 1
851 HasGneratedFlag = False
852 if self.PcdIsDriver == 'PEI_PCD_DRIVER':
853 if self.IsBinaryModule:
854 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "PEIPcdDataBase.raw")
855 else:
856 PcdExDbFileName = os.path.join(self.EfiOutputPath, "PEIPcdDataBase.raw")
857 PcdExDbSecName = os.path.join(self.OutputPath, "PEIPcdDataBaseSec.raw")
858 GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,
859 [PcdExDbFileName],
860 "EFI_SECTION_RAW",
861 )
862 SectFiles.append(PcdExDbSecName)
863 SectAlignments.append(None)
864 elif self.PcdIsDriver == 'DXE_PCD_DRIVER':
865 if self.IsBinaryModule:
866 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "DXEPcdDataBase.raw")
867 else:
868 PcdExDbFileName = os.path.join(self.EfiOutputPath, "DXEPcdDataBase.raw")
869 PcdExDbSecName = os.path.join(self.OutputPath, "DXEPcdDataBaseSec.raw")
870 GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,
871 [PcdExDbFileName],
872 "EFI_SECTION_RAW",
873 )
874 SectFiles.append(PcdExDbSecName)
875 SectAlignments.append(None)
876 for Sect in Rule.SectionList:
877 SecIndex = '%d' %Index
878 SectList = []
879 #
880 # Convert Fv Section Type for PI1.1 SMM driver.
881 #
882 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:
883 if Sect.SectionType == 'DXE_DEPEX':
884 Sect.SectionType = 'SMM_DEPEX'
885 #
886 # Framework SMM Driver has no SMM_DEPEX section type
887 #
888 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:
889 if Sect.SectionType == 'SMM_DEPEX':
890 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)
891 #
892 # process the inside FvImage from FvSection or GuidSection
893 #
894 if FvChildAddr != []:
895 if isinstance(Sect, FvImageSection):
896 Sect.FvAddr = FvChildAddr.pop(0)
897 elif isinstance(Sect, GuidSection):
898 Sect.FvAddr = FvChildAddr
899 if FvParentAddr != None and isinstance(Sect, GuidSection):
900 Sect.FvParentAddr = FvParentAddr
901
902 if Rule.KeyStringList != []:
903 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self)
904 else :
905 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self)
906
907 if not HasGneratedFlag:
908 UniVfrOffsetFileSection = ""
909 ModuleFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)
910 InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch]
911 #
912 # Search the source list in InfData to find if there are .vfr file exist.
913 #
914 VfrUniBaseName = {}
915 VfrUniOffsetList = []
916 for SourceFile in InfData.Sources:
917 if SourceFile.Type.upper() == ".VFR" :
918 #
919 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
920 #
921 VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin")
922 if SourceFile.Type.upper() == ".UNI" :
923 #
924 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
925 #
926 VfrUniBaseName["UniOffsetName"] = (self.BaseName + "Strings")
927
928
929 if len(VfrUniBaseName) > 0:
930 VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName)
931 #
932 # Generate the Raw data of raw section
933 #
934 os.path.join( self.OutputPath, self.BaseName + '.offset')
935 UniVfrOffsetFileName = os.path.join( self.OutputPath, self.BaseName + '.offset')
936 UniVfrOffsetFileSection = os.path.join( self.OutputPath, self.BaseName + 'Offset' + '.raw')
937
938 self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName)
939
940 UniVfrOffsetFileNameList = []
941 UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)
942 """Call GenSection"""
943 GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,
944 UniVfrOffsetFileNameList,
945 "EFI_SECTION_RAW"
946 )
947 os.remove(UniVfrOffsetFileName)
948 SectList.append(UniVfrOffsetFileSection)
949 HasGneratedFlag = True
950
951 for SecName in SectList :
952 SectFiles.append(SecName)
953 SectAlignments.append(Align)
954 Index = Index + 1
955 return SectFiles, SectAlignments
956
957 ## __GenComplexFileFfs__() method
958 #
959 # Generate FFS
960 #
961 # @param self The object pointer
962 # @param Rule The rule object used to generate section
963 # @param InputFileList The output file list from GenSection
964 # @retval string Generated FFS file name
965 #
966 def __GenComplexFileFfs__(self, Rule, InputFile, Alignments):
967
968 if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):
969 PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
970 if len(PcdValue) == 0:
971 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
972 % (Rule.NameGuid))
973 if PcdValue.startswith('{'):
974 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
975 RegistryGuidStr = PcdValue
976 if len(RegistryGuidStr) == 0:
977 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
978 % (Rule.NameGuid))
979 self.ModuleGuid = RegistryGuidStr
980
981 FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')
982 GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile,
983 Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
984 self.ModuleGuid, Fixed=Rule.Fixed,
985 CheckSum=Rule.CheckSum, Align=Rule.Alignment,
986 SectionAlign=Alignments
987 )
988 return FfsOutput
989
990 ## __GetGenFfsCmdParameter__() method
991 #
992 # Create parameter string for GenFfs
993 #
994 # @param self The object pointer
995 # @param Rule The rule object used to generate section
996 # @retval tuple (FileType, Fixed, CheckSum, Alignment)
997 #
998 def __GetGenFfsCmdParameter__(self, Rule):
999 result = tuple()
1000 result += ('-t', Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType])
1001 if Rule.Fixed != False:
1002 result += ('-x',)
1003 if Rule.CheckSum != False:
1004 result += ('-s',)
1005
1006 if Rule.Alignment != None and Rule.Alignment != '':
1007 result += ('-a', Rule.Alignment)
1008
1009 return result
1010
1011 ## __GetBuildOutputMapFileVfrUniInfo() method
1012 #
1013 # Find the offset of UNI/INF object offset in the EFI image file.
1014 #
1015 # @param self The object pointer
1016 # @param VfrUniBaseName A name list contain the UNI/INF object name.
1017 # @retval RetValue A list contain offset of UNI/INF object.
1018 #
1019 def __GetBuildOutputMapFileVfrUniInfo(self, VfrUniBaseName):
1020 MapFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".map")
1021 EfiFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".efi")
1022 return GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values())
1023
1024 ## __GenUniVfrOffsetFile() method
1025 #
1026 # Generate the offset file for the module which contain VFR or UNI file.
1027 #
1028 # @param self The object pointer
1029 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
1030 # @param UniVfrOffsetFileName The output offset file name.
1031 #
1032 def __GenUniVfrOffsetFile(self, VfrUniOffsetList, UniVfrOffsetFileName):
1033
1034 try:
1035 fInputfile = open(UniVfrOffsetFileName, "wb+", 0)
1036 except:
1037 EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %UniVfrOffsetFileName,None)
1038
1039 # Use a instance of StringIO to cache data
1040 fStringIO = StringIO.StringIO('')
1041
1042 for Item in VfrUniOffsetList:
1043 if (Item[0].find("Strings") != -1):
1044 #
1045 # UNI offset in image.
1046 # GUID + Offset
1047 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
1048 #
1049 UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
1050 UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]
1051 fStringIO.write(''.join(UniGuid))
1052 UniValue = pack ('Q', int (Item[1], 16))
1053 fStringIO.write (UniValue)
1054 else:
1055 #
1056 # VFR binary offset in image.
1057 # GUID + Offset
1058 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
1059 #
1060 VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
1061 VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]
1062 fStringIO.write(''.join(VfrGuid))
1063 type (Item[1])
1064 VfrValue = pack ('Q', int (Item[1], 16))
1065 fStringIO.write (VfrValue)
1066
1067 #
1068 # write data into file.
1069 #
1070 try :
1071 fInputfile.write (fStringIO.getvalue())
1072 except:
1073 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)
1074
1075 fStringIO.close ()
1076 fInputfile.close ()
1077
1078
1079
1080
1081
1082
1083
1084