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
= {}
59 self
.CurrentLineNum
= None
60 self
.CurrentLineContent
= None
62 self
.InfFileName
= None
64 ## GetFinalTargetSuffixMap() method
66 # Get final build target list
67 def GetFinalTargetSuffixMap(self
):
68 if not self
.InfModule
or not self
.CurrentArch
:
70 if not self
.FinalTargetSuffixMap
:
71 FinalBuildTargetList
= GenFdsGlobalVariable
.GetModuleCodaTargetList(self
.InfModule
, self
.CurrentArch
)
72 for File
in FinalBuildTargetList
:
73 self
.FinalTargetSuffixMap
.setdefault(os
.path
.splitext(File
)[1], []).append(File
)
75 # Check if current INF module has DEPEX
76 if '.depex' not in self
.FinalTargetSuffixMap
and self
.InfModule
.ModuleType
!= "USER_DEFINED" \
77 and not self
.InfModule
.DxsFile
and not self
.InfModule
.LibraryClass
:
78 ModuleType
= self
.InfModule
.ModuleType
79 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
81 if ModuleType
!= DataType
.SUP_MODULE_USER_DEFINED
:
82 for LibraryClass
in PlatformDataBase
.LibraryClasses
.GetKeys():
83 if LibraryClass
.startswith("NULL") and PlatformDataBase
.LibraryClasses
[LibraryClass
, ModuleType
]:
84 self
.InfModule
.LibraryClasses
[LibraryClass
] = PlatformDataBase
.LibraryClasses
[LibraryClass
, ModuleType
]
86 StrModule
= str(self
.InfModule
)
88 if StrModule
in PlatformDataBase
.Modules
:
89 PlatformModule
= PlatformDataBase
.Modules
[StrModule
]
90 for LibraryClass
in PlatformModule
.LibraryClasses
:
91 if LibraryClass
.startswith("NULL"):
92 self
.InfModule
.LibraryClasses
[LibraryClass
] = PlatformModule
.LibraryClasses
[LibraryClass
]
94 DependencyList
= [self
.InfModule
]
97 while len(DependencyList
) > 0:
98 Module
= DependencyList
.pop(0)
101 for Dep
in Module
.Depex
[self
.CurrentArch
, ModuleType
]:
103 DepexList
.append('AND')
104 DepexList
.append('(')
105 DepexList
.extend(Dep
)
106 if DepexList
[-1] == 'END': # no need of a END at this time
108 DepexList
.append(')')
109 if 'BEFORE' in DepexList
or 'AFTER' in DepexList
:
111 for LibName
in Module
.LibraryClasses
:
112 if LibName
in LibraryInstance
:
114 if PlatformModule
and LibName
in PlatformModule
.LibraryClasses
:
115 LibraryPath
= PlatformModule
.LibraryClasses
[LibName
]
117 LibraryPath
= PlatformDataBase
.LibraryClasses
[LibName
, ModuleType
]
119 LibraryPath
= Module
.LibraryClasses
[LibName
]
122 LibraryModule
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[LibraryPath
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
123 LibraryInstance
[LibName
] = LibraryModule
124 DependencyList
.append(LibraryModule
)
126 Dpx
= DependencyExpression(DepexList
, ModuleType
, True)
127 if len(Dpx
.PostfixNotation
) != 0:
128 # It means this module has DEPEX
129 self
.FinalTargetSuffixMap
['.depex'] = [os
.path
.join(self
.EfiOutputPath
, self
.BaseName
) + '.depex']
130 return self
.FinalTargetSuffixMap
132 ## __InfParse() method
134 # Parse inf file to get module information
136 # @param self The object pointer
137 # @param Dict dictionary contains macro and value pair
139 def __InfParse__(self
, Dict
= {}):
141 GenFdsGlobalVariable
.VerboseLogger( " Begine parsing INf file : %s" %self
.InfFileName
)
143 self
.InfFileName
= self
.InfFileName
.replace('$(WORKSPACE)', '')
144 if self
.InfFileName
[0] == '\\' or self
.InfFileName
[0] == '/' :
145 self
.InfFileName
= self
.InfFileName
[1:]
147 if self
.InfFileName
.find('$') == -1:
148 InfPath
= NormPath(self
.InfFileName
)
149 if not os
.path
.exists(InfPath
):
150 InfPath
= GenFdsGlobalVariable
.ReplaceWorkspaceMacro(InfPath
)
151 if not os
.path
.exists(InfPath
):
152 EdkLogger
.error("GenFds", GENFDS_ERROR
, "Non-existant Module %s !" % (self
.InfFileName
))
154 self
.CurrentArch
= self
.GetCurrentArch()
156 # Get the InfClass object
159 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
160 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
162 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
164 if self
.CurrentArch
!= None:
166 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, self
.CurrentArch
, GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
168 # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath
170 self
.BaseName
= Inf
.BaseName
171 self
.ModuleGuid
= Inf
.Guid
172 self
.ModuleType
= Inf
.ModuleType
173 if Inf
.Specification
!= None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
174 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
175 if Inf
.AutoGenVersion
< 0x00010005:
176 self
.ModuleType
= Inf
.ComponentType
177 self
.VersionString
= Inf
.Version
178 self
.BinFileList
= Inf
.Binaries
179 self
.SourceFileList
= Inf
.Sources
180 if self
.KeepReloc
== None and Inf
.Shadow
:
181 self
.ShadowFromInfFile
= Inf
.Shadow
184 Inf
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClassObj
, 'COMMON', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
185 self
.BaseName
= Inf
.BaseName
186 self
.ModuleGuid
= Inf
.Guid
187 self
.ModuleType
= Inf
.ModuleType
188 if Inf
.Specification
!= None and 'PI_SPECIFICATION_VERSION' in Inf
.Specification
:
189 self
.PiSpecVersion
= Inf
.Specification
['PI_SPECIFICATION_VERSION']
190 self
.VersionString
= Inf
.Version
191 self
.BinFileList
= Inf
.Binaries
192 self
.SourceFileList
= Inf
.Sources
193 if self
.BinFileList
== []:
194 EdkLogger
.error("GenFds", GENFDS_ERROR
,
195 "INF %s specified in FDF could not be found in build ARCH %s!" \
196 % (self
.InfFileName
, GenFdsGlobalVariable
.ArchList
))
198 if len(self
.SourceFileList
) != 0 and not self
.InDsc
:
199 EdkLogger
.warn("GenFds", GENFDS_ERROR
, "Module %s NOT found in DSC file; Is it really a binary module?" % (self
.InfFileName
))
201 if self
.ModuleType
== 'SMM_CORE' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
202 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
)
204 if Inf
._Defs
!= None and len(Inf
._Defs
) > 0:
205 self
.OptRomDefs
.update(Inf
._Defs
)
209 GenFdsGlobalVariable
.VerboseLogger( "BaseName : %s" %self
.BaseName
)
210 GenFdsGlobalVariable
.VerboseLogger("ModuleGuid : %s" %self
.ModuleGuid
)
211 GenFdsGlobalVariable
.VerboseLogger("ModuleType : %s" %self
.ModuleType
)
212 GenFdsGlobalVariable
.VerboseLogger("VersionString : %s" %self
.VersionString
)
213 GenFdsGlobalVariable
.VerboseLogger("InfFileName :%s" %self
.InfFileName
)
216 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\
219 self
.OutputPath
= os
.path
.join(GenFdsGlobalVariable
.FfsDir
, \
220 self
.ModuleGuid
+ self
.BaseName
)
221 if not os
.path
.exists(self
.OutputPath
) :
222 os
.makedirs(self
.OutputPath
)
224 self
.EfiOutputPath
= self
.__GetEFIOutPutPath
__()
225 GenFdsGlobalVariable
.VerboseLogger( "ModuelEFIPath: " + self
.EfiOutputPath
)
231 # @param self The object pointer
232 # @param Dict dictionary contains macro and value pair
233 # @param FvChildAddr Array of the inside FvImage base address
234 # @param FvParentAddr Parent Fv base address
235 # @retval string Generated FFS file name
237 def GenFfs(self
, Dict
= {}, FvChildAddr
= [], FvParentAddr
=None):
239 # Parse Inf file get Module related information
242 self
.__InfParse
__(Dict
)
245 # Allow binary type module not specify override rule in FDF file.
247 if len(self
.BinFileList
) >0 and not self
.InDsc
:
248 if self
.Rule
== None or self
.Rule
== "":
252 # Get the rule of how to generate Ffs file
254 Rule
= self
.__GetRule
__()
255 GenFdsGlobalVariable
.VerboseLogger( "Packing binaries from inf file : %s" %self
.InfFileName
)
257 # Convert Fv File Type for PI1.1 SMM driver.
259 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
260 if Rule
.FvFileType
== 'DRIVER':
261 Rule
.FvFileType
= 'SMM'
263 # Framework SMM Driver has no SMM FV file type
265 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
266 if Rule
.FvFileType
== 'SMM' or Rule
.FvFileType
== 'SMM_CORE':
267 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File
=self
.InfFileName
)
269 # For the rule only has simpleFile
271 if isinstance (Rule
, RuleSimpleFile
.RuleSimpleFile
) :
272 SectionOutputList
= self
.__GenSimpleFileSection
__(Rule
)
273 FfsOutput
= self
.__GenSimpleFileFfs
__(Rule
, SectionOutputList
)
276 # For Rule has ComplexFile
278 elif isinstance(Rule
, RuleComplexFile
.RuleComplexFile
):
279 InputSectList
, InputSectAlignments
= self
.__GenComplexFileSection
__(Rule
, FvChildAddr
, FvParentAddr
)
280 FfsOutput
= self
.__GenComplexFileFfs
__(Rule
, InputSectList
, InputSectAlignments
)
284 ## __ExtendMacro__() method
286 # Replace macro with its value
288 # @param self The object pointer
289 # @param String The string to be replaced
290 # @retval string Macro replaced string
292 def __ExtendMacro__ (self
, String
):
294 '$(INF_OUTPUT)' : self
.EfiOutputPath
,
295 '$(MODULE_NAME)' : self
.BaseName
,
296 '$(BUILD_NUMBER)': self
.BuildNum
,
297 '$(INF_VERSION)' : self
.VersionString
,
298 '$(NAMED_GUID)' : self
.ModuleGuid
300 String
= GenFdsGlobalVariable
.MacroExtend(String
, MacroDict
)
303 ## __GetRule__() method
305 # Get correct rule for generating FFS for this INF
307 # @param self The object pointer
308 # @retval Rule Rule object
310 def __GetRule__ (self
) :
312 if self
.CurrentArch
== None:
313 CurrentArchList
= ['common']
315 CurrentArchList
.append(self
.CurrentArch
)
317 for CurrentArch
in CurrentArchList
:
318 RuleName
= 'RULE' + \
320 CurrentArch
.upper() + \
322 self
.ModuleType
.upper()
323 if self
.Rule
!= None:
324 RuleName
= RuleName
+ \
328 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
330 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
333 RuleName
= 'RULE' + \
337 self
.ModuleType
.upper()
339 if self
.Rule
!= None:
340 RuleName
= RuleName
+ \
344 GenFdsGlobalVariable
.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName
, self
.InfFileName
))
346 Rule
= GenFdsGlobalVariable
.FdfParser
.Profile
.RuleDict
.get(RuleName
)
348 GenFdsGlobalVariable
.VerboseLogger ("Want To Find Rule Name is : " + RuleName
)
352 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'Don\'t Find common rule %s for INF %s' \
353 % (RuleName
, self
.InfFileName
))
355 ## __GetPlatformArchList__() method
357 # Get Arch list this INF built under
359 # @param self The object pointer
360 # @retval list Arch list
362 def __GetPlatformArchList__(self
):
364 InfFileKey
= os
.path
.normpath(os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
))
366 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'IA32', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
367 if PlatformDataBase
!= None:
368 if InfFileKey
in PlatformDataBase
.Modules
:
369 DscArchList
.append ('IA32')
371 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'X64', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
372 if PlatformDataBase
!= None:
373 if InfFileKey
in PlatformDataBase
.Modules
:
374 DscArchList
.append ('X64')
376 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'IPF', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
377 if PlatformDataBase
!= None:
378 if InfFileKey
in (PlatformDataBase
.Modules
):
379 DscArchList
.append ('IPF')
381 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'ARM', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
382 if PlatformDataBase
!= None:
383 if InfFileKey
in (PlatformDataBase
.Modules
):
384 DscArchList
.append ('ARM')
386 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'EBC', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
387 if PlatformDataBase
!= None:
388 if InfFileKey
in (PlatformDataBase
.Modules
):
389 DscArchList
.append ('EBC')
391 PlatformDataBase
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[GenFdsGlobalVariable
.ActivePlatform
, 'AARCH64', GenFdsGlobalVariable
.TargetName
, GenFdsGlobalVariable
.ToolChainTag
]
392 if PlatformDataBase
!= None:
393 if InfFileKey
in (PlatformDataBase
.Modules
):
394 DscArchList
.append ('AARCH64')
398 ## GetCurrentArch() method
400 # Get Arch list of the module from this INF is to be placed into flash
402 # @param self The object pointer
403 # @retval list Arch list
405 def GetCurrentArch(self
) :
407 TargetArchList
= GenFdsGlobalVariable
.ArchList
409 PlatformArchList
= self
.__GetPlatformArchList
__()
411 CurArchList
= TargetArchList
412 if PlatformArchList
!= []:
413 CurArchList
= list(set (TargetArchList
) & set (PlatformArchList
))
414 GenFdsGlobalVariable
.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList
))
417 if self
.KeyStringList
!= []:
418 for Key
in self
.KeyStringList
:
419 Key
= GenFdsGlobalVariable
.MacroExtend(Key
)
420 Target
, Tag
, Arch
= Key
.split('_')
421 if Arch
in CurArchList
:
422 ArchList
.append(Arch
)
423 if Target
not in self
.TargetOverrideList
:
424 self
.TargetOverrideList
.append(Target
)
426 ArchList
= CurArchList
428 UseArchList
= TargetArchList
429 if self
.UseArch
!= None:
431 UseArchList
.append(self
.UseArch
)
432 ArchList
= list(set (UseArchList
) & set (ArchList
))
434 self
.InfFileName
= NormPath(self
.InfFileName
)
435 if len(PlatformArchList
) == 0:
437 PathClassObj
= PathClass(self
.InfFileName
, GenFdsGlobalVariable
.WorkSpaceDir
)
438 ErrorCode
, ErrorInfo
= PathClassObj
.Validate(".inf")
440 EdkLogger
.error("GenFds", ErrorCode
, ExtraData
=ErrorInfo
)
441 if len(ArchList
) == 1:
444 elif len(ArchList
) > 1:
445 if len(PlatformArchList
) == 0:
446 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
))
448 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
))
450 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." \
451 % (self
.InfFileName
, str(PlatformArchList
), GenFdsGlobalVariable
.ActivePlatform
, str(set (UseArchList
) & set (TargetArchList
))))
453 ## __GetEFIOutPutPath__() method
455 # Get the output path for generated files
457 # @param self The object pointer
458 # @retval string Path that output files from this INF go to
460 def __GetEFIOutPutPath__(self
):
463 (ModulePath
, FileName
) = os
.path
.split(self
.InfFileName
)
464 Index
= FileName
.rfind('.')
465 FileName
= FileName
[0:Index
]
467 if self
.CurrentArch
!= None:
468 Arch
= self
.CurrentArch
470 OutputPath
= os
.path
.join(GenFdsGlobalVariable
.OutputDirDict
[Arch
],
476 OutputPath
= os
.path
.realpath(OutputPath
)
479 ## __GenSimpleFileSection__() method
481 # Generate section by specified file name or a list of files with file extension
483 # @param self The object pointer
484 # @param Rule The rule object used to generate section
485 # @retval string File name of the generated section file
487 def __GenSimpleFileSection__(self
, Rule
):
489 # Prepare the parameter of GenSection
493 GenSecInputFile
= None
494 if Rule
.FileName
!= None:
495 GenSecInputFile
= self
.__ExtendMacro
__(Rule
.FileName
)
496 if os
.path
.isabs(GenSecInputFile
):
497 GenSecInputFile
= os
.path
.normpath(GenSecInputFile
)
499 GenSecInputFile
= os
.path
.normpath(os
.path
.join(self
.EfiOutputPath
, GenSecInputFile
))
501 FileList
, IsSect
= Section
.Section
.GetFileList(self
, '', Rule
.FileExtension
)
504 SectionType
= Rule
.SectionType
506 # Convert Fv Section Type for PI1.1 SMM driver.
508 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
509 if SectionType
== 'DXE_DEPEX':
510 SectionType
= 'SMM_DEPEX'
512 # Framework SMM Driver has no SMM_DEPEX section type
514 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
515 if SectionType
== 'SMM_DEPEX':
516 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
518 if self
.ModuleType
in ('SEC', 'PEI_CORE', 'PEIM'):
519 if self
.KeepReloc
!= None:
520 NoStrip
= self
.KeepReloc
521 elif Rule
.KeepReloc
!= None:
522 NoStrip
= Rule
.KeepReloc
523 elif self
.ShadowFromInfFile
!= None:
524 NoStrip
= self
.ShadowFromInfFile
527 for File
in FileList
:
530 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
531 Ffs
.Ffs
.SectionSuffix
[SectionType
] + 'SEC' + SecNum
533 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
534 File
= GenFdsGlobalVariable
.MacroExtend(File
, Dict
, self
.CurrentArch
)
536 #Get PE Section alignment when align is set to AUTO
537 if self
.Alignment
== 'Auto' and (SectionType
== 'PE32' or SectionType
== 'TE'):
538 ImageObj
= PeImageClass (File
)
539 if ImageObj
.SectionAlignment
< 0x400:
540 self
.Alignment
= str (ImageObj
.SectionAlignment
)
542 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
545 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
546 if not os
.path
.exists(FileBeforeStrip
) or \
547 (os
.path
.getmtime(File
) > os
.path
.getmtime(FileBeforeStrip
)):
548 shutil
.copyfile(File
, FileBeforeStrip
)
549 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
550 GenFdsGlobalVariable
.GenerateFirmwareImage(
557 if SectionType
== 'TE':
558 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
559 GenFdsGlobalVariable
.GenerateFirmwareImage(
566 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [File
], Section
.Section
.SectionType
[SectionType
])
567 OutputFileList
.append(OutputFile
)
570 GenSecOutputFile
= self
.__ExtendMacro
__(Rule
.NameGuid
) + \
571 Ffs
.Ffs
.SectionSuffix
[SectionType
] + 'SEC' + SecNum
572 OutputFile
= os
.path
.join(self
.OutputPath
, GenSecOutputFile
)
573 GenSecInputFile
= GenFdsGlobalVariable
.MacroExtend(GenSecInputFile
, Dict
, self
.CurrentArch
)
575 #Get PE Section alignment when align is set to AUTO
576 if self
.Alignment
== 'Auto' and (SectionType
== 'PE32' or SectionType
== 'TE'):
577 ImageObj
= PeImageClass (GenSecInputFile
)
578 if ImageObj
.SectionAlignment
< 0x400:
579 self
.Alignment
= str (ImageObj
.SectionAlignment
)
581 self
.Alignment
= str (ImageObj
.SectionAlignment
/ 0x400) + 'K'
584 FileBeforeStrip
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.reloc')
585 if not os
.path
.exists(FileBeforeStrip
) or \
586 (os
.path
.getmtime(GenSecInputFile
) > os
.path
.getmtime(FileBeforeStrip
)):
587 shutil
.copyfile(GenSecInputFile
, FileBeforeStrip
)
588 StrippedFile
= os
.path
.join(self
.OutputPath
, ModuleName
+ '.stipped')
589 GenFdsGlobalVariable
.GenerateFirmwareImage(
594 GenSecInputFile
= StrippedFile
596 if SectionType
== 'TE':
597 TeFile
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ 'Te.raw')
598 GenFdsGlobalVariable
.GenerateFirmwareImage(
603 GenSecInputFile
= TeFile
605 GenFdsGlobalVariable
.GenerateSection(OutputFile
, [GenSecInputFile
], Section
.Section
.SectionType
[SectionType
])
606 OutputFileList
.append(OutputFile
)
608 return OutputFileList
610 ## __GenSimpleFileFfs__() method
614 # @param self The object pointer
615 # @param Rule The rule object used to generate section
616 # @param InputFileList The output file list from GenSection
617 # @retval string Generated FFS file name
619 def __GenSimpleFileFfs__(self
, Rule
, InputFileList
):
620 FfsOutput
= self
.OutputPath
+ \
622 self
.__ExtendMacro
__(Rule
.NameGuid
) + \
625 GenFdsGlobalVariable
.VerboseLogger(self
.__ExtendMacro
__(Rule
.NameGuid
))
627 SectionAlignments
= []
628 for InputFile
in InputFileList
:
629 InputSection
.append(InputFile
)
630 SectionAlignments
.append(Rule
.SectAlignment
)
632 if Rule
.NameGuid
!= None and Rule
.NameGuid
.startswith('PCD('):
633 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
634 if len(PcdValue
) == 0:
635 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
637 if PcdValue
.startswith('{'):
638 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
639 RegistryGuidStr
= PcdValue
640 if len(RegistryGuidStr
) == 0:
641 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
643 self
.ModuleGuid
= RegistryGuidStr
645 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputSection
,
646 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
647 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
648 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
649 SectionAlign
=SectionAlignments
653 ## __GenComplexFileSection__() method
655 # Generate section by sections in Rule
657 # @param self The object pointer
658 # @param Rule The rule object used to generate section
659 # @param FvChildAddr Array of the inside FvImage base address
660 # @param FvParentAddr Parent Fv base address
661 # @retval string File name of the generated section file
663 def __GenComplexFileSection__(self
, Rule
, FvChildAddr
, FvParentAddr
):
664 if self
.ModuleType
in ('SEC', 'PEI_CORE', 'PEIM'):
665 if Rule
.KeepReloc
!= None:
666 self
.KeepRelocFromRule
= Rule
.KeepReloc
670 HasGneratedFlag
= False
671 for Sect
in Rule
.SectionList
:
672 SecIndex
= '%d' %Index
675 # Convert Fv Section Type for PI1.1 SMM driver.
677 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) >= 0x0001000A:
678 if Sect
.SectionType
== 'DXE_DEPEX':
679 Sect
.SectionType
= 'SMM_DEPEX'
681 # Framework SMM Driver has no SMM_DEPEX section type
683 if self
.ModuleType
== 'DXE_SMM_DRIVER' and int(self
.PiSpecVersion
, 16) < 0x0001000A:
684 if Sect
.SectionType
== 'SMM_DEPEX':
685 EdkLogger
.error("GenFds", FORMAT_NOT_SUPPORTED
, "Framework SMM module doesn't support SMM_DEPEX section type", File
=self
.InfFileName
)
687 # process the inside FvImage from FvSection or GuidSection
689 if FvChildAddr
!= []:
690 if isinstance(Sect
, FvImageSection
):
691 Sect
.FvAddr
= FvChildAddr
.pop(0)
692 elif isinstance(Sect
, GuidSection
):
693 Sect
.FvAddr
= FvChildAddr
694 if FvParentAddr
!= None and isinstance(Sect
, GuidSection
):
695 Sect
.FvParentAddr
= FvParentAddr
697 if Rule
.KeyStringList
!= []:
698 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, Rule
.KeyStringList
, self
)
700 SectList
, Align
= Sect
.GenSection(self
.OutputPath
, self
.ModuleGuid
, SecIndex
, self
.KeyStringList
, self
)
702 if not HasGneratedFlag
:
703 UniVfrOffsetFileSection
= ""
704 ModuleFileName
= os
.path
.join(GenFdsGlobalVariable
.WorkSpaceDir
, self
.InfFileName
)
705 InfData
= GenFdsGlobalVariable
.WorkSpace
.BuildObject
[PathClass(ModuleFileName
), self
.CurrentArch
]
707 # Search the source list in InfData to find if there are .vfr file exist.
710 VfrUniOffsetList
= []
711 for SourceFile
in InfData
.Sources
:
712 if SourceFile
.Type
.upper() == ".VFR" :
714 # search the .map file to find the offset of vfr binary in the PE32+/TE file.
716 VfrUniBaseName
[SourceFile
.BaseName
] = (SourceFile
.BaseName
+ "Bin")
717 if SourceFile
.Type
.upper() == ".UNI" :
719 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
721 VfrUniBaseName
["UniOffsetName"] = (self
.BaseName
+ "Strings")
724 if len(VfrUniBaseName
) > 0:
725 VfrUniOffsetList
= self
.__GetBuildOutputMapFileVfrUniInfo
(VfrUniBaseName
)
727 # Generate the Raw data of raw section
729 os
.path
.join( self
.OutputPath
, self
.BaseName
+ '.offset')
730 UniVfrOffsetFileName
= os
.path
.join( self
.OutputPath
, self
.BaseName
+ '.offset')
731 UniVfrOffsetFileSection
= os
.path
.join( self
.OutputPath
, self
.BaseName
+ 'Offset' + '.raw')
733 self
.__GenUniVfrOffsetFile
(VfrUniOffsetList
, UniVfrOffsetFileName
)
735 UniVfrOffsetFileNameList
= []
736 UniVfrOffsetFileNameList
.append(UniVfrOffsetFileName
)
737 """Call GenSection"""
738 GenFdsGlobalVariable
.GenerateSection(UniVfrOffsetFileSection
,
739 UniVfrOffsetFileNameList
,
742 os
.remove(UniVfrOffsetFileName
)
743 SectList
.append(UniVfrOffsetFileSection
)
744 HasGneratedFlag
= True
746 for SecName
in SectList
:
747 SectFiles
.append(SecName
)
748 SectAlignments
.append(Align
)
750 return SectFiles
, SectAlignments
752 ## __GenComplexFileFfs__() method
756 # @param self The object pointer
757 # @param Rule The rule object used to generate section
758 # @param InputFileList The output file list from GenSection
759 # @retval string Generated FFS file name
761 def __GenComplexFileFfs__(self
, Rule
, InputFile
, Alignments
):
763 if Rule
.NameGuid
!= None and Rule
.NameGuid
.startswith('PCD('):
764 PcdValue
= GenFdsGlobalVariable
.GetPcdValue(Rule
.NameGuid
)
765 if len(PcdValue
) == 0:
766 EdkLogger
.error("GenFds", GENFDS_ERROR
, '%s NOT defined.' \
768 if PcdValue
.startswith('{'):
769 PcdValue
= GuidStructureByteArrayToGuidString(PcdValue
)
770 RegistryGuidStr
= PcdValue
771 if len(RegistryGuidStr
) == 0:
772 EdkLogger
.error("GenFds", GENFDS_ERROR
, 'GUID value for %s in wrong format.' \
774 self
.ModuleGuid
= RegistryGuidStr
776 FfsOutput
= os
.path
.join( self
.OutputPath
, self
.ModuleGuid
+ '.ffs')
777 GenFdsGlobalVariable
.GenerateFfs(FfsOutput
, InputFile
,
778 Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
],
779 self
.ModuleGuid
, Fixed
=Rule
.Fixed
,
780 CheckSum
=Rule
.CheckSum
, Align
=Rule
.Alignment
,
781 SectionAlign
=Alignments
785 ## __GetGenFfsCmdParameter__() method
787 # Create parameter string for GenFfs
789 # @param self The object pointer
790 # @param Rule The rule object used to generate section
791 # @retval tuple (FileType, Fixed, CheckSum, Alignment)
793 def __GetGenFfsCmdParameter__(self
, Rule
):
795 result
+= ('-t', Ffs
.Ffs
.FdfFvFileTypeToFileType
[Rule
.FvFileType
])
796 if Rule
.Fixed
!= False:
798 if Rule
.CheckSum
!= False:
801 if Rule
.Alignment
!= None and Rule
.Alignment
!= '':
802 result
+= ('-a', Rule
.Alignment
)
806 ## __GetBuildOutputMapFileVfrUniInfo() method
808 # Find the offset of UNI/INF object offset in the EFI image file.
810 # @param self The object pointer
811 # @param VfrUniBaseName A name list contain the UNI/INF object name.
812 # @retval RetValue A list contain offset of UNI/INF object.
814 def __GetBuildOutputMapFileVfrUniInfo(self
, VfrUniBaseName
):
818 MapFileName
= os
.path
.join(self
.EfiOutputPath
, self
.BaseName
+ ".map")
820 fInputfile
= open(MapFileName
, "r", 0)
822 FileLinesList
= fInputfile
.readlines()
824 EdkLogger
.error("GenFds", FILE_READ_FAILURE
, "File read failed for %s" %MapFileName
,None)
828 EdkLogger
.error("GenFds", FILE_OPEN_FAILURE
, "File open failed for %s" %MapFileName
,None)
831 for eachLine
in FileLinesList
:
832 for eachName
in VfrUniBaseName
.values():
833 if eachLine
.find(eachName
) != -1:
834 eachLine
= eachLine
.strip()
835 Element
= eachLine
.split()
837 # MSFT/ICC/EBC map file
839 if (len(Element
) == 4):
847 RetValue
.append((eachName
, Element
[2]))
852 elif (len(Element
) == 2) and Element
[0].startswith("0x"):
853 RetValue
.append((eachName
, Element
[0]))
857 ## __GenUniVfrOffsetFile() method
859 # Generate the offset file for the module which contain VFR or UNI file.
861 # @param self The object pointer
862 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.
863 # @param UniVfrOffsetFileName The output offset file name.
865 def __GenUniVfrOffsetFile(self
, VfrUniOffsetList
, UniVfrOffsetFileName
):
868 fInputfile
= open(UniVfrOffsetFileName
, "wb+", 0)
870 EdkLogger
.error("GenFds", FILE_OPEN_FAILURE
, "File open failed for %s" %UniVfrOffsetFileName
,None)
872 # Use a instance of StringIO to cache data
873 fStringIO
= StringIO
.StringIO('')
875 for Item
in VfrUniOffsetList
:
876 if (Item
[0].find("Strings") != -1):
878 # UNI offset in image.
880 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
882 UniGuid
= [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
883 UniGuid
= [chr(ItemGuid
) for ItemGuid
in UniGuid
]
884 fStringIO
.write(''.join(UniGuid
))
885 UniValue
= pack ('Q', int (Item
[1], 16))
886 fStringIO
.write (UniValue
)
889 # VFR binary offset in image.
891 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
893 VfrGuid
= [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
894 VfrGuid
= [chr(ItemGuid
) for ItemGuid
in VfrGuid
]
895 fStringIO
.write(''.join(VfrGuid
))
897 VfrValue
= pack ('Q', int (Item
[1], 16))
898 fStringIO
.write (VfrValue
)
901 # write data into file.
904 fInputfile
.write (fStringIO
.getvalue())
906 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)