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