Sync EDKII BaseTools to BaseTools project r1903.
[efi/edk2/.git] / edk2 / BaseTools / Source / Python / GenFds / FfsInfStatement.py
1 ## @file\r
2 # process FFS generation from INF statement\r
3 #\r
4 #  Copyright (c) 2007 - 2010, Intel Corporation\r
5 #\r
6 #  All rights reserved. This program and the accompanying materials\r
7 #  are licensed and made available under the terms and conditions of the BSD License\r
8 #  which accompanies this distribution.  The full text of the license may be found at\r
9 #  http://opensource.org/licenses/bsd-license.php\r
10 #\r
11 #  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 #  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13 #\r
14 \r
15 ##\r
16 # Import Modules\r
17 #\r
18 import Rule\r
19 import os\r
20 import shutil\r
21 from GenFdsGlobalVariable import GenFdsGlobalVariable\r
22 import Ffs\r
23 import subprocess\r
24 import sys\r
25 import Section\r
26 import RuleSimpleFile\r
27 import RuleComplexFile\r
28 from CommonDataClass.FdfClass import FfsInfStatementClassObject\r
29 from Common.String import *\r
30 from Common.Misc import PathClass\r
31 from Common.Misc import GuidStructureByteArrayToGuidString\r
32 from Common import EdkLogger\r
33 from Common.BuildToolError import *\r
34 from GuidSection import GuidSection\r
35 from FvImageSection import FvImageSection\r
36 from Common.Misc import PeImageClass\r
37 \r
38 ## generate FFS from INF\r
39 #\r
40 #\r
41 class FfsInfStatement(FfsInfStatementClassObject):\r
42     ## The constructor\r
43     #\r
44     #   @param  self        The object pointer\r
45     #\r
46     def __init__(self):\r
47         FfsInfStatementClassObject.__init__(self)\r
48         self.TargetOverrideList = []\r
49         self.ShadowFromInfFile = None\r
50         self.KeepRelocFromRule = None\r
51         self.InDsc = True\r
52         self.OptRomDefs = {}\r
53         self.PiSpecVersion = 0\r
54         \r
55     ## __InfParse() method\r
56     #\r
57     #   Parse inf file to get module information\r
58     #\r
59     #   @param  self        The object pointer\r
60     #   @param  Dict        dictionary contains macro and value pair\r
61     #\r
62     def __InfParse__(self, Dict = {}):\r
63 \r
64         GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName)\r
65 \r
66         self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '')\r
67         if self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' :\r
68             self.InfFileName = self.InfFileName[1:]\r
69 \r
70         if self.InfFileName.find('$') == -1:\r
71             InfPath = NormPath(self.InfFileName)\r
72             if not os.path.exists(InfPath):\r
73                 InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath)\r
74                 if not os.path.exists(InfPath):\r
75                     EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName))\r
76 \r
77         self.CurrentArch = self.GetCurrentArch()\r
78         #\r
79         # Get the InfClass object\r
80         #\r
81 \r
82         PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)\r
83         ErrorCode, ErrorInfo = PathClassObj.Validate()\r
84         if ErrorCode != 0:\r
85             EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
86         \r
87         if self.CurrentArch != None:\r
88 \r
89             Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch]\r
90             #\r
91             # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath\r
92             #\r
93             self.BaseName = Inf.BaseName\r
94             self.ModuleGuid = Inf.Guid\r
95             self.ModuleType = Inf.ModuleType\r
96             if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:\r
97                 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']\r
98             if Inf.AutoGenVersion < 0x00010005:\r
99                 self.ModuleType = Inf.ComponentType\r
100             self.VersionString = Inf.Version\r
101             self.BinFileList = Inf.Binaries\r
102             self.SourceFileList = Inf.Sources\r
103             if self.KeepReloc == None and Inf.Shadow:\r
104                 self.ShadowFromInfFile = Inf.Shadow\r
105 \r
106         else:\r
107             Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON']\r
108             self.BaseName = Inf.BaseName\r
109             self.ModuleGuid = Inf.Guid\r
110             self.ModuleType = Inf.ModuleType\r
111             if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:\r
112                 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']\r
113             self.VersionString = Inf.Version\r
114             self.BinFileList = Inf.Binaries\r
115             self.SourceFileList = Inf.Sources\r
116             if self.BinFileList == []:\r
117                 EdkLogger.error("GenFds", GENFDS_ERROR,\r
118                                 "INF %s specified in FDF could not be found in build ARCH %s!" \\r
119                                 % (self.InfFileName, GenFdsGlobalVariable.ArchList))\r
120 \r
121         if len(self.SourceFileList) != 0 and not self.InDsc:\r
122             EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName))\r
123 \r
124         if self.ModuleType == 'SMM_CORE' and self.PiSpecVersion < 0x0001000A:\r
125             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)      \r
126 \r
127         if Inf._Defs != None and len(Inf._Defs) > 0:\r
128             self.OptRomDefs.update(Inf._Defs)\r
129             \r
130         GenFdsGlobalVariable.VerboseLogger( "BaseName : %s" %self.BaseName)\r
131         GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" %self.ModuleGuid)\r
132         GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" %self.ModuleType)\r
133         GenFdsGlobalVariable.VerboseLogger("VersionString : %s" %self.VersionString)\r
134         GenFdsGlobalVariable.VerboseLogger("InfFileName :%s"  %self.InfFileName)\r
135 \r
136         #\r
137         # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\\r
138         #\r
139 \r
140         self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \\r
141                                        self.ModuleGuid + self.BaseName)\r
142         if not os.path.exists(self.OutputPath) :\r
143             os.makedirs(self.OutputPath)\r
144 \r
145         self.EfiOutputPath = self.__GetEFIOutPutPath__()\r
146         GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)\r
147 \r
148     ## GenFfs() method\r
149     #\r
150     #   Generate FFS\r
151     #\r
152     #   @param  self         The object pointer\r
153     #   @param  Dict         dictionary contains macro and value pair\r
154     #   @param  FvChildAddr  Array of the inside FvImage base address\r
155     #   @param  FvParentAddr Parent Fv base address\r
156     #   @retval string       Generated FFS file name\r
157     #\r
158     def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None):\r
159         #\r
160         # Parse Inf file get Module related information\r
161         #\r
162 \r
163         self.__InfParse__(Dict)\r
164         #\r
165         # Get the rule of how to generate Ffs file\r
166         #\r
167         Rule = self.__GetRule__()\r
168         GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName)\r
169         #\r
170         # Convert Fv File Type for PI1.1 SMM driver.\r
171         #\r
172         if self.ModuleType == 'DXE_SMM_DRIVER' and self.PiSpecVersion >= 0x0001000A:\r
173             if Rule.FvFileType == 'DRIVER':\r
174                 Rule.FvFileType = 'SMM'\r
175         #\r
176         # Framework SMM Driver has no SMM FV file type\r
177         #\r
178         if self.ModuleType == 'DXE_SMM_DRIVER' and self.PiSpecVersion < 0x0001000A:\r
179             if Rule.FvFileType == 'SMM' or Rule.FvFileType == 'SMM_CORE':\r
180                 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File=self.InfFileName)\r
181         #\r
182         # For the rule only has simpleFile\r
183         #\r
184         if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) :\r
185             SectionOutputList = self.__GenSimpleFileSection__(Rule)\r
186             FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList)\r
187             return FfsOutput\r
188         #\r
189         # For Rule has ComplexFile\r
190         #\r
191         elif isinstance(Rule, RuleComplexFile.RuleComplexFile):\r
192             InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr)\r
193             FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments)\r
194 \r
195             return FfsOutput\r
196 \r
197     ## __ExtendMacro__() method\r
198     #\r
199     #   Replace macro with its value\r
200     #\r
201     #   @param  self        The object pointer\r
202     #   @param  String      The string to be replaced\r
203     #   @retval string      Macro replaced string\r
204     #\r
205     def __ExtendMacro__ (self, String):\r
206         MacroDict = {\r
207             '$(INF_OUTPUT)'  : self.EfiOutputPath,\r
208             '$(MODULE_NAME)' : self.BaseName,\r
209             '$(BUILD_NUMBER)': self.BuildNum,\r
210             '$(INF_VERSION)' : self.VersionString,\r
211             '$(NAMED_GUID)'  : self.ModuleGuid\r
212         }\r
213         String = GenFdsGlobalVariable.MacroExtend(String, MacroDict)\r
214         return String\r
215 \r
216     ## __GetRule__() method\r
217     #\r
218     #   Get correct rule for generating FFS for this INF\r
219     #\r
220     #   @param  self        The object pointer\r
221     #   @retval Rule        Rule object\r
222     #\r
223     def __GetRule__ (self) :\r
224         CurrentArchList = []\r
225         if self.CurrentArch == None:\r
226             CurrentArchList = ['common']\r
227         else:\r
228             CurrentArchList.append(self.CurrentArch)\r
229 \r
230         for CurrentArch in CurrentArchList:\r
231             RuleName = 'RULE'              + \\r
232                        '.'                 + \\r
233                        CurrentArch.upper() + \\r
234                        '.'                 + \\r
235                        self.ModuleType.upper()\r
236             if self.Rule != None:\r
237                 RuleName = RuleName + \\r
238                            '.'      + \\r
239                            self.Rule.upper()\r
240 \r
241             Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)\r
242             if Rule != None:\r
243                 GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)\r
244                 return Rule\r
245 \r
246         RuleName = 'RULE'      + \\r
247                    '.'         + \\r
248                    'COMMON'    + \\r
249                    '.'         + \\r
250                    self.ModuleType.upper()\r
251 \r
252         if self.Rule != None:\r
253             RuleName = RuleName + \\r
254                        '.'      + \\r
255                        self.Rule.upper()\r
256 \r
257         GenFdsGlobalVariable.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName, self.InfFileName))\r
258 \r
259         Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)\r
260         if Rule != None:\r
261             GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)\r
262             return Rule\r
263 \r
264         if Rule == None :\r
265             EdkLogger.error("GenFds", GENFDS_ERROR, 'Don\'t Find common rule %s for INF %s' \\r
266                             % (RuleName, self.InfFileName))\r
267 \r
268     ## __GetPlatformArchList__() method\r
269     #\r
270     #   Get Arch list this INF built under\r
271     #\r
272     #   @param  self        The object pointer\r
273     #   @retval list        Arch list\r
274     #\r
275     def __GetPlatformArchList__(self):\r
276 \r
277         InfFileKey = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))\r
278         DscArchList = []\r
279         PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32']\r
280         if  PlatformDataBase != None:\r
281             if InfFileKey in PlatformDataBase.Modules:\r
282                 DscArchList.append ('IA32')\r
283 \r
284         PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'X64']\r
285         if  PlatformDataBase != None:\r
286             if InfFileKey in PlatformDataBase.Modules:\r
287                 DscArchList.append ('X64')\r
288 \r
289         PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IPF']\r
290         if PlatformDataBase != None:\r
291             if InfFileKey in (PlatformDataBase.Modules):\r
292                 DscArchList.append ('IPF')\r
293 \r
294         PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'ARM']\r
295         if PlatformDataBase != None:\r
296             if InfFileKey in (PlatformDataBase.Modules):\r
297                 DscArchList.append ('ARM')\r
298 \r
299         PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'EBC']\r
300         if PlatformDataBase != None:\r
301             if InfFileKey in (PlatformDataBase.Modules):\r
302                 DscArchList.append ('EBC')\r
303 \r
304         return DscArchList\r
305 \r
306     ## GetCurrentArch() method\r
307     #\r
308     #   Get Arch list of the module from this INF is to be placed into flash\r
309     #\r
310     #   @param  self        The object pointer\r
311     #   @retval list        Arch list\r
312     #\r
313     def GetCurrentArch(self) :\r
314 \r
315         TargetArchList = GenFdsGlobalVariable.ArchList\r
316 \r
317         PlatformArchList = self.__GetPlatformArchList__()\r
318 \r
319         CurArchList = TargetArchList\r
320         if PlatformArchList != []:\r
321             CurArchList = list(set (TargetArchList) & set (PlatformArchList))\r
322         GenFdsGlobalVariable.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList))\r
323 \r
324         ArchList = []\r
325         if self.KeyStringList != []:\r
326             for Key in self.KeyStringList:\r
327                 Key = GenFdsGlobalVariable.MacroExtend(Key)\r
328                 Target, Tag, Arch = Key.split('_')\r
329                 if Arch in CurArchList:\r
330                     ArchList.append(Arch)\r
331                 if Target not in self.TargetOverrideList:\r
332                     self.TargetOverrideList.append(Target)\r
333         else:\r
334             ArchList = CurArchList\r
335 \r
336         UseArchList = TargetArchList\r
337         if self.UseArch != None:\r
338             UseArchList = []\r
339             UseArchList.append(self.UseArch)\r
340             ArchList = list(set (UseArchList) & set (ArchList))\r
341 \r
342         self.InfFileName = NormPath(self.InfFileName)\r
343         if len(PlatformArchList) == 0:\r
344             self.InDsc = False\r
345             PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)\r
346             ErrorCode, ErrorInfo = PathClassObj.Validate()\r
347             if ErrorCode != 0:\r
348                 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
349         if len(ArchList) == 1:\r
350             Arch = ArchList[0]\r
351             return Arch\r
352         elif len(ArchList) > 1:\r
353             if len(PlatformArchList) == 0:\r
354                 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))\r
355             else:\r
356                 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))\r
357         else:\r
358             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." \\r
359                             % (self.InfFileName, str(PlatformArchList), GenFdsGlobalVariable.ActivePlatform, str(set (UseArchList) & set (TargetArchList))))\r
360 \r
361     ## __GetEFIOutPutPath__() method\r
362     #\r
363     #   Get the output path for generated files\r
364     #\r
365     #   @param  self        The object pointer\r
366     #   @retval string      Path that output files from this INF go to\r
367     #\r
368     def __GetEFIOutPutPath__(self):\r
369         Arch = ''\r
370         OutputPath = ''\r
371         (ModulePath, FileName) = os.path.split(self.InfFileName)\r
372         Index = FileName.find('.')\r
373         FileName = FileName[0:Index]\r
374         Arch = "NoneArch"\r
375         if self.CurrentArch != None:\r
376             Arch = self.CurrentArch\r
377 \r
378         OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],\r
379                                   Arch ,\r
380                                   ModulePath,\r
381                                   FileName,\r
382                                   'OUTPUT'\r
383                                   )\r
384         OutputPath = os.path.realpath(OutputPath)\r
385         return OutputPath\r
386 \r
387     ## __GenSimpleFileSection__() method\r
388     #\r
389     #   Generate section by specified file name or a list of files with file extension\r
390     #\r
391     #   @param  self        The object pointer\r
392     #   @param  Rule        The rule object used to generate section\r
393     #   @retval string      File name of the generated section file\r
394     #\r
395     def __GenSimpleFileSection__(self, Rule):\r
396         #\r
397         # Prepare the parameter of GenSection\r
398         #\r
399         FileList = []\r
400         OutputFileList = []\r
401         GenSecInputFile = None\r
402         if Rule.FileName != None:\r
403             GenSecInputFile = self.__ExtendMacro__(Rule.FileName)\r
404             if os.path.isabs(GenSecInputFile):
405                 GenSecInputFile = os.path.normpath(GenSecInputFile)
406             else:
407                 GenSecInputFile = os.path.normpath(os.path.join(self.EfiOutputPath, GenSecInputFile))\r
408         else:\r
409             FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension)\r
410 \r
411         Index = 1\r
412         SectionType = Rule.SectionType\r
413         #\r
414         # Convert Fv Section Type for PI1.1 SMM driver.\r
415         #\r
416         if self.ModuleType == 'DXE_SMM_DRIVER' and self.PiSpecVersion >= 0x0001000A:\r
417             if SectionType == 'DXE_DEPEX':\r
418                 SectionType = 'SMM_DEPEX'\r
419         #\r
420         # Framework SMM Driver has no SMM_DEPEX section type\r
421         #\r
422         if self.ModuleType == 'DXE_SMM_DRIVER' and self.PiSpecVersion < 0x0001000A:\r
423             if SectionType == 'SMM_DEPEX':\r
424                 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)\r
425         NoStrip = True\r
426         if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):\r
427             if self.KeepReloc != None:\r
428                 NoStrip = self.KeepReloc\r
429             elif Rule.KeepReloc != None:\r
430                 NoStrip = Rule.KeepReloc\r
431             elif self.ShadowFromInfFile != None:\r
432                 NoStrip = self.ShadowFromInfFile\r
433 \r
434         if FileList != [] :\r
435             for File in FileList:\r
436 \r
437                 SecNum = '%d' %Index\r
438                 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \\r
439                               Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum\r
440                 Index = Index + 1\r
441                 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)\r
442                 File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)\r
443 \r
444                 #Get PE Section alignment when align is set to AUTO\r
445                 if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):\r
446                     ImageObj = PeImageClass (File)\r
447                     if ImageObj.SectionAlignment < 0x400:\r
448                         self.Alignment = str (ImageObj.SectionAlignment)\r
449                     else:\r
450                         self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'\r
451 \r
452                 if not NoStrip:\r
453                     FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')\r
454                     if not os.path.exists(FileBeforeStrip) or \\r
455                         (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):\r
456                         shutil.copyfile(File, FileBeforeStrip)\r
457                     StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')\r
458                     GenFdsGlobalVariable.GenerateFirmwareImage(\r
459                                             StrippedFile,\r
460                                             [File],\r
461                                             Strip=True\r
462                                             )\r
463                     File = StrippedFile\r
464 \r
465                 if SectionType == 'TE':\r
466                     TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')\r
467                     GenFdsGlobalVariable.GenerateFirmwareImage(\r
468                                             TeFile,\r
469                                             [File],\r
470                                             Type='te'\r
471                                             )\r
472                     File = TeFile\r
473 \r
474                 GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType])\r
475                 OutputFileList.append(OutputFile)\r
476         else:\r
477             SecNum = '%d' %Index\r
478             GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \\r
479                               Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum\r
480             OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)\r
481             GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch)\r
482 \r
483             #Get PE Section alignment when align is set to AUTO\r
484             if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):\r
485                 ImageObj = PeImageClass (GenSecInputFile)\r
486                 if ImageObj.SectionAlignment < 0x400:\r
487                     self.Alignment = str (ImageObj.SectionAlignment)\r
488                 else:\r
489                     self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'\r
490 \r
491             if not NoStrip:\r
492                 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')\r
493                 if not os.path.exists(FileBeforeStrip) or \\r
494                     (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)):\r
495                     shutil.copyfile(GenSecInputFile, FileBeforeStrip)\r
496                 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')\r
497                 GenFdsGlobalVariable.GenerateFirmwareImage(\r
498                                         StrippedFile,\r
499                                         [GenSecInputFile],\r
500                                         Strip=True\r
501                                         )\r
502                 GenSecInputFile = StrippedFile\r
503 \r
504             if SectionType == 'TE':\r
505                 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')\r
506                 GenFdsGlobalVariable.GenerateFirmwareImage(\r
507                                         TeFile,\r
508                                         [GenSecInputFile],\r
509                                         Type='te'\r
510                                         )\r
511                 GenSecInputFile = TeFile\r
512 \r
513             GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType])\r
514             OutputFileList.append(OutputFile)\r
515 \r
516         return OutputFileList\r
517 \r
518     ## __GenSimpleFileFfs__() method\r
519     #\r
520     #   Generate FFS\r
521     #\r
522     #   @param  self        The object pointer\r
523     #   @param  Rule        The rule object used to generate section\r
524     #   @param  InputFileList        The output file list from GenSection\r
525     #   @retval string      Generated FFS file name\r
526     #\r
527     def __GenSimpleFileFfs__(self, Rule, InputFileList):\r
528         FfsOutput = self.OutputPath                     + \\r
529                     os.sep                              + \\r
530                     self.__ExtendMacro__(Rule.NameGuid) + \\r
531                     '.ffs'\r
532 \r
533         GenFdsGlobalVariable.VerboseLogger(self.__ExtendMacro__(Rule.NameGuid))\r
534         InputSection = []\r
535         SectionAlignments = []\r
536         for InputFile in InputFileList:\r
537             InputSection.append(InputFile)\r
538             SectionAlignments.append(Rule.SectAlignment)\r
539 \r
540         if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):\r
541             PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)\r
542             if len(PcdValue) == 0:\r
543                 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \\r
544                             % (Rule.NameGuid))\r
545             if PcdValue.startswith('{'):\r
546                 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)\r
547             RegistryGuidStr = PcdValue\r
548             if len(RegistryGuidStr) == 0:\r
549                 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \\r
550                             % (Rule.NameGuid))\r
551             self.ModuleGuid = RegistryGuidStr\r
552 \r
553         GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,\r
554                                          Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],\r
555                                          self.ModuleGuid, Fixed=Rule.Fixed,\r
556                                          CheckSum=Rule.CheckSum, Align=Rule.Alignment,\r
557                                          SectionAlign=SectionAlignments\r
558                                         )\r
559         return FfsOutput\r
560 \r
561     ## __GenComplexFileSection__() method\r
562     #\r
563     #   Generate section by sections in Rule\r
564     #\r
565     #   @param  self         The object pointer\r
566     #   @param  Rule         The rule object used to generate section\r
567     #   @param  FvChildAddr  Array of the inside FvImage base address\r
568     #   @param  FvParentAddr Parent Fv base address\r
569     #   @retval string       File name of the generated section file\r
570     #\r
571     def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr):\r
572         if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):\r
573             if Rule.KeepReloc != None:\r
574                 self.KeepRelocFromRule = Rule.KeepReloc\r
575         SectFiles = []\r
576         SectAlignments = []\r
577         Index = 1\r
578         for Sect in Rule.SectionList:\r
579             SecIndex = '%d' %Index\r
580             SectList  = []\r
581             #\r
582             # Convert Fv Section Type for PI1.1 SMM driver.\r
583             #\r
584             if self.ModuleType == 'DXE_SMM_DRIVER' and self.PiSpecVersion >= 0x0001000A:\r
585                 if Sect.SectionType == 'DXE_DEPEX':\r
586                     Sect.SectionType = 'SMM_DEPEX'\r
587             #\r
588             # Framework SMM Driver has no SMM_DEPEX section type\r
589             #\r
590             if self.ModuleType == 'DXE_SMM_DRIVER' and self.PiSpecVersion < 0x0001000A:\r
591                 if Sect.SectionType == 'SMM_DEPEX':\r
592                     EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)\r
593             #\r
594             # process the inside FvImage from FvSection or GuidSection\r
595             #\r
596             if FvChildAddr != []:\r
597                 if isinstance(Sect, FvImageSection):\r
598                     Sect.FvAddr = FvChildAddr.pop(0)\r
599                 elif isinstance(Sect, GuidSection):\r
600                     Sect.FvAddr = FvChildAddr\r
601             if FvParentAddr != None and isinstance(Sect, GuidSection):\r
602                 Sect.FvParentAddr = FvParentAddr\r
603             \r
604             if Rule.KeyStringList != []:\r
605                 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self)\r
606             else :\r
607                 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self)\r
608             for SecName in  SectList :\r
609                 SectFiles.append(SecName)\r
610                 SectAlignments.append(Align)\r
611             Index = Index + 1\r
612         return SectFiles, SectAlignments\r
613 \r
614     ## __GenComplexFileFfs__() method\r
615     #\r
616     #   Generate FFS\r
617     #\r
618     #   @param  self        The object pointer\r
619     #   @param  Rule        The rule object used to generate section\r
620     #   @param  InputFileList        The output file list from GenSection\r
621     #   @retval string      Generated FFS file name\r
622     #\r
623     def __GenComplexFileFfs__(self, Rule, InputFile, Alignments):\r
624 \r
625         if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):\r
626             PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)\r
627             if len(PcdValue) == 0:\r
628                 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \\r
629                             % (Rule.NameGuid))\r
630             if PcdValue.startswith('{'):\r
631                 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)\r
632             RegistryGuidStr = PcdValue\r
633             if len(RegistryGuidStr) == 0:\r
634                 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \\r
635                             % (Rule.NameGuid))\r
636             self.ModuleGuid = RegistryGuidStr\r
637 \r
638         FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')\r
639         GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile,\r
640                                          Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],\r
641                                          self.ModuleGuid, Fixed=Rule.Fixed,\r
642                                          CheckSum=Rule.CheckSum, Align=Rule.Alignment,\r
643                                          SectionAlign=Alignments\r
644                                         )\r
645         return FfsOutput\r
646 \r
647     ## __GetGenFfsCmdParameter__() method\r
648     #\r
649     #   Create parameter string for GenFfs\r
650     #\r
651     #   @param  self        The object pointer\r
652     #   @param  Rule        The rule object used to generate section\r
653     #   @retval tuple       (FileType, Fixed, CheckSum, Alignment)\r
654     #\r
655     def __GetGenFfsCmdParameter__(self, Rule):\r
656         result = tuple()\r
657         result += ('-t', Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType])\r
658         if Rule.Fixed != False:\r
659             result += ('-x',)\r
660         if Rule.CheckSum != False:\r
661             result += ('-s',)\r
662 \r
663         if Rule.Alignment != None and Rule.Alignment != '':\r
664             result += ('-a', Rule.Alignment)\r
665 \r
666         return result\r