]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/FfsInfStatement.py
b0b22d194d77dd86456ebdbfac4f0816b4765238
[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 else:
574 #
575 # BaseTools support build same module more than once, the module path with FILE_GUID overridden has
576 # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key,
577 # but the path (self.MetaFile.Path) is the real path
578 #
579 for key in PlatformDataBase.Modules.keys():
580 if InfFileKey == str((PlatformDataBase.Modules[key]).MetaFile.Path):
581 DscArchList.append (Arch)
582 break
583
584 return DscArchList
585
586 ## GetCurrentArch() method
587 #
588 # Get Arch list of the module from this INF is to be placed into flash
589 #
590 # @param self The object pointer
591 # @retval list Arch list
592 #
593 def GetCurrentArch(self) :
594
595 TargetArchList = GenFdsGlobalVariable.ArchList
596
597 PlatformArchList = self.__GetPlatformArchList__()
598
599 CurArchList = TargetArchList
600 if PlatformArchList != []:
601 CurArchList = list(set (TargetArchList) & set (PlatformArchList))
602 GenFdsGlobalVariable.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList))
603
604 ArchList = []
605 if self.KeyStringList != []:
606 for Key in self.KeyStringList:
607 Key = GenFdsGlobalVariable.MacroExtend(Key)
608 Target, Tag, Arch = Key.split('_')
609 if Arch in CurArchList:
610 ArchList.append(Arch)
611 if Target not in self.TargetOverrideList:
612 self.TargetOverrideList.append(Target)
613 else:
614 ArchList = CurArchList
615
616 UseArchList = TargetArchList
617 if self.UseArch != None:
618 UseArchList = []
619 UseArchList.append(self.UseArch)
620 ArchList = list(set (UseArchList) & set (ArchList))
621
622 self.InfFileName = NormPath(self.InfFileName)
623 if len(PlatformArchList) == 0:
624 self.InDsc = False
625 PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)
626 ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")
627 if ErrorCode != 0:
628 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
629 if len(ArchList) == 1:
630 Arch = ArchList[0]
631 return Arch
632 elif len(ArchList) > 1:
633 if len(PlatformArchList) == 0:
634 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))
635 else:
636 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))
637 else:
638 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." \
639 % (self.InfFileName, str(PlatformArchList), GenFdsGlobalVariable.ActivePlatform, str(set (UseArchList) & set (TargetArchList))))
640
641 ## __GetEFIOutPutPath__() method
642 #
643 # Get the output path for generated files
644 #
645 # @param self The object pointer
646 # @retval string Path that output files from this INF go to
647 #
648 def __GetEFIOutPutPath__(self):
649 Arch = ''
650 OutputPath = ''
651 (ModulePath, FileName) = os.path.split(self.InfFileName)
652 Index = FileName.rfind('.')
653 FileName = FileName[0:Index]
654 if self.OverrideGuid:
655 FileName = self.OverrideGuid
656 Arch = "NoneArch"
657 if self.CurrentArch != None:
658 Arch = self.CurrentArch
659
660 OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],
661 Arch ,
662 ModulePath,
663 FileName,
664 'OUTPUT'
665 )
666 OutputPath = os.path.realpath(OutputPath)
667 return OutputPath
668
669 ## __GenSimpleFileSection__() method
670 #
671 # Generate section by specified file name or a list of files with file extension
672 #
673 # @param self The object pointer
674 # @param Rule The rule object used to generate section
675 # @retval string File name of the generated section file
676 #
677 def __GenSimpleFileSection__(self, Rule):
678 #
679 # Prepare the parameter of GenSection
680 #
681 FileList = []
682 OutputFileList = []
683 GenSecInputFile = None
684 if Rule.FileName != None:
685 GenSecInputFile = self.__ExtendMacro__(Rule.FileName)
686 if os.path.isabs(GenSecInputFile):
687 GenSecInputFile = os.path.normpath(GenSecInputFile)
688 else:
689 GenSecInputFile = os.path.normpath(os.path.join(self.EfiOutputPath, GenSecInputFile))
690 else:
691 FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension)
692
693 Index = 1
694 SectionType = Rule.SectionType
695 #
696 # Convert Fv Section Type for PI1.1 SMM driver.
697 #
698 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:
699 if SectionType == 'DXE_DEPEX':
700 SectionType = 'SMM_DEPEX'
701 #
702 # Framework SMM Driver has no SMM_DEPEX section type
703 #
704 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:
705 if SectionType == 'SMM_DEPEX':
706 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)
707 NoStrip = True
708 if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):
709 if self.KeepReloc != None:
710 NoStrip = self.KeepReloc
711 elif Rule.KeepReloc != None:
712 NoStrip = Rule.KeepReloc
713 elif self.ShadowFromInfFile != None:
714 NoStrip = self.ShadowFromInfFile
715
716 if FileList != [] :
717 for File in FileList:
718
719 SecNum = '%d' %Index
720 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
721 Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum
722 Index = Index + 1
723 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)
724 File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)
725
726 #Get PE Section alignment when align is set to AUTO
727 if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):
728 ImageObj = PeImageClass (File)
729 if ImageObj.SectionAlignment < 0x400:
730 self.Alignment = str (ImageObj.SectionAlignment)
731 else:
732 self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
733
734 if not NoStrip:
735 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
736 if not os.path.exists(FileBeforeStrip) or \
737 (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
738 CopyLongFilePath(File, FileBeforeStrip)
739 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
740 GenFdsGlobalVariable.GenerateFirmwareImage(
741 StrippedFile,
742 [File],
743 Strip=True
744 )
745 File = StrippedFile
746
747 if SectionType == 'TE':
748 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
749 GenFdsGlobalVariable.GenerateFirmwareImage(
750 TeFile,
751 [File],
752 Type='te'
753 )
754 File = TeFile
755
756 GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType])
757 OutputFileList.append(OutputFile)
758 else:
759 SecNum = '%d' %Index
760 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
761 Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum
762 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)
763 GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch)
764
765 #Get PE Section alignment when align is set to AUTO
766 if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):
767 ImageObj = PeImageClass (GenSecInputFile)
768 if ImageObj.SectionAlignment < 0x400:
769 self.Alignment = str (ImageObj.SectionAlignment)
770 else:
771 self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
772
773 if not NoStrip:
774 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
775 if not os.path.exists(FileBeforeStrip) or \
776 (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)):
777 CopyLongFilePath(GenSecInputFile, FileBeforeStrip)
778
779 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
780 GenFdsGlobalVariable.GenerateFirmwareImage(
781 StrippedFile,
782 [GenSecInputFile],
783 Strip=True
784 )
785 GenSecInputFile = StrippedFile
786
787 if SectionType == 'TE':
788 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
789 GenFdsGlobalVariable.GenerateFirmwareImage(
790 TeFile,
791 [GenSecInputFile],
792 Type='te'
793 )
794 GenSecInputFile = TeFile
795
796 GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType])
797 OutputFileList.append(OutputFile)
798
799 return OutputFileList
800
801 ## __GenSimpleFileFfs__() method
802 #
803 # Generate FFS
804 #
805 # @param self The object pointer
806 # @param Rule The rule object used to generate section
807 # @param InputFileList The output file list from GenSection
808 # @retval string Generated FFS file name
809 #
810 def __GenSimpleFileFfs__(self, Rule, InputFileList):
811 FfsOutput = self.OutputPath + \
812 os.sep + \
813 self.__ExtendMacro__(Rule.NameGuid) + \
814 '.ffs'
815
816 GenFdsGlobalVariable.VerboseLogger(self.__ExtendMacro__(Rule.NameGuid))
817 InputSection = []
818 SectionAlignments = []
819 for InputFile in InputFileList:
820 InputSection.append(InputFile)
821 SectionAlignments.append(Rule.SectAlignment)
822
823 if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):
824 PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
825 if len(PcdValue) == 0:
826 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
827 % (Rule.NameGuid))
828 if PcdValue.startswith('{'):
829 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
830 RegistryGuidStr = PcdValue
831 if len(RegistryGuidStr) == 0:
832 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
833 % (Rule.NameGuid))
834 self.ModuleGuid = RegistryGuidStr
835
836 GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,
837 Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
838 self.ModuleGuid, Fixed=Rule.Fixed,
839 CheckSum=Rule.CheckSum, Align=Rule.Alignment,
840 SectionAlign=SectionAlignments
841 )
842 return FfsOutput
843
844 ## __GenComplexFileSection__() method
845 #
846 # Generate section by sections in Rule
847 #
848 # @param self The object pointer
849 # @param Rule The rule object used to generate section
850 # @param FvChildAddr Array of the inside FvImage base address
851 # @param FvParentAddr Parent Fv base address
852 # @retval string File name of the generated section file
853 #
854 def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr):
855 if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):
856 if Rule.KeepReloc != None:
857 self.KeepRelocFromRule = Rule.KeepReloc
858 SectFiles = []
859 SectAlignments = []
860 Index = 1
861 HasGneratedFlag = False
862 if self.PcdIsDriver == 'PEI_PCD_DRIVER':
863 if self.IsBinaryModule:
864 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "PEIPcdDataBase.raw")
865 else:
866 PcdExDbFileName = os.path.join(self.EfiOutputPath, "PEIPcdDataBase.raw")
867 PcdExDbSecName = os.path.join(self.OutputPath, "PEIPcdDataBaseSec.raw")
868 GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,
869 [PcdExDbFileName],
870 "EFI_SECTION_RAW",
871 )
872 SectFiles.append(PcdExDbSecName)
873 SectAlignments.append(None)
874 elif self.PcdIsDriver == 'DXE_PCD_DRIVER':
875 if self.IsBinaryModule:
876 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "DXEPcdDataBase.raw")
877 else:
878 PcdExDbFileName = os.path.join(self.EfiOutputPath, "DXEPcdDataBase.raw")
879 PcdExDbSecName = os.path.join(self.OutputPath, "DXEPcdDataBaseSec.raw")
880 GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,
881 [PcdExDbFileName],
882 "EFI_SECTION_RAW",
883 )
884 SectFiles.append(PcdExDbSecName)
885 SectAlignments.append(None)
886 for Sect in Rule.SectionList:
887 SecIndex = '%d' %Index
888 SectList = []
889 #
890 # Convert Fv Section Type for PI1.1 SMM driver.
891 #
892 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:
893 if Sect.SectionType == 'DXE_DEPEX':
894 Sect.SectionType = 'SMM_DEPEX'
895 #
896 # Framework SMM Driver has no SMM_DEPEX section type
897 #
898 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:
899 if Sect.SectionType == 'SMM_DEPEX':
900 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)
901 #
902 # process the inside FvImage from FvSection or GuidSection
903 #
904 if FvChildAddr != []:
905 if isinstance(Sect, FvImageSection):
906 Sect.FvAddr = FvChildAddr.pop(0)
907 elif isinstance(Sect, GuidSection):
908 Sect.FvAddr = FvChildAddr
909 if FvParentAddr != None and isinstance(Sect, GuidSection):
910 Sect.FvParentAddr = FvParentAddr
911
912 if Rule.KeyStringList != []:
913 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self)
914 else :
915 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self)
916
917 if not HasGneratedFlag:
918 UniVfrOffsetFileSection = ""
919 ModuleFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)
920 InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch]
921 #
922 # Search the source list in InfData to find if there are .vfr file exist.
923 #
924 VfrUniBaseName = {}
925 VfrUniOffsetList = []
926 for SourceFile in InfData.Sources:
927 if SourceFile.Type.upper() == ".VFR" :
928 #
929 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
930 #
931 VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin")
932 if SourceFile.Type.upper() == ".UNI" :
933 #
934 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
935 #
936 VfrUniBaseName["UniOffsetName"] = (self.BaseName + "Strings")
937
938
939 if len(VfrUniBaseName) > 0:
940 VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName)
941 #
942 # Generate the Raw data of raw section
943 #
944 os.path.join( self.OutputPath, self.BaseName + '.offset')
945 UniVfrOffsetFileName = os.path.join( self.OutputPath, self.BaseName + '.offset')
946 UniVfrOffsetFileSection = os.path.join( self.OutputPath, self.BaseName + 'Offset' + '.raw')
947
948 self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName)
949
950 UniVfrOffsetFileNameList = []
951 UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)
952 """Call GenSection"""
953 GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,
954 UniVfrOffsetFileNameList,
955 "EFI_SECTION_RAW"
956 )
957 os.remove(UniVfrOffsetFileName)
958 SectList.append(UniVfrOffsetFileSection)
959 HasGneratedFlag = True
960
961 for SecName in SectList :
962 SectFiles.append(SecName)
963 SectAlignments.append(Align)
964 Index = Index + 1
965 return SectFiles, SectAlignments
966
967 ## __GenComplexFileFfs__() method
968 #
969 # Generate FFS
970 #
971 # @param self The object pointer
972 # @param Rule The rule object used to generate section
973 # @param InputFileList The output file list from GenSection
974 # @retval string Generated FFS file name
975 #
976 def __GenComplexFileFfs__(self, Rule, InputFile, Alignments):
977
978 if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):
979 PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
980 if len(PcdValue) == 0:
981 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
982 % (Rule.NameGuid))
983 if PcdValue.startswith('{'):
984 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
985 RegistryGuidStr = PcdValue
986 if len(RegistryGuidStr) == 0:
987 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
988 % (Rule.NameGuid))
989 self.ModuleGuid = RegistryGuidStr
990
991 FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')
992 GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile,
993 Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
994 self.ModuleGuid, Fixed=Rule.Fixed,
995 CheckSum=Rule.CheckSum, Align=Rule.Alignment,
996 SectionAlign=Alignments
997 )
998 return FfsOutput
999
1000 ## __GetGenFfsCmdParameter__() method
1001 #
1002 # Create parameter string for GenFfs
1003 #
1004 # @param self The object pointer
1005 # @param Rule The rule object used to generate section
1006 # @retval tuple (FileType, Fixed, CheckSum, Alignment)
1007 #
1008 def __GetGenFfsCmdParameter__(self, Rule):
1009 result = tuple()
1010 result += ('-t', Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType])
1011 if Rule.Fixed != False:
1012 result += ('-x',)
1013 if Rule.CheckSum != False:
1014 result += ('-s',)
1015
1016 if Rule.Alignment != None and Rule.Alignment != '':
1017 result += ('-a', Rule.Alignment)
1018
1019 return result
1020
1021 ## __GetBuildOutputMapFileVfrUniInfo() method
1022 #
1023 # Find the offset of UNI/INF object offset in the EFI image file.
1024 #
1025 # @param self The object pointer
1026 # @param VfrUniBaseName A name list contain the UNI/INF object name.
1027 # @retval RetValue A list contain offset of UNI/INF object.
1028 #
1029 def __GetBuildOutputMapFileVfrUniInfo(self, VfrUniBaseName):
1030 MapFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".map")
1031 EfiFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".efi")
1032 return GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values())
1033
1034 ## __GenUniVfrOffsetFile() method
1035 #
1036 # Generate the offset file for the module which contain VFR or UNI file.
1037 #
1038 # @param self The object pointer
1039 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
1040 # @param UniVfrOffsetFileName The output offset file name.
1041 #
1042 def __GenUniVfrOffsetFile(self, VfrUniOffsetList, UniVfrOffsetFileName):
1043
1044 try:
1045 fInputfile = open(UniVfrOffsetFileName, "wb+", 0)
1046 except:
1047 EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %UniVfrOffsetFileName,None)
1048
1049 # Use a instance of StringIO to cache data
1050 fStringIO = StringIO.StringIO('')
1051
1052 for Item in VfrUniOffsetList:
1053 if (Item[0].find("Strings") != -1):
1054 #
1055 # UNI offset in image.
1056 # GUID + Offset
1057 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
1058 #
1059 UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
1060 UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]
1061 fStringIO.write(''.join(UniGuid))
1062 UniValue = pack ('Q', int (Item[1], 16))
1063 fStringIO.write (UniValue)
1064 else:
1065 #
1066 # VFR binary offset in image.
1067 # GUID + Offset
1068 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
1069 #
1070 VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
1071 VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]
1072 fStringIO.write(''.join(VfrGuid))
1073 type (Item[1])
1074 VfrValue = pack ('Q', int (Item[1], 16))
1075 fStringIO.write (VfrValue)
1076
1077 #
1078 # write data into file.
1079 #
1080 try :
1081 fInputfile.write (fStringIO.getvalue())
1082 except:
1083 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)
1084
1085 fStringIO.close ()
1086 fInputfile.close ()
1087
1088
1089
1090
1091
1092
1093
1094