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