2 # process FFS generation from INF statement
4 # Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
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
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.
23 from GenFdsGlobalVariable
import GenFdsGlobalVariable
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
40 ## generate FFS from INF
43 class FfsInfStatement(FfsInfStatementClassObject
):
46 # @param self The object pointer
49 FfsInfStatementClassObject
.__init
__(self
)
50 self
.TargetOverrideList
= []
51 self
.ShadowFromInfFile
= None
52 self
.KeepRelocFromRule
= None
55 self
.PiSpecVersion
= '0x00000000'
57 self
.FinalBuildTargetList
= []
59 ## GetFinalBuildTargetList() method
61 # Get final build target list
62 def GetFinalBuildTargetList(self
):
63 if not self
.InfModule
or not self
.CurrentArch
:
65 if not self
.FinalBuildTargetList
:
66 self
.FinalBuildTargetList
= GenFdsGlobalVariable
.GetModuleCodaTargetList(self
.InfModule
, self
.CurrentArch
)
67 return self
.FinalBuildTargetList
69 ## __InfParse() method
71 # Parse inf file to get module information
73 # @param self The object pointer
74 # @param Dict dictionary contains macro and value pair
76 def __InfParse__(self
, Dict
= {}):
78 GenFdsGlobalVariable
.VerboseLogger( " Begine parsing INf file : %s" %self
.InfFileName
)
80 self
.InfFileName
= self
.InfFileName
.replace('$(WORKSPACE)', '')
81 if self
.InfFileName
[0] == '\\' or self
.InfFileName
[0] == '/' :
82 self
.InfFileName
= self
.InfFileName
[1:]
84 if self
.InfFileName
.find('$') == -1:
85 InfPath
= NormPath(self
.InfFileName
)
86 if not os
.path
.exists(InfPath
):
87 InfPath
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(InfPath
)
88 if not os
.path
.exists(InfPath
):
89 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Non-existant Module %s !" % (self
.InfFileName
))
91 self
.CurrentArch
= self
.GetCurrentArch()
93 # Get the InfClass object
96 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
97 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
99 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
101 if self
.CurrentArch
!= None:
103 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, self
.CurrentArch
]
105 # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath
107 self
.BaseName
= Inf
.BaseName
108 self
.ModuleGuid
= Inf
.Guid
109 self
.ModuleType
= Inf
.ModuleType
110 if Inf
.Specification
!= None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
111 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
112 if Inf
.AutoGenVersion
< 0x00010005:
113 self
.ModuleType
= Inf
.ComponentType
114 self
.VersionString
= Inf
.Version
115 self
.BinFileList
= Inf
.Binaries
116 self
.SourceFileList
= Inf
.Sources
117 if self
.KeepReloc
== None and Inf
.Shadow
:
118 self
.ShadowFromInfFile
= Inf
.Shadow
121 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, 'COMMON']
122 self
.BaseName
= Inf
.BaseName
123 self
.ModuleGuid
= Inf
.Guid
124 self
.ModuleType
= Inf
.ModuleType
125 if Inf
.Specification
!= None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
126 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
127 self
.VersionString
= Inf
.Version
128 self
.BinFileList
= Inf
.Binaries
129 self
.SourceFileList
= Inf
.Sources
130 if self
.BinFileList
== []:
131 EdkLogger
.error("GenFds", GENFDS_ERROR
,
132 "INF %s specified in FDF could not be found in build ARCH %s!" \
133 % (self
.InfFileName
, GenFdsGlobalVariable
.ArchList
))
135 if len(self
.SourceFileList
) != 0 and not self
.InDsc
:
136 EdkLogger
.warn("GenFds", GENFDS_ERROR
, "Module %s NOT found in DSC file; Is it really a binary module?" % (self
.InfFileName
))
138 if self
.ModuleType
== 'SMM_CORE' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
139 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
)
141 if Inf
._Defs
!= None and len(Inf
._Defs
) > 0:
142 self
.OptRomDefs
.update(Inf
._Defs
)
146 GenFdsGlobalVariable
.VerboseLogger( "BaseName : %s" %self
.BaseName
)
147 GenFdsGlobalVariable
.VerboseLogger("ModuleGuid : %s" %self
.ModuleGuid
)
148 GenFdsGlobalVariable
.VerboseLogger("ModuleType : %s" %self
.ModuleType
)
149 GenFdsGlobalVariable
.VerboseLogger("VersionString : %s" %self
.VersionString
)
150 GenFdsGlobalVariable
.VerboseLogger("InfFileName :%s" %self
.InfFileName
)
153 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\
156 self
.OutputPath
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, \
157 self
.ModuleGuid
+ self
.BaseName
)
158 if not os
.path
.exists(self
.OutputPath
) :
159 os
.makedirs(self
.OutputPath
)
161 self
.EfiOutputPath
= self
.__GetEFIOutPutPath
__()
162 GenFdsGlobalVariable
.VerboseLogger( "ModuelEFIPath: " + self
.EfiOutputPath
)
168 # @param self The object pointer
169 # @param Dict dictionary contains macro and value pair
170 # @param FvChildAddr Array of the inside FvImage base address
171 # @param FvParentAddr Parent Fv base address
172 # @retval string Generated FFS file name
174 def GenFfs(self
, Dict
= {}, FvChildAddr
= [], FvParentAddr
=None):
176 # Parse Inf file get Module related information
179 self
.__InfParse
__(Dict
)
182 # Allow binary type module not specify override rule in FDF file.
184 if len(self
.BinFileList
) >0 and not self
.InDsc
:
185 if self
.Rule
== None or self
.Rule
== "":
189 # Get the rule of how to generate Ffs file
191 Rule
= self
.__GetRule
__()
192 GenFdsGlobalVariable
.VerboseLogger( "Packing binaries from inf file : %s" %self
.InfFileName
)
194 # Convert Fv File Type for PI1.1 SMM driver.
196 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
197 if Rule
.FvFileType
== 'DRIVER':
198 Rule
.FvFileType
= 'SMM'
200 # Framework SMM Driver has no SMM FV file type
202 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
203 if Rule
.FvFileType
== 'SMM' or Rule
.FvFileType
== 'SMM_CORE':
204 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File
=self
.InfFileName
)
206 # For the rule only has simpleFile
208 if isinstance (Rule
, RuleSimpleFile
.RuleSimpleFile
) :
209 SectionOutputList
= self
.__GenSimpleFileSection
__(Rule
)
210 FfsOutput
= self
.__GenSimpleFileFfs
__(Rule
, SectionOutputList
)
213 # For Rule has ComplexFile
215 elif isinstance(Rule
, RuleComplexFile
.RuleComplexFile
):
216 InputSectList
, InputSectAlignments
= self
.__GenComplexFileSection
__(Rule
, FvChildAddr
, FvParentAddr
)
217 FfsOutput
= self
.__GenComplexFileFfs
__(Rule
, InputSectList
, InputSectAlignments
)
221 ## __ExtendMacro__() method
223 # Replace macro with its value
225 # @param self The object pointer
226 # @param String The string to be replaced
227 # @retval string Macro replaced string
229 def __ExtendMacro__ (self
, String
):
231 '$(INF_OUTPUT)' : self
.EfiOutputPath
,
232 '$(MODULE_NAME)' : self
.BaseName
,
233 '$(BUILD_NUMBER)': self
.BuildNum
,
234 '$(INF_VERSION)' : self
.VersionString
,
235 '$(NAMED_GUID)' : self
.ModuleGuid
237 String
= GenFdsGlobalVariable
.MacroExtend(String
, MacroDict
)
240 ## __GetRule__() method
242 # Get correct rule for generating FFS for this INF
244 # @param self The object pointer
245 # @retval Rule Rule object
247 def __GetRule__ (self
) :
249 if self
.CurrentArch
== None:
250 CurrentArchList
= ['common']
252 CurrentArchList
.append(self
.CurrentArch
)
254 for CurrentArch
in CurrentArchList
:
255 RuleName
= 'RULE' + \
257 CurrentArch
.upper() + \
259 self
.ModuleType
.upper()
260 if self
.Rule
!= None:
261 RuleName
= RuleName
+ \
265 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
267 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
270 RuleName
= 'RULE' + \
274 self
.ModuleType
.upper()
276 if self
.Rule
!= None:
277 RuleName
= RuleName
+ \
281 GenFdsGlobalVariable
.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName
, self
.InfFileName
))
283 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
285 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
289 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'Don\'t Find common rule %s for INF %s' \
290 % (RuleName
, self
.InfFileName
))
292 ## __GetPlatformArchList__() method
294 # Get Arch list this INF built under
296 # @param self The object pointer
297 # @retval list Arch list
299 def __GetPlatformArchList__(self
):
301 InfFileKey
= os
.path
.normpath(os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
))
303 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'IA32']
304 if PlatformDataBase
!= None:
305 if InfFileKey
in PlatformDataBase
.Modules
:
306 DscArchList
.append ('IA32')
308 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'X64']
309 if PlatformDataBase
!= None:
310 if InfFileKey
in PlatformDataBase
.Modules
:
311 DscArchList
.append ('X64')
313 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'IPF']
314 if PlatformDataBase
!= None:
315 if InfFileKey
in (PlatformDataBase
.Modules
):
316 DscArchList
.append ('IPF')
318 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'ARM']
319 if PlatformDataBase
!= None:
320 if InfFileKey
in (PlatformDataBase
.Modules
):
321 DscArchList
.append ('ARM')
323 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'EBC']
324 if PlatformDataBase
!= None:
325 if InfFileKey
in (PlatformDataBase
.Modules
):
326 DscArchList
.append ('EBC')
330 ## GetCurrentArch() method
332 # Get Arch list of the module from this INF is to be placed into flash
334 # @param self The object pointer
335 # @retval list Arch list
337 def GetCurrentArch(self
) :
339 TargetArchList
= GenFdsGlobalVariable
.ArchList
341 PlatformArchList
= self
.__GetPlatformArchList
__()
343 CurArchList
= TargetArchList
344 if PlatformArchList
!= []:
345 CurArchList
= list(set (TargetArchList
) & set (PlatformArchList
))
346 GenFdsGlobalVariable
.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList
))
349 if self
.KeyStringList
!= []:
350 for Key
in self
.KeyStringList
:
351 Key
= GenFdsGlobalVariable
.MacroExtend(Key
)
352 Target
, Tag
, Arch
= Key
.split('_')
353 if Arch
in CurArchList
:
354 ArchList
.append(Arch
)
355 if Target
not in self
.TargetOverrideList
:
356 self
.TargetOverrideList
.append(Target
)
358 ArchList
= CurArchList
360 UseArchList
= TargetArchList
361 if self
.UseArch
!= None:
363 UseArchList
.append(self
.UseArch
)
364 ArchList
= list(set (UseArchList
) & set (ArchList
))
366 self
.InfFileName
= NormPath(self
.InfFileName
)
367 if len(PlatformArchList
) == 0:
369 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
370 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
372 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
373 if len(ArchList
) == 1:
376 elif len(ArchList
) > 1:
377 if len(PlatformArchList
) == 0:
378 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
))
380 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
))
382 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." \
383 % (self
.InfFileName
, str(PlatformArchList
), GenFdsGlobalVariable
.ActivePlatform
, str(set (UseArchList
) & set (TargetArchList
))))
385 ## __GetEFIOutPutPath__() method
387 # Get the output path for generated files
389 # @param self The object pointer
390 # @retval string Path that output files from this INF go to
392 def __GetEFIOutPutPath__(self
):
395 (ModulePath
, FileName
) = os
.path
.split(self
.InfFileName
)
396 Index
= FileName
.find('.')
397 FileName
= FileName
[0:Index
]
399 if self
.CurrentArch
!= None:
400 Arch
= self
.CurrentArch
402 OutputPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
408 OutputPath
= os
.path
.realpath(OutputPath
)
411 ## __GenSimpleFileSection__() method
413 # Generate section by specified file name or a list of files with file extension
415 # @param self The object pointer
416 # @param Rule The rule object used to generate section
417 # @retval string File name of the generated section file
419 def __GenSimpleFileSection__(self
, Rule
):
421 # Prepare the parameter of GenSection
425 GenSecInputFile
= None
426 if Rule
.FileName
!= None:
427 GenSecInputFile
= self
.__ExtendMacro
__(Rule
.FileName
)
428 if os
.path
.isabs(GenSecInputFile
):
429 GenSecInputFile
= os
.path
.normpath(GenSecInputFile
)
431 GenSecInputFile
= os
.path
.normpath(os
.path
.join(self
.EfiOutputPath
, GenSecInputFile
))
433 FileList
, IsSect
= Section
.Section
.GetFileList(self
, '', Rule
.FileExtension
)
436 SectionType
= Rule
.SectionType
438 # Convert Fv Section Type for PI1.1 SMM driver.
440 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
441 if SectionType
== 'DXE_DEPEX':
442 SectionType
= 'SMM_DEPEX'
444 # Framework SMM Driver has no SMM_DEPEX section type
446 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
447 if SectionType
== 'SMM_DEPEX':
448 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
450 if self
.ModuleType
in ('SEC', 'PEI_CORE', 'PEIM'):
451 if self
.KeepReloc
!= None:
452 NoStrip
= self
.KeepReloc
453 elif Rule
.KeepReloc
!= None:
454 NoStrip
= Rule
.KeepReloc
455 elif self
.ShadowFromInfFile
!= None:
456 NoStrip
= self
.ShadowFromInfFile
459 for File
in FileList
:
462 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
463 Ffs
.Ffs
.SectionSuffix
[SectionType
] + 'SEC' + SecNum
465 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
466 File
= GenFdsGlobalVariable
.MacroExtend(File
, Dict
, self
.CurrentArch
)
468 #Get PE Section alignment when align is set to AUTO
469 if self
.Alignment
== 'Auto' and (SectionType
== 'PE32' or SectionType
== 'TE'):
470 ImageObj
= PeImageClass (File
)
471 if ImageObj
.SectionAlignment
< 0x400:
472 self
.Alignment
= str (ImageObj
.SectionAlignment
)
474 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
477 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
478 if not os
.path
.exists(FileBeforeStrip
) or \
479 (os
.path
.getmtime(File
) > os
.path
.getmtime(FileBeforeStrip
)):
480 shutil
.copyfile(File
, FileBeforeStrip
)
481 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
482 GenFdsGlobalVariable
.GenerateFirmwareImage(
489 if SectionType
== 'TE':
490 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
491 GenFdsGlobalVariable
.GenerateFirmwareImage(
498 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [File
], Section
.Section
.SectionType
[SectionType
])
499 OutputFileList
.append(OutputFile
)
502 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
503 Ffs
.Ffs
.SectionSuffix
[SectionType
] + 'SEC' + SecNum
504 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
505 GenSecInputFile
= GenFdsGlobalVariable
.MacroExtend(GenSecInputFile
, Dict
, self
.CurrentArch
)
507 #Get PE Section alignment when align is set to AUTO
508 if self
.Alignment
== 'Auto' and (SectionType
== 'PE32' or SectionType
== 'TE'):
509 ImageObj
= PeImageClass (GenSecInputFile
)
510 if ImageObj
.SectionAlignment
< 0x400:
511 self
.Alignment
= str (ImageObj
.SectionAlignment
)
513 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
516 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
517 if not os
.path
.exists(FileBeforeStrip
) or \
518 (os
.path
.getmtime(GenSecInputFile
) > os
.path
.getmtime(FileBeforeStrip
)):
519 shutil
.copyfile(GenSecInputFile
, FileBeforeStrip
)
520 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
521 GenFdsGlobalVariable
.GenerateFirmwareImage(
526 GenSecInputFile
= StrippedFile
528 if SectionType
== 'TE':
529 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
530 GenFdsGlobalVariable
.GenerateFirmwareImage(
535 GenSecInputFile
= TeFile
537 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [GenSecInputFile
], Section
.Section
.SectionType
[SectionType
])
538 OutputFileList
.append(OutputFile
)
540 return OutputFileList
542 ## __GenSimpleFileFfs__() method
546 # @param self The object pointer
547 # @param Rule The rule object used to generate section
548 # @param InputFileList The output file list from GenSection
549 # @retval string Generated FFS file name
551 def __GenSimpleFileFfs__(self
, Rule
, InputFileList
):
552 FfsOutput
= self
.OutputPath
+ \
554 self
.__ExtendMacro
__(Rule
.NameGuid
) + \
557 GenFdsGlobalVariable
.VerboseLogger(self
.__ExtendMacro
__(Rule
.NameGuid
))
559 SectionAlignments
= []
560 for InputFile
in InputFileList
:
561 InputSection
.append(InputFile
)
562 SectionAlignments
.append(Rule
.SectAlignment
)
564 if Rule
.NameGuid
!= None and Rule
.NameGuid
.startswith('PCD('):
565 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
566 if len(PcdValue
) == 0:
567 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
569 if PcdValue
.startswith('{'):
570 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
571 RegistryGuidStr
= PcdValue
572 if len(RegistryGuidStr
) == 0:
573 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
575 self
.ModuleGuid
= RegistryGuidStr
577 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputSection
,
578 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
579 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
580 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
581 SectionAlign
=SectionAlignments
585 ## __GenComplexFileSection__() method
587 # Generate section by sections in Rule
589 # @param self The object pointer
590 # @param Rule The rule object used to generate section
591 # @param FvChildAddr Array of the inside FvImage base address
592 # @param FvParentAddr Parent Fv base address
593 # @retval string File name of the generated section file
595 def __GenComplexFileSection__(self
, Rule
, FvChildAddr
, FvParentAddr
):
596 if self
.ModuleType
in ('SEC', 'PEI_CORE', 'PEIM'):
597 if Rule
.KeepReloc
!= None:
598 self
.KeepRelocFromRule
= Rule
.KeepReloc
602 HasGneratedFlag
= False
603 for Sect
in Rule
.SectionList
:
604 SecIndex
= '%d' %Index
607 # Convert Fv Section Type for PI1.1 SMM driver.
609 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
610 if Sect
.SectionType
== 'DXE_DEPEX':
611 Sect
.SectionType
= 'SMM_DEPEX'
613 # Framework SMM Driver has no SMM_DEPEX section type
615 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
616 if Sect
.SectionType
== 'SMM_DEPEX':
617 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
619 # process the inside FvImage from FvSection or GuidSection
621 if FvChildAddr
!= []:
622 if isinstance(Sect
, FvImageSection
):
623 Sect
.FvAddr
= FvChildAddr
.pop(0)
624 elif isinstance(Sect
, GuidSection
):
625 Sect
.FvAddr
= FvChildAddr
626 if FvParentAddr
!= None and isinstance(Sect
, GuidSection
):
627 Sect
.FvParentAddr
= FvParentAddr
629 if Rule
.KeyStringList
!= []:
630 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, Rule
.KeyStringList
, self
)
632 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, self
.KeyStringList
, self
)
634 if not HasGneratedFlag
:
635 UniVfrOffsetFileSection
= ""
636 ModuleFileName
= os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
)
637 InfData
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClass(ModuleFileName
), self
.CurrentArch
]
639 # Search the source list in InfData to find if there are .vfr file exist.
642 VfrUniOffsetList
= []
643 for SourceFile
in InfData
.Sources
:
644 if SourceFile
.Type
.upper() == ".VFR" :
646 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
648 VfrUniBaseName
[SourceFile
.BaseName
] = (SourceFile
.BaseName
+ "Bin")
649 if SourceFile
.Type
.upper() == ".UNI" :
651 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
653 VfrUniBaseName
["UniOffsetName"] = (self
.BaseName
+ "Strings")
656 if len(VfrUniBaseName
) > 0:
657 VfrUniOffsetList
= self
.__GetBuildOutputMapFileVfrUniInfo
(VfrUniBaseName
)
659 # Generate the Raw data of raw section
661 os
.path
.join( self
.OutputPath
, self
.BaseName
+ '.offset')
662 UniVfrOffsetFileName
= os
.path
.join( self
.OutputPath
, self
.BaseName
+ '.offset')
663 UniVfrOffsetFileSection
= os
.path
.join( self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
665 self
.__GenUniVfrOffsetFile
(VfrUniOffsetList
, UniVfrOffsetFileName
)
667 UniVfrOffsetFileNameList
= []
668 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
669 """Call GenSection"""
670 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
671 UniVfrOffsetFileNameList
,
674 os
.remove(UniVfrOffsetFileName
)
675 SectList
.append(UniVfrOffsetFileSection
)
676 HasGneratedFlag
= True
678 for SecName
in SectList
:
679 SectFiles
.append(SecName
)
680 SectAlignments
.append(Align
)
682 return SectFiles
, SectAlignments
684 ## __GenComplexFileFfs__() method
688 # @param self The object pointer
689 # @param Rule The rule object used to generate section
690 # @param InputFileList The output file list from GenSection
691 # @retval string Generated FFS file name
693 def __GenComplexFileFfs__(self
, Rule
, InputFile
, Alignments
):
695 if Rule
.NameGuid
!= None and Rule
.NameGuid
.startswith('PCD('):
696 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
697 if len(PcdValue
) == 0:
698 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
700 if PcdValue
.startswith('{'):
701 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
702 RegistryGuidStr
= PcdValue
703 if len(RegistryGuidStr
) == 0:
704 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
706 self
.ModuleGuid
= RegistryGuidStr
708 FfsOutput
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
709 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputFile
,
710 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
711 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
712 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
713 SectionAlign
=Alignments
717 ## __GetGenFfsCmdParameter__() method
719 # Create parameter string for GenFfs
721 # @param self The object pointer
722 # @param Rule The rule object used to generate section
723 # @retval tuple (FileType, Fixed, CheckSum, Alignment)
725 def __GetGenFfsCmdParameter__(self
, Rule
):
727 result
+= ('-t', Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
])
728 if Rule
.Fixed
!= False:
730 if Rule
.CheckSum
!= False:
733 if Rule
.Alignment
!= None and Rule
.Alignment
!= '':
734 result
+= ('-a', Rule
.Alignment
)
738 ## __GetBuildOutputMapFileVfrUniInfo() method
740 # Find the offset of UNI/INF object offset in the EFI image file.
742 # @param self The object pointer
743 # @param VfrUniBaseName A name list contain the UNI/INF object name.
744 # @retval RetValue A list contain offset of UNI/INF object.
746 def __GetBuildOutputMapFileVfrUniInfo(self
, VfrUniBaseName
):
750 MapFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".map")
752 fInputfile
= open(MapFileName
, "r", 0)
754 FileLinesList
= fInputfile
.readlines()
756 EdkLogger
.error("GenFds", FILE_READ_FAILURE
, "File read failed for %s" %MapFileName
,None)
760 EdkLogger
.error("GenFds", FILE_OPEN_FAILURE
, "File open failed for %s" %MapFileName
,None)
763 for eachLine
in FileLinesList
:
764 for eachName
in VfrUniBaseName
.values():
765 if eachLine
.find(eachName
) != -1:
766 eachLine
= eachLine
.strip()
767 Element
= eachLine
.split()
769 # MSFT/ICC/EBC map file
771 if (len(Element
) == 4):
779 RetValue
.append((eachName
, Element
[2]))
784 elif (len(Element
) == 2) and Element
[0].startswith("0x"):
785 RetValue
.append((eachName
, Element
[0]))
789 ## __GenUniVfrOffsetFile() method
791 # Generate the offset file for the module which contain VFR or UNI file.
793 # @param self The object pointer
794 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
795 # @param UniVfrOffsetFileName The output offset file name.
797 def __GenUniVfrOffsetFile(self
, VfrUniOffsetList
, UniVfrOffsetFileName
):
800 fInputfile
= open(UniVfrOffsetFileName
, "wb+", 0)
802 EdkLogger
.error("GenFds", FILE_OPEN_FAILURE
, "File open failed for %s" %UniVfrOffsetFileName
,None)
804 # Use a instance of StringIO to cache data
805 fStringIO
= StringIO
.StringIO('')
807 for Item
in VfrUniOffsetList
:
808 if (Item
[0].find("Strings") != -1):
810 # UNI offset in image.
812 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
814 UniGuid
= [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
815 UniGuid
= [chr(ItemGuid
) for ItemGuid
in UniGuid
]
816 fStringIO
.write(''.join(UniGuid
))
817 UniValue
= pack ('Q', int (Item
[1], 16))
818 fStringIO
.write (UniValue
)
821 # VFR binary offset in image.
823 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
825 VfrGuid
= [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
826 VfrGuid
= [chr(ItemGuid
) for ItemGuid
in VfrGuid
]
827 fStringIO
.write(''.join(VfrGuid
))
829 VfrValue
= pack ('Q', int (Item
[1], 16))
830 fStringIO
.write (VfrValue
)
833 # write data into file.
836 fInputfile
.write (fStringIO
.getvalue())
838 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)