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