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