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