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