]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/FfsInfStatement.py
Sync BaseTools Branch (version r2149) to EDKII main trunk.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FfsInfStatement.py
1 ## @file
2 # process FFS generation from INF statement
3 #
4 # Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
5 #
6 # This program and the accompanying materials
7 # are licensed and made available under the terms and conditions of the BSD License
8 # which accompanies this distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
10 #
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13 #
14
15 ##
16 # Import Modules
17 #
18 import Rule
19 import os
20 import shutil
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.String import *
32 from Common.Misc import PathClass
33 from Common.Misc import GuidStructureByteArrayToGuidString
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
40 ## generate FFS from INF
41 #
42 #
43 class FfsInfStatement(FfsInfStatementClassObject):
44 ## The constructor
45 #
46 # @param self The object pointer
47 #
48 def __init__(self):
49 FfsInfStatementClassObject.__init__(self)
50 self.TargetOverrideList = []
51 self.ShadowFromInfFile = None
52 self.KeepRelocFromRule = None
53 self.InDsc = True
54 self.OptRomDefs = {}
55 self.PiSpecVersion = '0x00000000'
56
57 ## __InfParse() method
58 #
59 # Parse inf file to get module information
60 #
61 # @param self The object pointer
62 # @param Dict dictionary contains macro and value pair
63 #
64 def __InfParse__(self, Dict = {}):
65
66 GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName)
67
68 self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '')
69 if self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' :
70 self.InfFileName = self.InfFileName[1:]
71
72 if self.InfFileName.find('$') == -1:
73 InfPath = NormPath(self.InfFileName)
74 if not os.path.exists(InfPath):
75 InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath)
76 if not os.path.exists(InfPath):
77 EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName))
78
79 self.CurrentArch = self.GetCurrentArch()
80 #
81 # Get the InfClass object
82 #
83
84 PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)
85 ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")
86 if ErrorCode != 0:
87 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
88
89 if self.CurrentArch != None:
90
91 Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch]
92 #
93 # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath
94 #
95 self.BaseName = Inf.BaseName
96 self.ModuleGuid = Inf.Guid
97 self.ModuleType = Inf.ModuleType
98 if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:
99 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']
100 if Inf.AutoGenVersion < 0x00010005:
101 self.ModuleType = Inf.ComponentType
102 self.VersionString = Inf.Version
103 self.BinFileList = Inf.Binaries
104 self.SourceFileList = Inf.Sources
105 if self.KeepReloc == None and Inf.Shadow:
106 self.ShadowFromInfFile = Inf.Shadow
107
108 else:
109 Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON']
110 self.BaseName = Inf.BaseName
111 self.ModuleGuid = Inf.Guid
112 self.ModuleType = Inf.ModuleType
113 if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:
114 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']
115 self.VersionString = Inf.Version
116 self.BinFileList = Inf.Binaries
117 self.SourceFileList = Inf.Sources
118 if self.BinFileList == []:
119 EdkLogger.error("GenFds", GENFDS_ERROR,
120 "INF %s specified in FDF could not be found in build ARCH %s!" \
121 % (self.InfFileName, GenFdsGlobalVariable.ArchList))
122
123 if len(self.SourceFileList) != 0 and not self.InDsc:
124 EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName))
125
126 if self.ModuleType == 'SMM_CORE' and int(self.PiSpecVersion, 16) < 0x0001000A:
127 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)
128
129 if Inf._Defs != None and len(Inf._Defs) > 0:
130 self.OptRomDefs.update(Inf._Defs)
131
132 GenFdsGlobalVariable.VerboseLogger( "BaseName : %s" %self.BaseName)
133 GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" %self.ModuleGuid)
134 GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" %self.ModuleType)
135 GenFdsGlobalVariable.VerboseLogger("VersionString : %s" %self.VersionString)
136 GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" %self.InfFileName)
137
138 #
139 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\
140 #
141
142 self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \
143 self.ModuleGuid + self.BaseName)
144 if not os.path.exists(self.OutputPath) :
145 os.makedirs(self.OutputPath)
146
147 self.EfiOutputPath = self.__GetEFIOutPutPath__()
148 GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)
149
150 ## GenFfs() method
151 #
152 # Generate FFS
153 #
154 # @param self The object pointer
155 # @param Dict dictionary contains macro and value pair
156 # @param FvChildAddr Array of the inside FvImage base address
157 # @param FvParentAddr Parent Fv base address
158 # @retval string Generated FFS file name
159 #
160 def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None):
161 #
162 # Parse Inf file get Module related information
163 #
164
165 self.__InfParse__(Dict)
166
167 #
168 # Allow binary type module not specify override rule in FDF file.
169 #
170 if len(self.BinFileList) >0 and not self.InDsc:
171 if self.Rule == None or self.Rule == "":
172 self.Rule = "BINARY"
173
174 #
175 # Get the rule of how to generate Ffs file
176 #
177 Rule = self.__GetRule__()
178 GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName)
179 #
180 # Convert Fv File Type for PI1.1 SMM driver.
181 #
182 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:
183 if Rule.FvFileType == 'DRIVER':
184 Rule.FvFileType = 'SMM'
185 #
186 # Framework SMM Driver has no SMM FV file type
187 #
188 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:
189 if Rule.FvFileType == 'SMM' or Rule.FvFileType == 'SMM_CORE':
190 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File=self.InfFileName)
191 #
192 # For the rule only has simpleFile
193 #
194 if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) :
195 SectionOutputList = self.__GenSimpleFileSection__(Rule)
196 FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList)
197 return FfsOutput
198 #
199 # For Rule has ComplexFile
200 #
201 elif isinstance(Rule, RuleComplexFile.RuleComplexFile):
202 InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr)
203 FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments)
204
205 return FfsOutput
206
207 ## __ExtendMacro__() method
208 #
209 # Replace macro with its value
210 #
211 # @param self The object pointer
212 # @param String The string to be replaced
213 # @retval string Macro replaced string
214 #
215 def __ExtendMacro__ (self, String):
216 MacroDict = {
217 '$(INF_OUTPUT)' : self.EfiOutputPath,
218 '$(MODULE_NAME)' : self.BaseName,
219 '$(BUILD_NUMBER)': self.BuildNum,
220 '$(INF_VERSION)' : self.VersionString,
221 '$(NAMED_GUID)' : self.ModuleGuid
222 }
223 String = GenFdsGlobalVariable.MacroExtend(String, MacroDict)
224 return String
225
226 ## __GetRule__() method
227 #
228 # Get correct rule for generating FFS for this INF
229 #
230 # @param self The object pointer
231 # @retval Rule Rule object
232 #
233 def __GetRule__ (self) :
234 CurrentArchList = []
235 if self.CurrentArch == None:
236 CurrentArchList = ['common']
237 else:
238 CurrentArchList.append(self.CurrentArch)
239
240 for CurrentArch in CurrentArchList:
241 RuleName = 'RULE' + \
242 '.' + \
243 CurrentArch.upper() + \
244 '.' + \
245 self.ModuleType.upper()
246 if self.Rule != None:
247 RuleName = RuleName + \
248 '.' + \
249 self.Rule.upper()
250
251 Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)
252 if Rule != None:
253 GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)
254 return Rule
255
256 RuleName = 'RULE' + \
257 '.' + \
258 'COMMON' + \
259 '.' + \
260 self.ModuleType.upper()
261
262 if self.Rule != None:
263 RuleName = RuleName + \
264 '.' + \
265 self.Rule.upper()
266
267 GenFdsGlobalVariable.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName, self.InfFileName))
268
269 Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)
270 if Rule != None:
271 GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)
272 return Rule
273
274 if Rule == None :
275 EdkLogger.error("GenFds", GENFDS_ERROR, 'Don\'t Find common rule %s for INF %s' \
276 % (RuleName, self.InfFileName))
277
278 ## __GetPlatformArchList__() method
279 #
280 # Get Arch list this INF built under
281 #
282 # @param self The object pointer
283 # @retval list Arch list
284 #
285 def __GetPlatformArchList__(self):
286
287 InfFileKey = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))
288 DscArchList = []
289 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32']
290 if PlatformDataBase != None:
291 if InfFileKey in PlatformDataBase.Modules:
292 DscArchList.append ('IA32')
293
294 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'X64']
295 if PlatformDataBase != None:
296 if InfFileKey in PlatformDataBase.Modules:
297 DscArchList.append ('X64')
298
299 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IPF']
300 if PlatformDataBase != None:
301 if InfFileKey in (PlatformDataBase.Modules):
302 DscArchList.append ('IPF')
303
304 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'ARM']
305 if PlatformDataBase != None:
306 if InfFileKey in (PlatformDataBase.Modules):
307 DscArchList.append ('ARM')
308
309 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'EBC']
310 if PlatformDataBase != None:
311 if InfFileKey in (PlatformDataBase.Modules):
312 DscArchList.append ('EBC')
313
314 return DscArchList
315
316 ## GetCurrentArch() method
317 #
318 # Get Arch list of the module from this INF is to be placed into flash
319 #
320 # @param self The object pointer
321 # @retval list Arch list
322 #
323 def GetCurrentArch(self) :
324
325 TargetArchList = GenFdsGlobalVariable.ArchList
326
327 PlatformArchList = self.__GetPlatformArchList__()
328
329 CurArchList = TargetArchList
330 if PlatformArchList != []:
331 CurArchList = list(set (TargetArchList) & set (PlatformArchList))
332 GenFdsGlobalVariable.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList))
333
334 ArchList = []
335 if self.KeyStringList != []:
336 for Key in self.KeyStringList:
337 Key = GenFdsGlobalVariable.MacroExtend(Key)
338 Target, Tag, Arch = Key.split('_')
339 if Arch in CurArchList:
340 ArchList.append(Arch)
341 if Target not in self.TargetOverrideList:
342 self.TargetOverrideList.append(Target)
343 else:
344 ArchList = CurArchList
345
346 UseArchList = TargetArchList
347 if self.UseArch != None:
348 UseArchList = []
349 UseArchList.append(self.UseArch)
350 ArchList = list(set (UseArchList) & set (ArchList))
351
352 self.InfFileName = NormPath(self.InfFileName)
353 if len(PlatformArchList) == 0:
354 self.InDsc = False
355 PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)
356 ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")
357 if ErrorCode != 0:
358 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
359 if len(ArchList) == 1:
360 Arch = ArchList[0]
361 return Arch
362 elif len(ArchList) > 1:
363 if len(PlatformArchList) == 0:
364 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))
365 else:
366 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))
367 else:
368 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." \
369 % (self.InfFileName, str(PlatformArchList), GenFdsGlobalVariable.ActivePlatform, str(set (UseArchList) & set (TargetArchList))))
370
371 ## __GetEFIOutPutPath__() method
372 #
373 # Get the output path for generated files
374 #
375 # @param self The object pointer
376 # @retval string Path that output files from this INF go to
377 #
378 def __GetEFIOutPutPath__(self):
379 Arch = ''
380 OutputPath = ''
381 (ModulePath, FileName) = os.path.split(self.InfFileName)
382 Index = FileName.find('.')
383 FileName = FileName[0:Index]
384 Arch = "NoneArch"
385 if self.CurrentArch != None:
386 Arch = self.CurrentArch
387
388 OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],
389 Arch ,
390 ModulePath,
391 FileName,
392 'OUTPUT'
393 )
394 OutputPath = os.path.realpath(OutputPath)
395 return OutputPath
396
397 ## __GenSimpleFileSection__() method
398 #
399 # Generate section by specified file name or a list of files with file extension
400 #
401 # @param self The object pointer
402 # @param Rule The rule object used to generate section
403 # @retval string File name of the generated section file
404 #
405 def __GenSimpleFileSection__(self, Rule):
406 #
407 # Prepare the parameter of GenSection
408 #
409 FileList = []
410 OutputFileList = []
411 GenSecInputFile = None
412 if Rule.FileName != None:
413 GenSecInputFile = self.__ExtendMacro__(Rule.FileName)
414 if os.path.isabs(GenSecInputFile):
415 GenSecInputFile = os.path.normpath(GenSecInputFile)
416 else:
417 GenSecInputFile = os.path.normpath(os.path.join(self.EfiOutputPath, GenSecInputFile))
418 else:
419 FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension)
420
421 Index = 1
422 SectionType = Rule.SectionType
423 #
424 # Convert Fv Section Type for PI1.1 SMM driver.
425 #
426 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:
427 if SectionType == 'DXE_DEPEX':
428 SectionType = 'SMM_DEPEX'
429 #
430 # Framework SMM Driver has no SMM_DEPEX section type
431 #
432 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:
433 if SectionType == 'SMM_DEPEX':
434 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)
435 NoStrip = True
436 if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):
437 if self.KeepReloc != None:
438 NoStrip = self.KeepReloc
439 elif Rule.KeepReloc != None:
440 NoStrip = Rule.KeepReloc
441 elif self.ShadowFromInfFile != None:
442 NoStrip = self.ShadowFromInfFile
443
444 if FileList != [] :
445 for File in FileList:
446
447 SecNum = '%d' %Index
448 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
449 Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum
450 Index = Index + 1
451 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)
452 File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)
453
454 #Get PE Section alignment when align is set to AUTO
455 if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):
456 ImageObj = PeImageClass (File)
457 if ImageObj.SectionAlignment < 0x400:
458 self.Alignment = str (ImageObj.SectionAlignment)
459 else:
460 self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
461
462 if not NoStrip:
463 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
464 if not os.path.exists(FileBeforeStrip) or \
465 (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
466 shutil.copyfile(File, FileBeforeStrip)
467 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
468 GenFdsGlobalVariable.GenerateFirmwareImage(
469 StrippedFile,
470 [File],
471 Strip=True
472 )
473 File = StrippedFile
474
475 if SectionType == 'TE':
476 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
477 GenFdsGlobalVariable.GenerateFirmwareImage(
478 TeFile,
479 [File],
480 Type='te'
481 )
482 File = TeFile
483
484 GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType])
485 OutputFileList.append(OutputFile)
486 else:
487 SecNum = '%d' %Index
488 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
489 Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum
490 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)
491 GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch)
492
493 #Get PE Section alignment when align is set to AUTO
494 if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):
495 ImageObj = PeImageClass (GenSecInputFile)
496 if ImageObj.SectionAlignment < 0x400:
497 self.Alignment = str (ImageObj.SectionAlignment)
498 else:
499 self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
500
501 if not NoStrip:
502 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
503 if not os.path.exists(FileBeforeStrip) or \
504 (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)):
505 shutil.copyfile(GenSecInputFile, FileBeforeStrip)
506 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
507 GenFdsGlobalVariable.GenerateFirmwareImage(
508 StrippedFile,
509 [GenSecInputFile],
510 Strip=True
511 )
512 GenSecInputFile = StrippedFile
513
514 if SectionType == 'TE':
515 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
516 GenFdsGlobalVariable.GenerateFirmwareImage(
517 TeFile,
518 [GenSecInputFile],
519 Type='te'
520 )
521 GenSecInputFile = TeFile
522
523 GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType])
524 OutputFileList.append(OutputFile)
525
526 return OutputFileList
527
528 ## __GenSimpleFileFfs__() method
529 #
530 # Generate FFS
531 #
532 # @param self The object pointer
533 # @param Rule The rule object used to generate section
534 # @param InputFileList The output file list from GenSection
535 # @retval string Generated FFS file name
536 #
537 def __GenSimpleFileFfs__(self, Rule, InputFileList):
538 FfsOutput = self.OutputPath + \
539 os.sep + \
540 self.__ExtendMacro__(Rule.NameGuid) + \
541 '.ffs'
542
543 GenFdsGlobalVariable.VerboseLogger(self.__ExtendMacro__(Rule.NameGuid))
544 InputSection = []
545 SectionAlignments = []
546 for InputFile in InputFileList:
547 InputSection.append(InputFile)
548 SectionAlignments.append(Rule.SectAlignment)
549
550 if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):
551 PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
552 if len(PcdValue) == 0:
553 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
554 % (Rule.NameGuid))
555 if PcdValue.startswith('{'):
556 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
557 RegistryGuidStr = PcdValue
558 if len(RegistryGuidStr) == 0:
559 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
560 % (Rule.NameGuid))
561 self.ModuleGuid = RegistryGuidStr
562
563 GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,
564 Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
565 self.ModuleGuid, Fixed=Rule.Fixed,
566 CheckSum=Rule.CheckSum, Align=Rule.Alignment,
567 SectionAlign=SectionAlignments
568 )
569 return FfsOutput
570
571 ## __GenComplexFileSection__() method
572 #
573 # Generate section by sections in Rule
574 #
575 # @param self The object pointer
576 # @param Rule The rule object used to generate section
577 # @param FvChildAddr Array of the inside FvImage base address
578 # @param FvParentAddr Parent Fv base address
579 # @retval string File name of the generated section file
580 #
581 def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr):
582 if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):
583 if Rule.KeepReloc != None:
584 self.KeepRelocFromRule = Rule.KeepReloc
585 SectFiles = []
586 SectAlignments = []
587 Index = 1
588 HasGneratedFlag = False
589 for Sect in Rule.SectionList:
590 SecIndex = '%d' %Index
591 SectList = []
592 #
593 # Convert Fv Section Type for PI1.1 SMM driver.
594 #
595 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:
596 if Sect.SectionType == 'DXE_DEPEX':
597 Sect.SectionType = 'SMM_DEPEX'
598 #
599 # Framework SMM Driver has no SMM_DEPEX section type
600 #
601 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:
602 if Sect.SectionType == 'SMM_DEPEX':
603 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)
604 #
605 # process the inside FvImage from FvSection or GuidSection
606 #
607 if FvChildAddr != []:
608 if isinstance(Sect, FvImageSection):
609 Sect.FvAddr = FvChildAddr.pop(0)
610 elif isinstance(Sect, GuidSection):
611 Sect.FvAddr = FvChildAddr
612 if FvParentAddr != None and isinstance(Sect, GuidSection):
613 Sect.FvParentAddr = FvParentAddr
614
615 if Rule.KeyStringList != []:
616 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self)
617 else :
618 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self)
619
620 if not HasGneratedFlag:
621 UniVfrOffsetFileSection = ""
622 ModuleFileName = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)
623 InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch]
624 #
625 # Search the source list in InfData to find if there are .vfr file exist.
626 #
627 VfrUniBaseName = {}
628 VfrUniOffsetList = []
629 for SourceFile in InfData.Sources:
630 if SourceFile.Type.upper() == ".VFR" :
631 #
632 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
633 #
634 VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin")
635 if SourceFile.Type.upper() == ".UNI" :
636 #
637 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
638 #
639 VfrUniBaseName["UniOffsetName"] = (self.BaseName + "Strings")
640
641
642 if len(VfrUniBaseName) > 0:
643 VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName)
644 #
645 # Generate the Raw data of raw section
646 #
647 os.path.join( self.OutputPath, self.BaseName + '.offset')
648 UniVfrOffsetFileName = os.path.join( self.OutputPath, self.BaseName + '.offset')
649 UniVfrOffsetFileSection = os.path.join( self.OutputPath, self.BaseName + 'Offset' + '.raw')
650
651 self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName)
652
653 UniVfrOffsetFileNameList = []
654 UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)
655 """Call GenSection"""
656 GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,
657 UniVfrOffsetFileNameList,
658 "EFI_SECTION_RAW"
659 )
660 os.remove(UniVfrOffsetFileName)
661 SectList.append(UniVfrOffsetFileSection)
662 HasGneratedFlag = True
663
664 for SecName in SectList :
665 SectFiles.append(SecName)
666 SectAlignments.append(Align)
667 Index = Index + 1
668 return SectFiles, SectAlignments
669
670 ## __GenComplexFileFfs__() method
671 #
672 # Generate FFS
673 #
674 # @param self The object pointer
675 # @param Rule The rule object used to generate section
676 # @param InputFileList The output file list from GenSection
677 # @retval string Generated FFS file name
678 #
679 def __GenComplexFileFfs__(self, Rule, InputFile, Alignments):
680
681 if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):
682 PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
683 if len(PcdValue) == 0:
684 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
685 % (Rule.NameGuid))
686 if PcdValue.startswith('{'):
687 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
688 RegistryGuidStr = PcdValue
689 if len(RegistryGuidStr) == 0:
690 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
691 % (Rule.NameGuid))
692 self.ModuleGuid = RegistryGuidStr
693
694 FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')
695 GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile,
696 Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
697 self.ModuleGuid, Fixed=Rule.Fixed,
698 CheckSum=Rule.CheckSum, Align=Rule.Alignment,
699 SectionAlign=Alignments
700 )
701 return FfsOutput
702
703 ## __GetGenFfsCmdParameter__() method
704 #
705 # Create parameter string for GenFfs
706 #
707 # @param self The object pointer
708 # @param Rule The rule object used to generate section
709 # @retval tuple (FileType, Fixed, CheckSum, Alignment)
710 #
711 def __GetGenFfsCmdParameter__(self, Rule):
712 result = tuple()
713 result += ('-t', Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType])
714 if Rule.Fixed != False:
715 result += ('-x',)
716 if Rule.CheckSum != False:
717 result += ('-s',)
718
719 if Rule.Alignment != None and Rule.Alignment != '':
720 result += ('-a', Rule.Alignment)
721
722 return result
723
724 ## __GetBuildOutputMapFileVfrUniInfo() method
725 #
726 # Find the offset of UNI/INF object offset in the EFI image file.
727 #
728 # @param self The object pointer
729 # @param VfrUniBaseName A name list contain the UNI/INF object name.
730 # @retval RetValue A list contain offset of UNI/INF object.
731 #
732 def __GetBuildOutputMapFileVfrUniInfo(self, VfrUniBaseName):
733
734 RetValue = []
735
736 MapFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".map")
737 try:
738 fInputfile = open(MapFileName, "r", 0)
739 try:
740 FileLinesList = fInputfile.readlines()
741 except:
742 EdkLogger.error("GenFds", FILE_READ_FAILURE, "File read failed for %s" %MapFileName,None)
743 finally:
744 fInputfile.close()
745 except:
746 EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %MapFileName,None)
747
748 IsHex = False
749 for eachLine in FileLinesList:
750 for eachName in VfrUniBaseName.values():
751 if eachLine.find(eachName) != -1:
752 eachLine = eachLine.strip()
753 Element = eachLine.split()
754 #
755 # MSFT/ICC/EBC map file
756 #
757 if (len(Element) == 4):
758 try:
759 int (Element[2], 16)
760 IsHex = True
761 except:
762 IsHex = False
763
764 if IsHex:
765 RetValue.append((eachName, Element[2]))
766 IsHex = False
767 #
768 # GCC map file
769 #
770 elif (len(Element) == 2) and Element[0].startswith("0x"):
771 RetValue.append((eachName, Element[0]))
772
773 return RetValue
774
775 ## __GenUniVfrOffsetFile() method
776 #
777 # Generate the offset file for the module which contain VFR or UNI file.
778 #
779 # @param self The object pointer
780 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
781 # @param UniVfrOffsetFileName The output offset file name.
782 #
783 def __GenUniVfrOffsetFile(self, VfrUniOffsetList, UniVfrOffsetFileName):
784
785 try:
786 fInputfile = open(UniVfrOffsetFileName, "wb+", 0)
787 except:
788 EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %UniVfrOffsetFileName,None)
789
790 # Use a instance of StringIO to cache data
791 fStringIO = StringIO.StringIO('')
792
793 for Item in VfrUniOffsetList:
794 if (Item[0].find("Strings") != -1):
795 #
796 # UNI offset in image.
797 # GUID + Offset
798 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
799 #
800 UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
801 UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]
802 fStringIO.write(''.join(UniGuid))
803 UniValue = pack ('Q', int (Item[1], 16))
804 fStringIO.write (UniValue)
805 else:
806 #
807 # VFR binary offset in image.
808 # GUID + Offset
809 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
810 #
811 VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
812 VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]
813 fStringIO.write(''.join(VfrGuid))
814 type (Item[1])
815 VfrValue = pack ('Q', int (Item[1], 16))
816 fStringIO.write (VfrValue)
817
818 #
819 # write data into file.
820 #
821 try :
822 fInputfile.write (fStringIO.getvalue())
823 except:
824 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)
825
826 fStringIO.close ()
827 fInputfile.close ()
828
829
830
831
832
833
834
835