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