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