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