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