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