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
39 from AutoGen
.GenDepex
import DependencyExpression
41 ## generate FFS from INF
44 class FfsInfStatement(FfsInfStatementClassObject
):
47 # @param self The object pointer
50 FfsInfStatementClassObject
.__init
__(self
)
51 self
.TargetOverrideList
= []
52 self
.ShadowFromInfFile
= None
53 self
.KeepRelocFromRule
= None
56 self
.PiSpecVersion
= '0x00000000'
58 self
.FinalTargetSuffixMap
= {}
60 ## GetFinalTargetSuffixMap() method
62 # Get final build target list
63 def GetFinalTargetSuffixMap(self
):
64 if not self
.InfModule
or not self
.CurrentArch
:
66 if not self
.FinalTargetSuffixMap
:
67 FinalBuildTargetList
= GenFdsGlobalVariable
.GetModuleCodaTargetList(self
.InfModule
, self
.CurrentArch
)
68 for File
in FinalBuildTargetList
:
69 self
.FinalTargetSuffixMap
.setdefault(os
.path
.splitext(File
)[1], []).append(File
)
71 # Check if current INF module has DEPEX
72 if '.depex' not in self
.FinalTargetSuffixMap
and self
.InfModule
.ModuleType
!= "USER_DEFINED" \
73 and not self
.InfModule
.DxsFile
and not self
.InfModule
.LibraryClass
:
74 ModuleType
= self
.InfModule
.ModuleType
75 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
77 if ModuleType
!= DataType
.SUP_MODULE_USER_DEFINED
:
78 for LibraryClass
in PlatformDataBase
.LibraryClasses
.GetKeys():
79 if LibraryClass
.startswith("NULL") and PlatformDataBase
.LibraryClasses
[LibraryClass
, ModuleType
]:
80 self
.InfModule
.LibraryClasses
[LibraryClass
] = PlatformDataBase
.LibraryClasses
[LibraryClass
, ModuleType
]
82 StrModule
= str(self
.InfModule
)
84 if StrModule
in PlatformDataBase
.Modules
:
85 PlatformModule
= PlatformDataBase
.Modules
[StrModule
]
86 for LibraryClass
in PlatformModule
.LibraryClasses
:
87 if LibraryClass
.startswith("NULL"):
88 self
.InfModule
.LibraryClasses
[LibraryClass
] = PlatformModule
.LibraryClasses
[LibraryClass
]
90 DependencyList
= [self
.InfModule
]
93 while len(DependencyList
) > 0:
94 Module
= DependencyList
.pop(0)
97 for Dep
in Module
.Depex
[self
.CurrentArch
, ModuleType
]:
99 DepexList
.append('AND')
100 DepexList
.append('(')
101 DepexList
.extend(Dep
)
102 if DepexList
[-1] == 'END': # no need of a END at this time
104 DepexList
.append(')')
105 if 'BEFORE' in DepexList
or 'AFTER' in DepexList
:
107 for LibName
in Module
.LibraryClasses
:
108 if LibName
in LibraryInstance
:
110 if PlatformModule
and LibName
in PlatformModule
.LibraryClasses
:
111 LibraryPath
= PlatformModule
.LibraryClasses
[LibName
]
113 LibraryPath
= PlatformDataBase
.LibraryClasses
[LibName
, ModuleType
]
115 LibraryPath
= Module
.LibraryClasses
[LibName
]
118 LibraryModule
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[LibraryPath
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
119 LibraryInstance
[LibName
] = LibraryModule
120 DependencyList
.append(LibraryModule
)
122 Dpx
= DependencyExpression(DepexList
, ModuleType
, True)
123 if len(Dpx
.PostfixNotation
) != 0:
124 # It means this module has DEPEX
125 self
.FinalTargetSuffixMap
['.depex'] = [os
.path
.join(self
.EfiOutputPath
, self
.BaseName
) + '.depex']
126 return self
.FinalTargetSuffixMap
128 ## __InfParse() method
130 # Parse inf file to get module information
132 # @param self The object pointer
133 # @param Dict dictionary contains macro and value pair
135 def __InfParse__(self
, Dict
= {}):
137 GenFdsGlobalVariable
.VerboseLogger( " Begine parsing INf file : %s" %self
.InfFileName
)
139 self
.InfFileName
= self
.InfFileName
.replace('$(WORKSPACE)', '')
140 if self
.InfFileName
[0] == '\\' or self
.InfFileName
[0] == '/' :
141 self
.InfFileName
= self
.InfFileName
[1:]
143 if self
.InfFileName
.find('$') == -1:
144 InfPath
= NormPath(self
.InfFileName
)
145 if not os
.path
.exists(InfPath
):
146 InfPath
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(InfPath
)
147 if not os
.path
.exists(InfPath
):
148 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Non-existant Module %s !" % (self
.InfFileName
))
150 self
.CurrentArch
= self
.GetCurrentArch()
152 # Get the InfClass object
155 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
156 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
158 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
160 if self
.CurrentArch
!= None:
162 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, self
.CurrentArch
]
164 # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath
166 self
.BaseName
= Inf
.BaseName
167 self
.ModuleGuid
= Inf
.Guid
168 self
.ModuleType
= Inf
.ModuleType
169 if Inf
.Specification
!= None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
170 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
171 if Inf
.AutoGenVersion
< 0x00010005:
172 self
.ModuleType
= Inf
.ComponentType
173 self
.VersionString
= Inf
.Version
174 self
.BinFileList
= Inf
.Binaries
175 self
.SourceFileList
= Inf
.Sources
176 if self
.KeepReloc
== None and Inf
.Shadow
:
177 self
.ShadowFromInfFile
= Inf
.Shadow
180 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, 'COMMON']
181 self
.BaseName
= Inf
.BaseName
182 self
.ModuleGuid
= Inf
.Guid
183 self
.ModuleType
= Inf
.ModuleType
184 if Inf
.Specification
!= None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
185 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
186 self
.VersionString
= Inf
.Version
187 self
.BinFileList
= Inf
.Binaries
188 self
.SourceFileList
= Inf
.Sources
189 if self
.BinFileList
== []:
190 EdkLogger
.error("GenFds", GENFDS_ERROR
,
191 "INF %s specified in FDF could not be found in build ARCH %s!" \
192 % (self
.InfFileName
, GenFdsGlobalVariable
.ArchList
))
194 if len(self
.SourceFileList
) != 0 and not self
.InDsc
:
195 EdkLogger
.warn("GenFds", GENFDS_ERROR
, "Module %s NOT found in DSC file; Is it really a binary module?" % (self
.InfFileName
))
197 if self
.ModuleType
== 'SMM_CORE' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
198 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
)
200 if Inf
._Defs
!= None and len(Inf
._Defs
) > 0:
201 self
.OptRomDefs
.update(Inf
._Defs
)
205 GenFdsGlobalVariable
.VerboseLogger( "BaseName : %s" %self
.BaseName
)
206 GenFdsGlobalVariable
.VerboseLogger("ModuleGuid : %s" %self
.ModuleGuid
)
207 GenFdsGlobalVariable
.VerboseLogger("ModuleType : %s" %self
.ModuleType
)
208 GenFdsGlobalVariable
.VerboseLogger("VersionString : %s" %self
.VersionString
)
209 GenFdsGlobalVariable
.VerboseLogger("InfFileName :%s" %self
.InfFileName
)
212 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\
215 self
.OutputPath
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, \
216 self
.ModuleGuid
+ self
.BaseName
)
217 if not os
.path
.exists(self
.OutputPath
) :
218 os
.makedirs(self
.OutputPath
)
220 self
.EfiOutputPath
= self
.__GetEFIOutPutPath
__()
221 GenFdsGlobalVariable
.VerboseLogger( "ModuelEFIPath: " + self
.EfiOutputPath
)
227 # @param self The object pointer
228 # @param Dict dictionary contains macro and value pair
229 # @param FvChildAddr Array of the inside FvImage base address
230 # @param FvParentAddr Parent Fv base address
231 # @retval string Generated FFS file name
233 def GenFfs(self
, Dict
= {}, FvChildAddr
= [], FvParentAddr
=None):
235 # Parse Inf file get Module related information
238 self
.__InfParse
__(Dict
)
241 # Allow binary type module not specify override rule in FDF file.
243 if len(self
.BinFileList
) >0 and not self
.InDsc
:
244 if self
.Rule
== None or self
.Rule
== "":
248 # Get the rule of how to generate Ffs file
250 Rule
= self
.__GetRule
__()
251 GenFdsGlobalVariable
.VerboseLogger( "Packing binaries from inf file : %s" %self
.InfFileName
)
253 # Convert Fv File Type for PI1.1 SMM driver.
255 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
256 if Rule
.FvFileType
== 'DRIVER':
257 Rule
.FvFileType
= 'SMM'
259 # Framework SMM Driver has no SMM FV file type
261 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
262 if Rule
.FvFileType
== 'SMM' or Rule
.FvFileType
== 'SMM_CORE':
263 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File
=self
.InfFileName
)
265 # For the rule only has simpleFile
267 if isinstance (Rule
, RuleSimpleFile
.RuleSimpleFile
) :
268 SectionOutputList
= self
.__GenSimpleFileSection
__(Rule
)
269 FfsOutput
= self
.__GenSimpleFileFfs
__(Rule
, SectionOutputList
)
272 # For Rule has ComplexFile
274 elif isinstance(Rule
, RuleComplexFile
.RuleComplexFile
):
275 InputSectList
, InputSectAlignments
= self
.__GenComplexFileSection
__(Rule
, FvChildAddr
, FvParentAddr
)
276 FfsOutput
= self
.__GenComplexFileFfs
__(Rule
, InputSectList
, InputSectAlignments
)
280 ## __ExtendMacro__() method
282 # Replace macro with its value
284 # @param self The object pointer
285 # @param String The string to be replaced
286 # @retval string Macro replaced string
288 def __ExtendMacro__ (self
, String
):
290 '$(INF_OUTPUT)' : self
.EfiOutputPath
,
291 '$(MODULE_NAME)' : self
.BaseName
,
292 '$(BUILD_NUMBER)': self
.BuildNum
,
293 '$(INF_VERSION)' : self
.VersionString
,
294 '$(NAMED_GUID)' : self
.ModuleGuid
296 String
= GenFdsGlobalVariable
.MacroExtend(String
, MacroDict
)
299 ## __GetRule__() method
301 # Get correct rule for generating FFS for this INF
303 # @param self The object pointer
304 # @retval Rule Rule object
306 def __GetRule__ (self
) :
308 if self
.CurrentArch
== None:
309 CurrentArchList
= ['common']
311 CurrentArchList
.append(self
.CurrentArch
)
313 for CurrentArch
in CurrentArchList
:
314 RuleName
= 'RULE' + \
316 CurrentArch
.upper() + \
318 self
.ModuleType
.upper()
319 if self
.Rule
!= None:
320 RuleName
= RuleName
+ \
324 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
326 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
329 RuleName
= 'RULE' + \
333 self
.ModuleType
.upper()
335 if self
.Rule
!= None:
336 RuleName
= RuleName
+ \
340 GenFdsGlobalVariable
.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName
, self
.InfFileName
))
342 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
344 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
348 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'Don\'t Find common rule %s for INF %s' \
349 % (RuleName
, self
.InfFileName
))
351 ## __GetPlatformArchList__() method
353 # Get Arch list this INF built under
355 # @param self The object pointer
356 # @retval list Arch list
358 def __GetPlatformArchList__(self
):
360 InfFileKey
= os
.path
.normpath(os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
))
362 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'IA32']
363 if PlatformDataBase
!= None:
364 if InfFileKey
in PlatformDataBase
.Modules
:
365 DscArchList
.append ('IA32')
367 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'X64']
368 if PlatformDataBase
!= None:
369 if InfFileKey
in PlatformDataBase
.Modules
:
370 DscArchList
.append ('X64')
372 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'IPF']
373 if PlatformDataBase
!= None:
374 if InfFileKey
in (PlatformDataBase
.Modules
):
375 DscArchList
.append ('IPF')
377 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'ARM']
378 if PlatformDataBase
!= None:
379 if InfFileKey
in (PlatformDataBase
.Modules
):
380 DscArchList
.append ('ARM')
382 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'EBC']
383 if PlatformDataBase
!= None:
384 if InfFileKey
in (PlatformDataBase
.Modules
):
385 DscArchList
.append ('EBC')
389 ## GetCurrentArch() method
391 # Get Arch list of the module from this INF is to be placed into flash
393 # @param self The object pointer
394 # @retval list Arch list
396 def GetCurrentArch(self
) :
398 TargetArchList
= GenFdsGlobalVariable
.ArchList
400 PlatformArchList
= self
.__GetPlatformArchList
__()
402 CurArchList
= TargetArchList
403 if PlatformArchList
!= []:
404 CurArchList
= list(set (TargetArchList
) & set (PlatformArchList
))
405 GenFdsGlobalVariable
.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList
))
408 if self
.KeyStringList
!= []:
409 for Key
in self
.KeyStringList
:
410 Key
= GenFdsGlobalVariable
.MacroExtend(Key
)
411 Target
, Tag
, Arch
= Key
.split('_')
412 if Arch
in CurArchList
:
413 ArchList
.append(Arch
)
414 if Target
not in self
.TargetOverrideList
:
415 self
.TargetOverrideList
.append(Target
)
417 ArchList
= CurArchList
419 UseArchList
= TargetArchList
420 if self
.UseArch
!= None:
422 UseArchList
.append(self
.UseArch
)
423 ArchList
= list(set (UseArchList
) & set (ArchList
))
425 self
.InfFileName
= NormPath(self
.InfFileName
)
426 if len(PlatformArchList
) == 0:
428 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
429 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
431 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
432 if len(ArchList
) == 1:
435 elif len(ArchList
) > 1:
436 if len(PlatformArchList
) == 0:
437 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
))
439 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
))
441 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." \
442 % (self
.InfFileName
, str(PlatformArchList
), GenFdsGlobalVariable
.ActivePlatform
, str(set (UseArchList
) & set (TargetArchList
))))
444 ## __GetEFIOutPutPath__() method
446 # Get the output path for generated files
448 # @param self The object pointer
449 # @retval string Path that output files from this INF go to
451 def __GetEFIOutPutPath__(self
):
454 (ModulePath
, FileName
) = os
.path
.split(self
.InfFileName
)
455 Index
= FileName
.find('.')
456 FileName
= FileName
[0:Index
]
458 if self
.CurrentArch
!= None:
459 Arch
= self
.CurrentArch
461 OutputPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
467 OutputPath
= os
.path
.realpath(OutputPath
)
470 ## __GenSimpleFileSection__() method
472 # Generate section by specified file name or a list of files with file extension
474 # @param self The object pointer
475 # @param Rule The rule object used to generate section
476 # @retval string File name of the generated section file
478 def __GenSimpleFileSection__(self
, Rule
):
480 # Prepare the parameter of GenSection
484 GenSecInputFile
= None
485 if Rule
.FileName
!= None:
486 GenSecInputFile
= self
.__ExtendMacro
__(Rule
.FileName
)
487 if os
.path
.isabs(GenSecInputFile
):
488 GenSecInputFile
= os
.path
.normpath(GenSecInputFile
)
490 GenSecInputFile
= os
.path
.normpath(os
.path
.join(self
.EfiOutputPath
, GenSecInputFile
))
492 FileList
, IsSect
= Section
.Section
.GetFileList(self
, '', Rule
.FileExtension
)
495 SectionType
= Rule
.SectionType
497 # Convert Fv Section Type for PI1.1 SMM driver.
499 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
500 if SectionType
== 'DXE_DEPEX':
501 SectionType
= 'SMM_DEPEX'
503 # Framework SMM Driver has no SMM_DEPEX section type
505 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
506 if SectionType
== 'SMM_DEPEX':
507 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
509 if self
.ModuleType
in ('SEC', 'PEI_CORE', 'PEIM'):
510 if self
.KeepReloc
!= None:
511 NoStrip
= self
.KeepReloc
512 elif Rule
.KeepReloc
!= None:
513 NoStrip
= Rule
.KeepReloc
514 elif self
.ShadowFromInfFile
!= None:
515 NoStrip
= self
.ShadowFromInfFile
518 for File
in FileList
:
521 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
522 Ffs
.Ffs
.SectionSuffix
[SectionType
] + 'SEC' + SecNum
524 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
525 File
= GenFdsGlobalVariable
.MacroExtend(File
, Dict
, self
.CurrentArch
)
527 #Get PE Section alignment when align is set to AUTO
528 if self
.Alignment
== 'Auto' and (SectionType
== 'PE32' or SectionType
== 'TE'):
529 ImageObj
= PeImageClass (File
)
530 if ImageObj
.SectionAlignment
< 0x400:
531 self
.Alignment
= str (ImageObj
.SectionAlignment
)
533 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
536 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
537 if not os
.path
.exists(FileBeforeStrip
) or \
538 (os
.path
.getmtime(File
) > os
.path
.getmtime(FileBeforeStrip
)):
539 shutil
.copyfile(File
, FileBeforeStrip
)
540 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
541 GenFdsGlobalVariable
.GenerateFirmwareImage(
548 if SectionType
== 'TE':
549 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
550 GenFdsGlobalVariable
.GenerateFirmwareImage(
557 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [File
], Section
.Section
.SectionType
[SectionType
])
558 OutputFileList
.append(OutputFile
)
561 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
562 Ffs
.Ffs
.SectionSuffix
[SectionType
] + 'SEC' + SecNum
563 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
564 GenSecInputFile
= GenFdsGlobalVariable
.MacroExtend(GenSecInputFile
, Dict
, self
.CurrentArch
)
566 #Get PE Section alignment when align is set to AUTO
567 if self
.Alignment
== 'Auto' and (SectionType
== 'PE32' or SectionType
== 'TE'):
568 ImageObj
= PeImageClass (GenSecInputFile
)
569 if ImageObj
.SectionAlignment
< 0x400:
570 self
.Alignment
= str (ImageObj
.SectionAlignment
)
572 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
575 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
576 if not os
.path
.exists(FileBeforeStrip
) or \
577 (os
.path
.getmtime(GenSecInputFile
) > os
.path
.getmtime(FileBeforeStrip
)):
578 shutil
.copyfile(GenSecInputFile
, FileBeforeStrip
)
579 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
580 GenFdsGlobalVariable
.GenerateFirmwareImage(
585 GenSecInputFile
= StrippedFile
587 if SectionType
== 'TE':
588 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
589 GenFdsGlobalVariable
.GenerateFirmwareImage(
594 GenSecInputFile
= TeFile
596 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [GenSecInputFile
], Section
.Section
.SectionType
[SectionType
])
597 OutputFileList
.append(OutputFile
)
599 return OutputFileList
601 ## __GenSimpleFileFfs__() method
605 # @param self The object pointer
606 # @param Rule The rule object used to generate section
607 # @param InputFileList The output file list from GenSection
608 # @retval string Generated FFS file name
610 def __GenSimpleFileFfs__(self
, Rule
, InputFileList
):
611 FfsOutput
= self
.OutputPath
+ \
613 self
.__ExtendMacro
__(Rule
.NameGuid
) + \
616 GenFdsGlobalVariable
.VerboseLogger(self
.__ExtendMacro
__(Rule
.NameGuid
))
618 SectionAlignments
= []
619 for InputFile
in InputFileList
:
620 InputSection
.append(InputFile
)
621 SectionAlignments
.append(Rule
.SectAlignment
)
623 if Rule
.NameGuid
!= None and Rule
.NameGuid
.startswith('PCD('):
624 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
625 if len(PcdValue
) == 0:
626 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
628 if PcdValue
.startswith('{'):
629 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
630 RegistryGuidStr
= PcdValue
631 if len(RegistryGuidStr
) == 0:
632 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
634 self
.ModuleGuid
= RegistryGuidStr
636 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputSection
,
637 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
638 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
639 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
640 SectionAlign
=SectionAlignments
644 ## __GenComplexFileSection__() method
646 # Generate section by sections in Rule
648 # @param self The object pointer
649 # @param Rule The rule object used to generate section
650 # @param FvChildAddr Array of the inside FvImage base address
651 # @param FvParentAddr Parent Fv base address
652 # @retval string File name of the generated section file
654 def __GenComplexFileSection__(self
, Rule
, FvChildAddr
, FvParentAddr
):
655 if self
.ModuleType
in ('SEC', 'PEI_CORE', 'PEIM'):
656 if Rule
.KeepReloc
!= None:
657 self
.KeepRelocFromRule
= Rule
.KeepReloc
661 HasGneratedFlag
= False
662 for Sect
in Rule
.SectionList
:
663 SecIndex
= '%d' %Index
666 # Convert Fv Section Type for PI1.1 SMM driver.
668 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
669 if Sect
.SectionType
== 'DXE_DEPEX':
670 Sect
.SectionType
= 'SMM_DEPEX'
672 # Framework SMM Driver has no SMM_DEPEX section type
674 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
675 if Sect
.SectionType
== 'SMM_DEPEX':
676 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
678 # process the inside FvImage from FvSection or GuidSection
680 if FvChildAddr
!= []:
681 if isinstance(Sect
, FvImageSection
):
682 Sect
.FvAddr
= FvChildAddr
.pop(0)
683 elif isinstance(Sect
, GuidSection
):
684 Sect
.FvAddr
= FvChildAddr
685 if FvParentAddr
!= None and isinstance(Sect
, GuidSection
):
686 Sect
.FvParentAddr
= FvParentAddr
688 if Rule
.KeyStringList
!= []:
689 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, Rule
.KeyStringList
, self
)
691 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, self
.KeyStringList
, self
)
693 if not HasGneratedFlag
:
694 UniVfrOffsetFileSection
= ""
695 ModuleFileName
= os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
)
696 InfData
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClass(ModuleFileName
), self
.CurrentArch
]
698 # Search the source list in InfData to find if there are .vfr file exist.
701 VfrUniOffsetList
= []
702 for SourceFile
in InfData
.Sources
:
703 if SourceFile
.Type
.upper() == ".VFR" :
705 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
707 VfrUniBaseName
[SourceFile
.BaseName
] = (SourceFile
.BaseName
+ "Bin")
708 if SourceFile
.Type
.upper() == ".UNI" :
710 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
712 VfrUniBaseName
["UniOffsetName"] = (self
.BaseName
+ "Strings")
715 if len(VfrUniBaseName
) > 0:
716 VfrUniOffsetList
= self
.__GetBuildOutputMapFileVfrUniInfo
(VfrUniBaseName
)
718 # Generate the Raw data of raw section
720 os
.path
.join( self
.OutputPath
, self
.BaseName
+ '.offset')
721 UniVfrOffsetFileName
= os
.path
.join( self
.OutputPath
, self
.BaseName
+ '.offset')
722 UniVfrOffsetFileSection
= os
.path
.join( self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
724 self
.__GenUniVfrOffsetFile
(VfrUniOffsetList
, UniVfrOffsetFileName
)
726 UniVfrOffsetFileNameList
= []
727 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
728 """Call GenSection"""
729 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
730 UniVfrOffsetFileNameList
,
733 os
.remove(UniVfrOffsetFileName
)
734 SectList
.append(UniVfrOffsetFileSection
)
735 HasGneratedFlag
= True
737 for SecName
in SectList
:
738 SectFiles
.append(SecName
)
739 SectAlignments
.append(Align
)
741 return SectFiles
, SectAlignments
743 ## __GenComplexFileFfs__() method
747 # @param self The object pointer
748 # @param Rule The rule object used to generate section
749 # @param InputFileList The output file list from GenSection
750 # @retval string Generated FFS file name
752 def __GenComplexFileFfs__(self
, Rule
, InputFile
, Alignments
):
754 if Rule
.NameGuid
!= None and Rule
.NameGuid
.startswith('PCD('):
755 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
756 if len(PcdValue
) == 0:
757 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
759 if PcdValue
.startswith('{'):
760 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
761 RegistryGuidStr
= PcdValue
762 if len(RegistryGuidStr
) == 0:
763 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
765 self
.ModuleGuid
= RegistryGuidStr
767 FfsOutput
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
768 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputFile
,
769 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
770 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
771 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
772 SectionAlign
=Alignments
776 ## __GetGenFfsCmdParameter__() method
778 # Create parameter string for GenFfs
780 # @param self The object pointer
781 # @param Rule The rule object used to generate section
782 # @retval tuple (FileType, Fixed, CheckSum, Alignment)
784 def __GetGenFfsCmdParameter__(self
, Rule
):
786 result
+= ('-t', Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
])
787 if Rule
.Fixed
!= False:
789 if Rule
.CheckSum
!= False:
792 if Rule
.Alignment
!= None and Rule
.Alignment
!= '':
793 result
+= ('-a', Rule
.Alignment
)
797 ## __GetBuildOutputMapFileVfrUniInfo() method
799 # Find the offset of UNI/INF object offset in the EFI image file.
801 # @param self The object pointer
802 # @param VfrUniBaseName A name list contain the UNI/INF object name.
803 # @retval RetValue A list contain offset of UNI/INF object.
805 def __GetBuildOutputMapFileVfrUniInfo(self
, VfrUniBaseName
):
809 MapFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".map")
811 fInputfile
= open(MapFileName
, "r", 0)
813 FileLinesList
= fInputfile
.readlines()
815 EdkLogger
.error("GenFds", FILE_READ_FAILURE
, "File read failed for %s" %MapFileName
,None)
819 EdkLogger
.error("GenFds", FILE_OPEN_FAILURE
, "File open failed for %s" %MapFileName
,None)
822 for eachLine
in FileLinesList
:
823 for eachName
in VfrUniBaseName
.values():
824 if eachLine
.find(eachName
) != -1:
825 eachLine
= eachLine
.strip()
826 Element
= eachLine
.split()
828 # MSFT/ICC/EBC map file
830 if (len(Element
) == 4):
838 RetValue
.append((eachName
, Element
[2]))
843 elif (len(Element
) == 2) and Element
[0].startswith("0x"):
844 RetValue
.append((eachName
, Element
[0]))
848 ## __GenUniVfrOffsetFile() method
850 # Generate the offset file for the module which contain VFR or UNI file.
852 # @param self The object pointer
853 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
854 # @param UniVfrOffsetFileName The output offset file name.
856 def __GenUniVfrOffsetFile(self
, VfrUniOffsetList
, UniVfrOffsetFileName
):
859 fInputfile
= open(UniVfrOffsetFileName
, "wb+", 0)
861 EdkLogger
.error("GenFds", FILE_OPEN_FAILURE
, "File open failed for %s" %UniVfrOffsetFileName
,None)
863 # Use a instance of StringIO to cache data
864 fStringIO
= StringIO
.StringIO('')
866 for Item
in VfrUniOffsetList
:
867 if (Item
[0].find("Strings") != -1):
869 # UNI offset in image.
871 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
873 UniGuid
= [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
874 UniGuid
= [chr(ItemGuid
) for ItemGuid
in UniGuid
]
875 fStringIO
.write(''.join(UniGuid
))
876 UniValue
= pack ('Q', int (Item
[1], 16))
877 fStringIO
.write (UniValue
)
880 # VFR binary offset in image.
882 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
884 VfrGuid
= [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
885 VfrGuid
= [chr(ItemGuid
) for ItemGuid
in VfrGuid
]
886 fStringIO
.write(''.join(VfrGuid
))
888 VfrValue
= pack ('Q', int (Item
[1], 16))
889 fStringIO
.write (VfrValue
)
892 # write data into file.
895 fInputfile
.write (fStringIO
.getvalue())
897 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)