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