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