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