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