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