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