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