]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/FfsInfStatement.py
BaseTools: Fix the regression issue after enbaling s_* an d_* macros in FDF.
[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
1be2ed90 4# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
0acb3d28 5# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>\r
30fdf114 6#\r
40d841f6 7# This program and the accompanying materials\r
30fdf114
LG
8# are licensed and made available under the terms and conditions of the BSD License\r
9# which accompanies this distribution. The full text of the license may be found at\r
10# http://opensource.org/licenses/bsd-license.php\r
11#\r
12# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14#\r
15\r
16##\r
17# Import Modules\r
18#\r
19import Rule\r
1be2ed90 20import Common.LongFilePathOs as os\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
97fa0ee9 34from Common.Misc import ProcessDuplicatedInf\r
30fdf114
LG
35from Common import EdkLogger\r
36from Common.BuildToolError import *\r
52302d4d
LG
37from GuidSection import GuidSection\r
38from FvImageSection import FvImageSection\r
39from Common.Misc import PeImageClass\r
b36d134f 40from AutoGen.GenDepex import DependencyExpression\r
e8a47801 41from PatchPcdValue.PatchPcdValue import PatchBinaryFile\r
1be2ed90
HC
42from Common.LongFilePathSupport import CopyLongFilePath\r
43from Common.LongFilePathSupport import OpenLongFilePath as open\r
30fdf114
LG
44\r
45## generate FFS from INF\r
46#\r
47#\r
48class FfsInfStatement(FfsInfStatementClassObject):\r
2bc3256c
LG
49 ## The mapping dictionary from datum type to its maximum number.\r
50 _MAX_SIZE_TYPE = {"BOOLEAN":0x01, "UINT8":0xFF, "UINT16":0xFFFF, "UINT32":0xFFFFFFFF, "UINT64":0xFFFFFFFFFFFFFFFF}\r
30fdf114
LG
51 ## The constructor\r
52 #\r
53 # @param self The object pointer\r
54 #\r
55 def __init__(self):\r
56 FfsInfStatementClassObject.__init__(self)\r
57 self.TargetOverrideList = []\r
58 self.ShadowFromInfFile = None\r
59 self.KeepRelocFromRule = None\r
60 self.InDsc = True\r
61 self.OptRomDefs = {}\r
da92f276 62 self.PiSpecVersion = '0x00000000'\r
4234283c 63 self.InfModule = None\r
b36d134f 64 self.FinalTargetSuffixMap = {}\r
79b74a03
LG
65 self.CurrentLineNum = None\r
66 self.CurrentLineContent = None\r
67 self.FileName = None\r
68 self.InfFileName = None\r
97fa0ee9
YL
69 self.OverrideGuid = None\r
70 self.PatchedBinFile = ''\r
7ae7dcb9 71 self.MacroDict = {}\r
4234283c 72\r
b36d134f 73 ## GetFinalTargetSuffixMap() method\r
4234283c
LG
74 #\r
75 # Get final build target list\r
b36d134f 76 def GetFinalTargetSuffixMap(self):\r
4234283c
LG
77 if not self.InfModule or not self.CurrentArch:\r
78 return []\r
b36d134f
LG
79 if not self.FinalTargetSuffixMap:\r
80 FinalBuildTargetList = GenFdsGlobalVariable.GetModuleCodaTargetList(self.InfModule, self.CurrentArch)\r
81 for File in FinalBuildTargetList:\r
82 self.FinalTargetSuffixMap.setdefault(os.path.splitext(File)[1], []).append(File)\r
83\r
84 # Check if current INF module has DEPEX\r
85 if '.depex' not in self.FinalTargetSuffixMap and self.InfModule.ModuleType != "USER_DEFINED" \\r
86 and not self.InfModule.DxsFile and not self.InfModule.LibraryClass:\r
87 ModuleType = self.InfModule.ModuleType\r
88 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
89\r
90 if ModuleType != DataType.SUP_MODULE_USER_DEFINED:\r
91 for LibraryClass in PlatformDataBase.LibraryClasses.GetKeys():\r
92 if LibraryClass.startswith("NULL") and PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]:\r
93 self.InfModule.LibraryClasses[LibraryClass] = PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]\r
94\r
95 StrModule = str(self.InfModule)\r
96 PlatformModule = None\r
97 if StrModule in PlatformDataBase.Modules:\r
98 PlatformModule = PlatformDataBase.Modules[StrModule]\r
99 for LibraryClass in PlatformModule.LibraryClasses:\r
100 if LibraryClass.startswith("NULL"):\r
101 self.InfModule.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]\r
102\r
103 DependencyList = [self.InfModule]\r
104 LibraryInstance = {}\r
105 DepexList = []\r
106 while len(DependencyList) > 0:\r
107 Module = DependencyList.pop(0)\r
108 if not Module:\r
109 continue\r
110 for Dep in Module.Depex[self.CurrentArch, ModuleType]:\r
111 if DepexList != []:\r
112 DepexList.append('AND')\r
113 DepexList.append('(')\r
114 DepexList.extend(Dep)\r
115 if DepexList[-1] == 'END': # no need of a END at this time\r
116 DepexList.pop()\r
117 DepexList.append(')')\r
118 if 'BEFORE' in DepexList or 'AFTER' in DepexList:\r
119 break\r
120 for LibName in Module.LibraryClasses:\r
121 if LibName in LibraryInstance:\r
122 continue\r
123 if PlatformModule and LibName in PlatformModule.LibraryClasses:\r
124 LibraryPath = PlatformModule.LibraryClasses[LibName]\r
125 else:\r
126 LibraryPath = PlatformDataBase.LibraryClasses[LibName, ModuleType]\r
127 if not LibraryPath:\r
128 LibraryPath = Module.LibraryClasses[LibName]\r
129 if not LibraryPath:\r
130 continue\r
131 LibraryModule = GenFdsGlobalVariable.WorkSpace.BuildObject[LibraryPath, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
132 LibraryInstance[LibName] = LibraryModule\r
133 DependencyList.append(LibraryModule)\r
134 if DepexList:\r
135 Dpx = DependencyExpression(DepexList, ModuleType, True)\r
136 if len(Dpx.PostfixNotation) != 0:\r
137 # It means this module has DEPEX\r
138 self.FinalTargetSuffixMap['.depex'] = [os.path.join(self.EfiOutputPath, self.BaseName) + '.depex']\r
139 return self.FinalTargetSuffixMap\r
4234283c 140\r
30fdf114
LG
141 ## __InfParse() method\r
142 #\r
143 # Parse inf file to get module information\r
144 #\r
145 # @param self The object pointer\r
146 # @param Dict dictionary contains macro and value pair\r
147 #\r
148 def __InfParse__(self, Dict = {}):\r
149\r
150 GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName)\r
151\r
152 self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '')\r
97fa0ee9
YL
153 if len(self.InfFileName) > 1 and self.InfFileName[0] == '\\' and self.InfFileName[1] == '\\':\r
154 pass\r
155 elif self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' :\r
30fdf114
LG
156 self.InfFileName = self.InfFileName[1:]\r
157\r
158 if self.InfFileName.find('$') == -1:\r
159 InfPath = NormPath(self.InfFileName)\r
160 if not os.path.exists(InfPath):\r
161 InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath)\r
162 if not os.path.exists(InfPath):\r
163 EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName))\r
164\r
165 self.CurrentArch = self.GetCurrentArch()\r
166 #\r
167 # Get the InfClass object\r
168 #\r
169\r
170 PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)\r
e56468c0 171 ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")\r
30fdf114
LG
172 if ErrorCode != 0:\r
173 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
97fa0ee9
YL
174\r
175 if self.OverrideGuid:\r
176 PathClassObj = ProcessDuplicatedInf(PathClassObj, self.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir)\r
30fdf114
LG
177 if self.CurrentArch != None:\r
178\r
0d2711a6 179 Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
30fdf114
LG
180 #\r
181 # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath\r
182 #\r
183 self.BaseName = Inf.BaseName\r
184 self.ModuleGuid = Inf.Guid\r
185 self.ModuleType = Inf.ModuleType\r
52302d4d 186 if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:\r
b303ea72 187 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']\r
30fdf114
LG
188 if Inf.AutoGenVersion < 0x00010005:\r
189 self.ModuleType = Inf.ComponentType\r
190 self.VersionString = Inf.Version\r
191 self.BinFileList = Inf.Binaries\r
192 self.SourceFileList = Inf.Sources\r
193 if self.KeepReloc == None and Inf.Shadow:\r
194 self.ShadowFromInfFile = Inf.Shadow\r
195\r
196 else:\r
0d2711a6 197 Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
30fdf114
LG
198 self.BaseName = Inf.BaseName\r
199 self.ModuleGuid = Inf.Guid\r
200 self.ModuleType = Inf.ModuleType\r
52302d4d 201 if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:\r
b303ea72 202 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']\r
30fdf114
LG
203 self.VersionString = Inf.Version\r
204 self.BinFileList = Inf.Binaries\r
205 self.SourceFileList = Inf.Sources\r
206 if self.BinFileList == []:\r
207 EdkLogger.error("GenFds", GENFDS_ERROR,\r
208 "INF %s specified in FDF could not be found in build ARCH %s!" \\r
209 % (self.InfFileName, GenFdsGlobalVariable.ArchList))\r
210\r
97fa0ee9
YL
211 if self.OverrideGuid:\r
212 self.ModuleGuid = self.OverrideGuid\r
213\r
30fdf114
LG
214 if len(self.SourceFileList) != 0 and not self.InDsc:\r
215 EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName))\r
216\r
da92f276 217 if self.ModuleType == 'SMM_CORE' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
b303ea72
LG
218 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
219\r
30fdf114
LG
220 if Inf._Defs != None and len(Inf._Defs) > 0:\r
221 self.OptRomDefs.update(Inf._Defs)\r
2bc3256c 222\r
e8a47801
LG
223 self.PatchPcds = []\r
224 InfPcds = Inf.Pcds\r
225 Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
226 FdfPcdDict = GenFdsGlobalVariable.FdfParser.Profile.PcdDict\r
2bc3256c
LG
227\r
228 # Workaround here: both build and GenFds tool convert the workspace path to lower case\r
229 # But INF file path in FDF and DSC file may have real case characters.\r
230 # Try to convert the path to lower case to see if PCDs value are override by DSC.\r
e8a47801
LG
231 DscModules = {}\r
232 for DscModule in Platform.Modules:\r
233 DscModules[str(DscModule).lower()] = Platform.Modules[DscModule]\r
234 for PcdKey in InfPcds:\r
235 Pcd = InfPcds[PcdKey]\r
236 if not hasattr(Pcd, 'Offset'):\r
237 continue\r
238 if Pcd.Type != 'PatchableInModule':\r
239 continue\r
2bc3256c 240 # Override Patchable PCD value by the value from DSC\r
e8a47801
LG
241 PatchPcd = None\r
242 InfLowerPath = str(PathClassObj).lower()\r
243 if InfLowerPath in DscModules and PcdKey in DscModules[InfLowerPath].Pcds:\r
244 PatchPcd = DscModules[InfLowerPath].Pcds[PcdKey]\r
245 elif PcdKey in Platform.Pcds:\r
246 PatchPcd = Platform.Pcds[PcdKey]\r
247 DscOverride = False\r
248 if PatchPcd and Pcd.Type == PatchPcd.Type:\r
249 DefaultValue = PatchPcd.DefaultValue\r
250 DscOverride = True\r
2bc3256c
LG
251\r
252 # Override Patchable PCD value by the value from FDF\r
e8a47801
LG
253 FdfOverride = False\r
254 if PcdKey in FdfPcdDict:\r
255 DefaultValue = FdfPcdDict[PcdKey]\r
256 FdfOverride = True\r
2bc3256c 257\r
e8a47801
LG
258 if not DscOverride and not FdfOverride:\r
259 continue\r
2bc3256c 260 # Check value, if value are equal, no need to patch\r
e8a47801
LG
261 if Pcd.DatumType == "VOID*":\r
262 if Pcd.DefaultValue == DefaultValue or DefaultValue in [None, '']:\r
263 continue\r
2bc3256c 264 # Get the string size from FDF or DSC\r
e8a47801 265 if DefaultValue[0] == 'L':\r
2bc3256c 266 # Remove L"", but the '\0' must be appended\r
e8a47801
LG
267 MaxDatumSize = str((len(DefaultValue) - 2) * 2)\r
268 elif DefaultValue[0] == '{':\r
269 MaxDatumSize = str(len(DefaultValue.split(',')))\r
270 else:\r
271 MaxDatumSize = str(len(DefaultValue) - 1)\r
272 if DscOverride:\r
273 Pcd.MaxDatumSize = PatchPcd.MaxDatumSize\r
2bc3256c 274 # If no defined the maximum size in DSC, try to get current size from INF\r
e8a47801
LG
275 if Pcd.MaxDatumSize in ['', None]:\r
276 Pcd.MaxDatumSize = str(len(Pcd.DefaultValue.split(',')))\r
277 else:\r
278 Base1 = Base2 = 10\r
279 if Pcd.DefaultValue.upper().startswith('0X'):\r
280 Base1 = 16\r
281 if DefaultValue.upper().startswith('0X'):\r
282 Base2 = 16\r
283 try:\r
284 PcdValueInImg = int(Pcd.DefaultValue, Base1)\r
285 PcdValueInDscOrFdf = int(DefaultValue, Base2)\r
286 if PcdValueInImg == PcdValueInDscOrFdf:\r
287 continue\r
288 except:\r
289 continue\r
2bc3256c 290 # Check the Pcd size and data type\r
e8a47801
LG
291 if Pcd.DatumType == "VOID*":\r
292 if int(MaxDatumSize) > int(Pcd.MaxDatumSize):\r
293 EdkLogger.error("GenFds", GENFDS_ERROR, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \\r
294 % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, int(MaxDatumSize) - int(Pcd.MaxDatumSize)))\r
295 else:\r
296 if PcdValueInDscOrFdf > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType] \\r
297 or PcdValueInImg > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType]:\r
298 EdkLogger.error("GenFds", GENFDS_ERROR, "The size of %s type PCD '%s.%s' doesn't match its data type." \\r
299 % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
97fa0ee9
YL
300 self.PatchPcds.append((Pcd, DefaultValue))\r
301\r
4234283c 302 self.InfModule = Inf\r
e8a47801
LG
303 self.PcdIsDriver = Inf.PcdIsDriver\r
304 self.IsBinaryModule = Inf.IsBinaryModule\r
305 GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName)\r
306 GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid)\r
307 GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType)\r
308 GenFdsGlobalVariable.VerboseLogger("VersionString : %s" % self.VersionString)\r
309 GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" % self.InfFileName)\r
30fdf114
LG
310\r
311 #\r
312 # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\\r
313 #\r
314\r
315 self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \\r
316 self.ModuleGuid + self.BaseName)\r
317 if not os.path.exists(self.OutputPath) :\r
318 os.makedirs(self.OutputPath)\r
319\r
320 self.EfiOutputPath = self.__GetEFIOutPutPath__()\r
321 GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)\r
322\r
97fa0ee9 323 ## PatchEfiFile\r
e8a47801
LG
324 #\r
325 # Patch EFI file with patch PCD\r
326 #\r
327 # @param EfiFile: EFI file needs to be patched.\r
328 # @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name\r
329 # If passed in file does not end with efi, return as is\r
330 #\r
97fa0ee9 331 def PatchEfiFile(self, EfiFile, FileType):\r
e8a47801
LG
332 if not self.PatchPcds:\r
333 return EfiFile\r
97fa0ee9
YL
334 if FileType != 'PE32' and self.ModuleType != "USER_DEFINED":\r
335 return EfiFile\r
336 if self.PatchedBinFile:\r
337 EdkLogger.error("GenFds", GENFDS_ERROR,\r
338 'Only one binary file can be patched:\n'\r
339 ' a binary file has been patched: %s\n'\r
340 ' current file: %s' % (self.PatchedBinFile, EfiFile),\r
341 File=self.InfFileName)\r
e8a47801
LG
342 Basename = os.path.basename(EfiFile)\r
343 Output = os.path.join(self.OutputPath, Basename)\r
1be2ed90 344 CopyLongFilePath(EfiFile, Output)\r
97fa0ee9
YL
345 for Pcd, Value in self.PatchPcds:\r
346 RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Value, Pcd.MaxDatumSize)\r
e8a47801
LG
347 if RetVal:\r
348 EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName)\r
97fa0ee9 349 self.PatchedBinFile = os.path.normpath(EfiFile)\r
e8a47801 350 return Output\r
30fdf114
LG
351 ## GenFfs() method\r
352 #\r
353 # Generate FFS\r
354 #\r
52302d4d
LG
355 # @param self The object pointer\r
356 # @param Dict dictionary contains macro and value pair\r
357 # @param FvChildAddr Array of the inside FvImage base address\r
358 # @param FvParentAddr Parent Fv base address\r
359 # @retval string Generated FFS file name\r
30fdf114 360 #\r
52302d4d 361 def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None):\r
30fdf114
LG
362 #\r
363 # Parse Inf file get Module related information\r
364 #\r
365\r
366 self.__InfParse__(Dict)\r
0acb3d28
AC
367 SrcFile = os.path.join( GenFdsGlobalVariable.WorkSpaceDir , self.InfFileName);\r
368 DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')\r
6780eef1 369 \r
0acb3d28
AC
370 SrcFileDir = "."\r
371 SrcPath = os.path.dirname(SrcFile)\r
372 SrcFileName = os.path.basename(SrcFile)\r
373 SrcFileBase, SrcFileExt = os.path.splitext(SrcFileName) \r
374 DestPath = os.path.dirname(DestFile)\r
375 DestFileName = os.path.basename(DestFile)\r
376 DestFileBase, DestFileExt = os.path.splitext(DestFileName) \r
377 self.MacroDict = {\r
378 # source file\r
379 "${src}" : SrcFile,\r
380 "${s_path}" : SrcPath,\r
381 "${s_dir}" : SrcFileDir,\r
382 "${s_name}" : SrcFileName,\r
383 "${s_base}" : SrcFileBase,\r
384 "${s_ext}" : SrcFileExt,\r
385 # destination file\r
386 "${dst}" : DestFile,\r
387 "${d_path}" : DestPath,\r
388 "${d_name}" : DestFileName,\r
389 "${d_base}" : DestFileBase,\r
390 "${d_ext}" : DestFileExt\r
391 }\r
6780eef1
LG
392 #\r
393 # Allow binary type module not specify override rule in FDF file.\r
394 # \r
97fa0ee9 395 if len(self.BinFileList) > 0:\r
6780eef1
LG
396 if self.Rule == None or self.Rule == "":\r
397 self.Rule = "BINARY"\r
398 \r
30fdf114
LG
399 #\r
400 # Get the rule of how to generate Ffs file\r
401 #\r
402 Rule = self.__GetRule__()\r
403 GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName)\r
b303ea72
LG
404 #\r
405 # Convert Fv File Type for PI1.1 SMM driver.\r
406 #\r
da92f276 407 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:\r
b303ea72
LG
408 if Rule.FvFileType == 'DRIVER':\r
409 Rule.FvFileType = 'SMM'\r
410 #\r
411 # Framework SMM Driver has no SMM FV file type\r
412 #\r
da92f276 413 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
b303ea72
LG
414 if Rule.FvFileType == 'SMM' or Rule.FvFileType == 'SMM_CORE':\r
415 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
416 #\r
417 # For the rule only has simpleFile\r
418 #\r
419 if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) :\r
420 SectionOutputList = self.__GenSimpleFileSection__(Rule)\r
421 FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList)\r
422 return FfsOutput\r
423 #\r
424 # For Rule has ComplexFile\r
425 #\r
426 elif isinstance(Rule, RuleComplexFile.RuleComplexFile):\r
52302d4d 427 InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr)\r
30fdf114
LG
428 FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments)\r
429\r
430 return FfsOutput\r
431\r
432 ## __ExtendMacro__() method\r
433 #\r
434 # Replace macro with its value\r
435 #\r
436 # @param self The object pointer\r
437 # @param String The string to be replaced\r
438 # @retval string Macro replaced string\r
439 #\r
440 def __ExtendMacro__ (self, String):\r
441 MacroDict = {\r
442 '$(INF_OUTPUT)' : self.EfiOutputPath,\r
443 '$(MODULE_NAME)' : self.BaseName,\r
444 '$(BUILD_NUMBER)': self.BuildNum,\r
445 '$(INF_VERSION)' : self.VersionString,\r
446 '$(NAMED_GUID)' : self.ModuleGuid\r
447 }\r
448 String = GenFdsGlobalVariable.MacroExtend(String, MacroDict)\r
0acb3d28 449 String = GenFdsGlobalVariable.MacroExtend(String, self.MacroDict) \r
30fdf114
LG
450 return String\r
451\r
452 ## __GetRule__() method\r
453 #\r
454 # Get correct rule for generating FFS for this INF\r
455 #\r
456 # @param self The object pointer\r
457 # @retval Rule Rule object\r
458 #\r
459 def __GetRule__ (self) :\r
460 CurrentArchList = []\r
461 if self.CurrentArch == None:\r
462 CurrentArchList = ['common']\r
463 else:\r
464 CurrentArchList.append(self.CurrentArch)\r
465\r
466 for CurrentArch in CurrentArchList:\r
467 RuleName = 'RULE' + \\r
468 '.' + \\r
469 CurrentArch.upper() + \\r
470 '.' + \\r
471 self.ModuleType.upper()\r
472 if self.Rule != None:\r
473 RuleName = RuleName + \\r
474 '.' + \\r
475 self.Rule.upper()\r
476\r
477 Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)\r
478 if Rule != None:\r
479 GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)\r
480 return Rule\r
481\r
482 RuleName = 'RULE' + \\r
483 '.' + \\r
484 'COMMON' + \\r
485 '.' + \\r
486 self.ModuleType.upper()\r
487\r
488 if self.Rule != None:\r
489 RuleName = RuleName + \\r
490 '.' + \\r
491 self.Rule.upper()\r
492\r
493 GenFdsGlobalVariable.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName, self.InfFileName))\r
494\r
495 Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)\r
496 if Rule != None:\r
497 GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)\r
498 return Rule\r
499\r
500 if Rule == None :\r
501 EdkLogger.error("GenFds", GENFDS_ERROR, 'Don\'t Find common rule %s for INF %s' \\r
502 % (RuleName, self.InfFileName))\r
503\r
504 ## __GetPlatformArchList__() method\r
505 #\r
506 # Get Arch list this INF built under\r
507 #\r
508 # @param self The object pointer\r
509 # @retval list Arch list\r
510 #\r
511 def __GetPlatformArchList__(self):\r
512\r
513 InfFileKey = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))\r
514 DscArchList = []\r
0d2711a6 515 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
30fdf114
LG
516 if PlatformDataBase != None:\r
517 if InfFileKey in PlatformDataBase.Modules:\r
518 DscArchList.append ('IA32')\r
519\r
0d2711a6 520 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'X64', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
30fdf114
LG
521 if PlatformDataBase != None:\r
522 if InfFileKey in PlatformDataBase.Modules:\r
523 DscArchList.append ('X64')\r
524\r
0d2711a6 525 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IPF', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
30fdf114
LG
526 if PlatformDataBase != None:\r
527 if InfFileKey in (PlatformDataBase.Modules):\r
528 DscArchList.append ('IPF')\r
529\r
0d2711a6 530 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'ARM', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
30fdf114
LG
531 if PlatformDataBase != None:\r
532 if InfFileKey in (PlatformDataBase.Modules):\r
533 DscArchList.append ('ARM')\r
534\r
0d2711a6 535 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'EBC', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
30fdf114
LG
536 if PlatformDataBase != None:\r
537 if InfFileKey in (PlatformDataBase.Modules):\r
538 DscArchList.append ('EBC')\r
539\r
4afd3d04
LG
540 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'AARCH64', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
541 if PlatformDataBase != None:\r
542 if InfFileKey in (PlatformDataBase.Modules):\r
543 DscArchList.append ('AARCH64')\r
544\r
30fdf114
LG
545 return DscArchList\r
546\r
547 ## GetCurrentArch() method\r
548 #\r
549 # Get Arch list of the module from this INF is to be placed into flash\r
550 #\r
551 # @param self The object pointer\r
552 # @retval list Arch list\r
553 #\r
554 def GetCurrentArch(self) :\r
555\r
556 TargetArchList = GenFdsGlobalVariable.ArchList\r
557\r
558 PlatformArchList = self.__GetPlatformArchList__()\r
559\r
560 CurArchList = TargetArchList\r
561 if PlatformArchList != []:\r
562 CurArchList = list(set (TargetArchList) & set (PlatformArchList))\r
563 GenFdsGlobalVariable.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList))\r
564\r
565 ArchList = []\r
566 if self.KeyStringList != []:\r
567 for Key in self.KeyStringList:\r
568 Key = GenFdsGlobalVariable.MacroExtend(Key)\r
569 Target, Tag, Arch = Key.split('_')\r
570 if Arch in CurArchList:\r
571 ArchList.append(Arch)\r
572 if Target not in self.TargetOverrideList:\r
573 self.TargetOverrideList.append(Target)\r
574 else:\r
575 ArchList = CurArchList\r
576\r
577 UseArchList = TargetArchList\r
578 if self.UseArch != None:\r
579 UseArchList = []\r
580 UseArchList.append(self.UseArch)\r
581 ArchList = list(set (UseArchList) & set (ArchList))\r
582\r
583 self.InfFileName = NormPath(self.InfFileName)\r
584 if len(PlatformArchList) == 0:\r
585 self.InDsc = False\r
586 PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)\r
e56468c0 587 ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")\r
30fdf114
LG
588 if ErrorCode != 0:\r
589 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
590 if len(ArchList) == 1:\r
591 Arch = ArchList[0]\r
592 return Arch\r
593 elif len(ArchList) > 1:\r
594 if len(PlatformArchList) == 0:\r
595 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
596 else:\r
597 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
598 else:\r
599 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
600 % (self.InfFileName, str(PlatformArchList), GenFdsGlobalVariable.ActivePlatform, str(set (UseArchList) & set (TargetArchList))))\r
601\r
602 ## __GetEFIOutPutPath__() method\r
603 #\r
604 # Get the output path for generated files\r
605 #\r
606 # @param self The object pointer\r
607 # @retval string Path that output files from this INF go to\r
608 #\r
609 def __GetEFIOutPutPath__(self):\r
610 Arch = ''\r
611 OutputPath = ''\r
612 (ModulePath, FileName) = os.path.split(self.InfFileName)\r
79b74a03 613 Index = FileName.rfind('.')\r
30fdf114 614 FileName = FileName[0:Index]\r
97fa0ee9
YL
615 if self.OverrideGuid:\r
616 FileName = self.OverrideGuid\r
30fdf114
LG
617 Arch = "NoneArch"\r
618 if self.CurrentArch != None:\r
619 Arch = self.CurrentArch\r
620\r
621 OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],\r
622 Arch ,\r
623 ModulePath,\r
624 FileName,\r
625 'OUTPUT'\r
626 )\r
627 OutputPath = os.path.realpath(OutputPath)\r
628 return OutputPath\r
629\r
630 ## __GenSimpleFileSection__() method\r
631 #\r
632 # Generate section by specified file name or a list of files with file extension\r
633 #\r
634 # @param self The object pointer\r
635 # @param Rule The rule object used to generate section\r
636 # @retval string File name of the generated section file\r
637 #\r
638 def __GenSimpleFileSection__(self, Rule):\r
639 #\r
640 # Prepare the parameter of GenSection\r
641 #\r
642 FileList = []\r
643 OutputFileList = []\r
52302d4d 644 GenSecInputFile = None\r
30fdf114
LG
645 if Rule.FileName != None:\r
646 GenSecInputFile = self.__ExtendMacro__(Rule.FileName)\r
da92f276
LG
647 if os.path.isabs(GenSecInputFile):\r
648 GenSecInputFile = os.path.normpath(GenSecInputFile)\r
649 else:\r
52302d4d 650 GenSecInputFile = os.path.normpath(os.path.join(self.EfiOutputPath, GenSecInputFile))\r
30fdf114
LG
651 else:\r
652 FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension)\r
653\r
654 Index = 1\r
b303ea72
LG
655 SectionType = Rule.SectionType\r
656 #\r
657 # Convert Fv Section Type for PI1.1 SMM driver.\r
658 #\r
da92f276 659 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:\r
b303ea72
LG
660 if SectionType == 'DXE_DEPEX':\r
661 SectionType = 'SMM_DEPEX'\r
662 #\r
663 # Framework SMM Driver has no SMM_DEPEX section type\r
664 #\r
da92f276 665 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
b303ea72
LG
666 if SectionType == 'SMM_DEPEX':\r
667 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)\r
30fdf114
LG
668 NoStrip = True\r
669 if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):\r
670 if self.KeepReloc != None:\r
671 NoStrip = self.KeepReloc\r
672 elif Rule.KeepReloc != None:\r
673 NoStrip = Rule.KeepReloc\r
674 elif self.ShadowFromInfFile != None:\r
675 NoStrip = self.ShadowFromInfFile\r
676\r
677 if FileList != [] :\r
678 for File in FileList:\r
679\r
680 SecNum = '%d' %Index\r
681 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \\r
682 Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum\r
683 Index = Index + 1\r
684 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)\r
52302d4d
LG
685 File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)\r
686\r
687 #Get PE Section alignment when align is set to AUTO\r
688 if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):\r
689 ImageObj = PeImageClass (File)\r
690 if ImageObj.SectionAlignment < 0x400:\r
691 self.Alignment = str (ImageObj.SectionAlignment)\r
692 else:\r
693 self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'\r
30fdf114
LG
694\r
695 if not NoStrip:\r
696 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')\r
697 if not os.path.exists(FileBeforeStrip) or \\r
1be2ed90
HC
698 (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):\r
699 CopyLongFilePath(File, FileBeforeStrip)\r
30fdf114
LG
700 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')\r
701 GenFdsGlobalVariable.GenerateFirmwareImage(\r
702 StrippedFile,\r
52302d4d 703 [File],\r
30fdf114
LG
704 Strip=True\r
705 )\r
706 File = StrippedFile\r
707\r
708 if SectionType == 'TE':\r
709 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')\r
710 GenFdsGlobalVariable.GenerateFirmwareImage(\r
711 TeFile,\r
52302d4d 712 [File],\r
30fdf114
LG
713 Type='te'\r
714 )\r
715 File = TeFile\r
716\r
717 GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType])\r
718 OutputFileList.append(OutputFile)\r
719 else:\r
720 SecNum = '%d' %Index\r
721 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \\r
722 Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum\r
723 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)\r
52302d4d
LG
724 GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch)\r
725\r
726 #Get PE Section alignment when align is set to AUTO\r
727 if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):\r
728 ImageObj = PeImageClass (GenSecInputFile)\r
729 if ImageObj.SectionAlignment < 0x400:\r
730 self.Alignment = str (ImageObj.SectionAlignment)\r
731 else:\r
732 self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'\r
30fdf114
LG
733\r
734 if not NoStrip:\r
735 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')\r
736 if not os.path.exists(FileBeforeStrip) or \\r
1be2ed90
HC
737 (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)):\r
738 CopyLongFilePath(GenSecInputFile, FileBeforeStrip)\r
739\r
30fdf114
LG
740 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')\r
741 GenFdsGlobalVariable.GenerateFirmwareImage(\r
742 StrippedFile,\r
52302d4d 743 [GenSecInputFile],\r
30fdf114
LG
744 Strip=True\r
745 )\r
746 GenSecInputFile = StrippedFile\r
747\r
748 if SectionType == 'TE':\r
749 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')\r
750 GenFdsGlobalVariable.GenerateFirmwareImage(\r
751 TeFile,\r
52302d4d 752 [GenSecInputFile],\r
30fdf114
LG
753 Type='te'\r
754 )\r
755 GenSecInputFile = TeFile\r
756\r
757 GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType])\r
758 OutputFileList.append(OutputFile)\r
759\r
760 return OutputFileList\r
761\r
762 ## __GenSimpleFileFfs__() method\r
763 #\r
764 # Generate FFS\r
765 #\r
766 # @param self The object pointer\r
767 # @param Rule The rule object used to generate section\r
768 # @param InputFileList The output file list from GenSection\r
769 # @retval string Generated FFS file name\r
770 #\r
771 def __GenSimpleFileFfs__(self, Rule, InputFileList):\r
772 FfsOutput = self.OutputPath + \\r
773 os.sep + \\r
774 self.__ExtendMacro__(Rule.NameGuid) + \\r
775 '.ffs'\r
776\r
777 GenFdsGlobalVariable.VerboseLogger(self.__ExtendMacro__(Rule.NameGuid))\r
778 InputSection = []\r
779 SectionAlignments = []\r
780 for InputFile in InputFileList:\r
781 InputSection.append(InputFile)\r
52302d4d 782 SectionAlignments.append(Rule.SectAlignment)\r
30fdf114
LG
783\r
784 if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):\r
785 PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)\r
786 if len(PcdValue) == 0:\r
787 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \\r
788 % (Rule.NameGuid))\r
789 if PcdValue.startswith('{'):\r
790 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)\r
791 RegistryGuidStr = PcdValue\r
792 if len(RegistryGuidStr) == 0:\r
793 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \\r
794 % (Rule.NameGuid))\r
795 self.ModuleGuid = RegistryGuidStr\r
796\r
797 GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,\r
798 Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],\r
799 self.ModuleGuid, Fixed=Rule.Fixed,\r
800 CheckSum=Rule.CheckSum, Align=Rule.Alignment,\r
801 SectionAlign=SectionAlignments\r
802 )\r
803 return FfsOutput\r
804\r
805 ## __GenComplexFileSection__() method\r
806 #\r
807 # Generate section by sections in Rule\r
808 #\r
52302d4d
LG
809 # @param self The object pointer\r
810 # @param Rule The rule object used to generate section\r
811 # @param FvChildAddr Array of the inside FvImage base address\r
812 # @param FvParentAddr Parent Fv base address\r
813 # @retval string File name of the generated section file\r
30fdf114 814 #\r
52302d4d 815 def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr):\r
30fdf114
LG
816 if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):\r
817 if Rule.KeepReloc != None:\r
818 self.KeepRelocFromRule = Rule.KeepReloc\r
819 SectFiles = []\r
820 SectAlignments = []\r
821 Index = 1\r
da92f276 822 HasGneratedFlag = False\r
e8a47801
LG
823 if self.PcdIsDriver == 'PEI_PCD_DRIVER':\r
824 if self.IsBinaryModule:\r
825 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "PEIPcdDataBase.raw")\r
826 else:\r
827 PcdExDbFileName = os.path.join(self.EfiOutputPath, "PEIPcdDataBase.raw")\r
828 PcdExDbSecName = os.path.join(self.OutputPath, "PEIPcdDataBaseSec.raw")\r
829 GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,\r
830 [PcdExDbFileName],\r
831 "EFI_SECTION_RAW",\r
832 )\r
833 SectFiles.append(PcdExDbSecName)\r
834 SectAlignments.append(None)\r
835 elif self.PcdIsDriver == 'DXE_PCD_DRIVER':\r
836 if self.IsBinaryModule:\r
837 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "DXEPcdDataBase.raw")\r
838 else:\r
839 PcdExDbFileName = os.path.join(self.EfiOutputPath, "DXEPcdDataBase.raw")\r
840 PcdExDbSecName = os.path.join(self.OutputPath, "DXEPcdDataBaseSec.raw")\r
841 GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,\r
842 [PcdExDbFileName],\r
843 "EFI_SECTION_RAW",\r
844 )\r
845 SectFiles.append(PcdExDbSecName)\r
846 SectAlignments.append(None)\r
30fdf114
LG
847 for Sect in Rule.SectionList:\r
848 SecIndex = '%d' %Index\r
849 SectList = []\r
b303ea72
LG
850 #\r
851 # Convert Fv Section Type for PI1.1 SMM driver.\r
852 #\r
da92f276 853 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:\r
b303ea72
LG
854 if Sect.SectionType == 'DXE_DEPEX':\r
855 Sect.SectionType = 'SMM_DEPEX'\r
856 #\r
857 # Framework SMM Driver has no SMM_DEPEX section type\r
858 #\r
da92f276 859 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
b303ea72
LG
860 if Sect.SectionType == 'SMM_DEPEX':\r
861 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)\r
52302d4d
LG
862 #\r
863 # process the inside FvImage from FvSection or GuidSection\r
864 #\r
865 if FvChildAddr != []:\r
866 if isinstance(Sect, FvImageSection):\r
867 Sect.FvAddr = FvChildAddr.pop(0)\r
868 elif isinstance(Sect, GuidSection):\r
869 Sect.FvAddr = FvChildAddr\r
870 if FvParentAddr != None and isinstance(Sect, GuidSection):\r
871 Sect.FvParentAddr = FvParentAddr\r
872 \r
30fdf114
LG
873 if Rule.KeyStringList != []:\r
874 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self)\r
875 else :\r
876 SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self)\r
da92f276
LG
877 \r
878 if not HasGneratedFlag:\r
879 UniVfrOffsetFileSection = "" \r
880 ModuleFileName = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)\r
881 InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch]\r
882 #\r
883 # Search the source list in InfData to find if there are .vfr file exist.\r
884 #\r
885 VfrUniBaseName = {}\r
886 VfrUniOffsetList = []\r
887 for SourceFile in InfData.Sources:\r
888 if SourceFile.Type.upper() == ".VFR" :\r
889 #\r
890 # search the .map file to find the offset of vfr binary in the PE32+/TE file. \r
891 #\r
892 VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin")\r
893 if SourceFile.Type.upper() == ".UNI" :\r
894 #\r
895 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file. \r
896 #\r
897 VfrUniBaseName["UniOffsetName"] = (self.BaseName + "Strings")\r
898 \r
899 \r
900 if len(VfrUniBaseName) > 0:\r
901 VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName)\r
902 #\r
903 # Generate the Raw data of raw section\r
904 #\r
905 os.path.join( self.OutputPath, self.BaseName + '.offset')\r
906 UniVfrOffsetFileName = os.path.join( self.OutputPath, self.BaseName + '.offset')\r
907 UniVfrOffsetFileSection = os.path.join( self.OutputPath, self.BaseName + 'Offset' + '.raw')\r
908 \r
909 self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName)\r
910 \r
911 UniVfrOffsetFileNameList = []\r
912 UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)\r
913 """Call GenSection"""\r
914 GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,\r
915 UniVfrOffsetFileNameList,\r
916 "EFI_SECTION_RAW"\r
917 )\r
918 os.remove(UniVfrOffsetFileName) \r
919 SectList.append(UniVfrOffsetFileSection)\r
920 HasGneratedFlag = True\r
921 \r
30fdf114
LG
922 for SecName in SectList :\r
923 SectFiles.append(SecName)\r
924 SectAlignments.append(Align)\r
925 Index = Index + 1\r
926 return SectFiles, SectAlignments\r
927\r
928 ## __GenComplexFileFfs__() method\r
929 #\r
930 # Generate FFS\r
931 #\r
932 # @param self The object pointer\r
933 # @param Rule The rule object used to generate section\r
934 # @param InputFileList The output file list from GenSection\r
935 # @retval string Generated FFS file name\r
936 #\r
937 def __GenComplexFileFfs__(self, Rule, InputFile, Alignments):\r
938\r
939 if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):\r
940 PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)\r
941 if len(PcdValue) == 0:\r
942 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \\r
943 % (Rule.NameGuid))\r
944 if PcdValue.startswith('{'):\r
945 PcdValue = GuidStructureByteArrayToGuidString(PcdValue)\r
946 RegistryGuidStr = PcdValue\r
947 if len(RegistryGuidStr) == 0:\r
948 EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \\r
949 % (Rule.NameGuid))\r
950 self.ModuleGuid = RegistryGuidStr\r
951\r
952 FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')\r
953 GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile,\r
954 Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],\r
955 self.ModuleGuid, Fixed=Rule.Fixed,\r
956 CheckSum=Rule.CheckSum, Align=Rule.Alignment,\r
957 SectionAlign=Alignments\r
958 )\r
959 return FfsOutput\r
960\r
961 ## __GetGenFfsCmdParameter__() method\r
962 #\r
963 # Create parameter string for GenFfs\r
964 #\r
965 # @param self The object pointer\r
966 # @param Rule The rule object used to generate section\r
967 # @retval tuple (FileType, Fixed, CheckSum, Alignment)\r
968 #\r
969 def __GetGenFfsCmdParameter__(self, Rule):\r
970 result = tuple()\r
971 result += ('-t', Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType])\r
972 if Rule.Fixed != False:\r
973 result += ('-x',)\r
974 if Rule.CheckSum != False:\r
975 result += ('-s',)\r
976\r
977 if Rule.Alignment != None and Rule.Alignment != '':\r
978 result += ('-a', Rule.Alignment)\r
979\r
980 return result\r
da92f276
LG
981 \r
982 ## __GetBuildOutputMapFileVfrUniInfo() method\r
983 #\r
984 # Find the offset of UNI/INF object offset in the EFI image file.\r
985 #\r
986 # @param self The object pointer\r
987 # @param VfrUniBaseName A name list contain the UNI/INF object name.\r
988 # @retval RetValue A list contain offset of UNI/INF object.\r
989 # \r
990 def __GetBuildOutputMapFileVfrUniInfo(self, VfrUniBaseName):\r
991 \r
992 RetValue = []\r
993 \r
994 MapFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".map")\r
995 try:\r
996 fInputfile = open(MapFileName, "r", 0)\r
997 try:\r
998 FileLinesList = fInputfile.readlines()\r
999 except:\r
1000 EdkLogger.error("GenFds", FILE_READ_FAILURE, "File read failed for %s" %MapFileName,None)\r
1001 finally:\r
1002 fInputfile.close()\r
1003 except:\r
1004 EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %MapFileName,None)\r
1005 \r
1006 IsHex = False\r
1007 for eachLine in FileLinesList:\r
1008 for eachName in VfrUniBaseName.values():\r
1009 if eachLine.find(eachName) != -1:\r
1010 eachLine = eachLine.strip()\r
1011 Element = eachLine.split()\r
1012 #\r
1013 # MSFT/ICC/EBC map file\r
1014 #\r
1015 if (len(Element) == 4):\r
1016 try:\r
1017 int (Element[2], 16)\r
1018 IsHex = True\r
1019 except:\r
1020 IsHex = False\r
1021 \r
1022 if IsHex:\r
1023 RetValue.append((eachName, Element[2]))\r
1024 IsHex = False\r
1025 #\r
1026 # GCC map file\r
1027 #\r
1028 elif (len(Element) == 2) and Element[0].startswith("0x"):\r
1029 RetValue.append((eachName, Element[0]))\r
1030 \r
1031 return RetValue\r
1032 \r
1033 ## __GenUniVfrOffsetFile() method\r
1034 #\r
1035 # Generate the offset file for the module which contain VFR or UNI file.\r
1036 #\r
1037 # @param self The object pointer\r
1038 # @param VfrUniOffsetList A list contain the VFR/UNI offsets in the EFI image file.\r
1039 # @param UniVfrOffsetFileName The output offset file name.\r
1040 #\r
1041 def __GenUniVfrOffsetFile(self, VfrUniOffsetList, UniVfrOffsetFileName):\r
1042 \r
1043 try:\r
1044 fInputfile = open(UniVfrOffsetFileName, "wb+", 0)\r
1045 except:\r
1046 EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %UniVfrOffsetFileName,None)\r
1047 \r
1048 # Use a instance of StringIO to cache data\r
1049 fStringIO = StringIO.StringIO('') \r
1050 \r
1051 for Item in VfrUniOffsetList:\r
1052 if (Item[0].find("Strings") != -1):\r
1053 #\r
1054 # UNI offset in image.\r
1055 # GUID + Offset\r
1056 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }\r
1057 #\r
1058 UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]\r
1059 UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]\r
1060 fStringIO.write(''.join(UniGuid)) \r
1061 UniValue = pack ('Q', int (Item[1], 16))\r
1062 fStringIO.write (UniValue)\r
1063 else:\r
1064 #\r
1065 # VFR binary offset in image.\r
1066 # GUID + Offset\r
1067 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };\r
1068 #\r
1069 VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]\r
1070 VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]\r
1071 fStringIO.write(''.join(VfrGuid)) \r
1072 type (Item[1]) \r
1073 VfrValue = pack ('Q', int (Item[1], 16))\r
1074 fStringIO.write (VfrValue)\r
1075 \r
1076 #\r
1077 # write data into file.\r
1078 #\r
1079 try : \r
1080 fInputfile.write (fStringIO.getvalue())\r
1081 except:\r
1082 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
1083 \r
1084 fStringIO.close ()\r
1085 fInputfile.close ()\r
1086 \r
1087 \r
1088 \r
1089 \r
1090 \r
1091 \r
1092 \r
1093 \r