]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - BaseTools/Source/Python/GenFds/FfsInfStatement.py
BaseTools: Update Build tool to support multiple workspaces
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FfsInfStatement.py
... / ...
CommitLineData
1## @file\r
2# process FFS generation from INF statement\r
3#\r
4# Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
5# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>\r
6#\r
7# This program and the accompanying materials\r
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
20import Common.LongFilePathOs as os\r
21import StringIO\r
22from struct import *\r
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.MultipleWorkspace import MultipleWorkspace as mws\r
32from Common.String import *\r
33from Common.Misc import PathClass\r
34from Common.Misc import GuidStructureByteArrayToGuidString\r
35from Common.Misc import ProcessDuplicatedInf\r
36from Common.Misc import GetVariableOffset\r
37from Common import EdkLogger\r
38from Common.BuildToolError import *\r
39from GuidSection import GuidSection\r
40from FvImageSection import FvImageSection\r
41from Common.Misc import PeImageClass\r
42from AutoGen.GenDepex import DependencyExpression\r
43from PatchPcdValue.PatchPcdValue import PatchBinaryFile\r
44from Common.LongFilePathSupport import CopyLongFilePath\r
45from Common.LongFilePathSupport import OpenLongFilePath as open\r
46\r
47## generate FFS from INF\r
48#\r
49#\r
50class FfsInfStatement(FfsInfStatementClassObject):\r
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
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
64 self.PiSpecVersion = '0x00000000'\r
65 self.InfModule = None\r
66 self.FinalTargetSuffixMap = {}\r
67 self.CurrentLineNum = None\r
68 self.CurrentLineContent = None\r
69 self.FileName = None\r
70 self.InfFileName = None\r
71 self.OverrideGuid = None\r
72 self.PatchedBinFile = ''\r
73 self.MacroDict = {}\r
74\r
75 ## GetFinalTargetSuffixMap() method\r
76 #\r
77 # Get final build target list\r
78 def GetFinalTargetSuffixMap(self):\r
79 if not self.InfModule or not self.CurrentArch:\r
80 return []\r
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
142\r
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
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
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
173 ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")\r
174 if ErrorCode != 0:\r
175 EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
176\r
177 if self.OverrideGuid:\r
178 PathClassObj = ProcessDuplicatedInf(PathClassObj, self.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir)\r
179 if self.CurrentArch != None:\r
180\r
181 Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
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
188 if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:\r
189 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']\r
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
199 Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
200 self.BaseName = Inf.BaseName\r
201 self.ModuleGuid = Inf.Guid\r
202 self.ModuleType = Inf.ModuleType\r
203 if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:\r
204 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']\r
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
213 if self.OverrideGuid:\r
214 self.ModuleGuid = self.OverrideGuid\r
215\r
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
219 if self.ModuleType == 'SMM_CORE' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
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
222 if Inf._Defs != None and len(Inf._Defs) > 0:\r
223 self.OptRomDefs.update(Inf._Defs)\r
224\r
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
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
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
242 # Override Patchable PCD value by the value from DSC\r
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
253\r
254 # Override Patchable PCD value by the value from FDF\r
255 FdfOverride = False\r
256 if PcdKey in FdfPcdDict:\r
257 DefaultValue = FdfPcdDict[PcdKey]\r
258 FdfOverride = True\r
259\r
260 if not DscOverride and not FdfOverride:\r
261 continue\r
262 # Check value, if value are equal, no need to patch\r
263 if Pcd.DatumType == "VOID*":\r
264 if Pcd.DefaultValue == DefaultValue or DefaultValue in [None, '']:\r
265 continue\r
266 # Get the string size from FDF or DSC\r
267 if DefaultValue[0] == 'L':\r
268 # Remove L"", but the '\0' must be appended\r
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
276 # If no defined the maximum size in DSC, try to get current size from INF\r
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
292 # Check the Pcd size and data type\r
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
302 self.PatchPcds.append((Pcd, DefaultValue))\r
303\r
304 self.InfModule = Inf\r
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
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
325 ## PatchEfiFile\r
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
333 def PatchEfiFile(self, EfiFile, FileType):\r
334 if not self.PatchPcds:\r
335 return EfiFile\r
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
344 Basename = os.path.basename(EfiFile)\r
345 Output = os.path.join(self.OutputPath, Basename)\r
346 CopyLongFilePath(EfiFile, Output)\r
347 for Pcd, Value in self.PatchPcds:\r
348 RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Value, Pcd.MaxDatumSize)\r
349 if RetVal:\r
350 EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName)\r
351 self.PatchedBinFile = os.path.normpath(EfiFile)\r
352 return Output\r
353 ## GenFfs() method\r
354 #\r
355 # Generate FFS\r
356 #\r
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
362 #\r
363 def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None):\r
364 #\r
365 # Parse Inf file get Module related information\r
366 #\r
367\r
368 self.__InfParse__(Dict)\r
369 SrcFile = mws.join( GenFdsGlobalVariable.WorkSpaceDir , self.InfFileName);\r
370 DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')\r
371 \r
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
394 #\r
395 # Allow binary type module not specify override rule in FDF file.\r
396 # \r
397 if len(self.BinFileList) > 0:\r
398 if self.Rule == None or self.Rule == "":\r
399 self.Rule = "BINARY"\r
400 \r
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
406 #\r
407 # Convert Fv File Type for PI1.1 SMM driver.\r
408 #\r
409 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:\r
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
415 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
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
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
429 InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr)\r
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
451 String = GenFdsGlobalVariable.MacroExtend(String, self.MacroDict) \r
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
515 InfFileKey = os.path.normpath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))\r
516 DscArchList = []\r
517 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
518 if PlatformDataBase != None:\r
519 if InfFileKey in PlatformDataBase.Modules:\r
520 DscArchList.append ('IA32')\r
521\r
522 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'X64', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
523 if PlatformDataBase != None:\r
524 if InfFileKey in PlatformDataBase.Modules:\r
525 DscArchList.append ('X64')\r
526\r
527 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IPF', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
528 if PlatformDataBase != None:\r
529 if InfFileKey in (PlatformDataBase.Modules):\r
530 DscArchList.append ('IPF')\r
531\r
532 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'ARM', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
533 if PlatformDataBase != None:\r
534 if InfFileKey in (PlatformDataBase.Modules):\r
535 DscArchList.append ('ARM')\r
536\r
537 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'EBC', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
538 if PlatformDataBase != None:\r
539 if InfFileKey in (PlatformDataBase.Modules):\r
540 DscArchList.append ('EBC')\r
541\r
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
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
589 ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")\r
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
615 Index = FileName.rfind('.')\r
616 FileName = FileName[0:Index]\r
617 if self.OverrideGuid:\r
618 FileName = self.OverrideGuid\r
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
646 GenSecInputFile = None\r
647 if Rule.FileName != None:\r
648 GenSecInputFile = self.__ExtendMacro__(Rule.FileName)\r
649 if os.path.isabs(GenSecInputFile):\r
650 GenSecInputFile = os.path.normpath(GenSecInputFile)\r
651 else:\r
652 GenSecInputFile = os.path.normpath(os.path.join(self.EfiOutputPath, GenSecInputFile))\r
653 else:\r
654 FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension)\r
655\r
656 Index = 1\r
657 SectionType = Rule.SectionType\r
658 #\r
659 # Convert Fv Section Type for PI1.1 SMM driver.\r
660 #\r
661 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:\r
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
667 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
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
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
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
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
700 (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):\r
701 CopyLongFilePath(File, FileBeforeStrip)\r
702 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')\r
703 GenFdsGlobalVariable.GenerateFirmwareImage(\r
704 StrippedFile,\r
705 [File],\r
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
714 [File],\r
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
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
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
739 (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)):\r
740 CopyLongFilePath(GenSecInputFile, FileBeforeStrip)\r
741\r
742 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')\r
743 GenFdsGlobalVariable.GenerateFirmwareImage(\r
744 StrippedFile,\r
745 [GenSecInputFile],\r
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
754 [GenSecInputFile],\r
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
784 SectionAlignments.append(Rule.SectAlignment)\r
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
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
816 #\r
817 def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr):\r
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
824 HasGneratedFlag = False\r
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
849 for Sect in Rule.SectionList:\r
850 SecIndex = '%d' %Index\r
851 SectList = []\r
852 #\r
853 # Convert Fv Section Type for PI1.1 SMM driver.\r
854 #\r
855 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:\r
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
861 if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
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
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
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
879 \r
880 if not HasGneratedFlag:\r
881 UniVfrOffsetFileSection = "" \r
882 ModuleFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)\r
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
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
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
993 MapFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".map")\r
994 EfiFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".efi")\r
995 return GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values())\r
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