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