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