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