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