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