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