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