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