]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/GenFds.py
BaseTools: AutoGen and GenFds share the parser data.
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / GenFds.py
CommitLineData
f51461c8
LG
1## @file\r
2# generate flash image\r
3#\r
541a3f58 4# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
f51461c8
LG
5#\r
6# This program and the accompanying materials\r
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
1ccc4d89
LG
18from __future__ import print_function\r
19from __future__ import absolute_import\r
9e47e6f9 20from re import compile\r
f51461c8 21from optparse import OptionParser\r
9e47e6f9
CJ
22from sys import exit\r
23from glob import glob\r
24from struct import unpack\r
25from linecache import getlines\r
86379ac4 26from io import BytesIO\r
9e47e6f9
CJ
27\r
28import Common.LongFilePathOs as os\r
29from Common.TargetTxtClassObject import TargetTxtClassObject\r
95816356 30from Common.DataType import *\r
f51461c8
LG
31import Common.GlobalData as GlobalData\r
32from Common import EdkLogger\r
9e47e6f9
CJ
33from Common.StringUtils import NormPath\r
34from Common.Misc import DirCache, PathClass, GuidStructureStringToGuidString\r
35from Common.Misc import SaveFileOnChange, ClearDuplicatedInf\r
f51461c8 36from Common.BuildVersion import gBUILD_VERSION\r
05cc51ad 37from Common.MultipleWorkspace import MultipleWorkspace as mws\r
b3497bad 38from Common.BuildToolError import FatalError, GENFDS_ERROR, CODE_ERROR, FORMAT_INVALID, RESOURCE_NOT_AVAILABLE, FILE_NOT_FOUND, OPTION_MISSING, FORMAT_NOT_SUPPORTED, OPTION_VALUE_INVALID, PARAMETER_INVALID\r
9e47e6f9
CJ
39from Workspace.WorkspaceDatabase import WorkspaceDatabase\r
40\r
41from .FdfParser import FdfParser, Warning\r
42from .GenFdsGlobalVariable import GenFdsGlobalVariable\r
43from .FfsFileStatement import FileStatement\r
f51461c8
LG
44\r
45## Version and Copyright\r
46versionNumber = "1.0" + ' ' + gBUILD_VERSION\r
47__version__ = "%prog Version " + versionNumber\r
f7496d71 48__copyright__ = "Copyright (c) 2007 - 2018, Intel Corporation All rights reserved."\r
f51461c8
LG
49\r
50## Tool entrance method\r
51#\r
52# This method mainly dispatch specific methods per the command line options.\r
53# If no error found, return zero value so the caller of this tool can know\r
54# if it's executed successfully or not.\r
55#\r
56# @retval 0 Tool was successful\r
57# @retval 1 Tool failed\r
58#\r
59def main():\r
60 global Options\r
61 Options = myOptionParser()\r
b3497bad
ZZ
62 EdkLogger.Initialize()\r
63 return GenFdsApi(OptionsToCommandDict(Options))\r
f51461c8 64\r
b3497bad 65def GenFdsApi(FdsCommandDict, WorkSpaceDataBase=None):\r
f51461c8
LG
66 global Workspace\r
67 Workspace = ""\r
68 ArchList = None\r
69 ReturnCode = 0\r
70\r
f51461c8 71 try:\r
b3497bad 72 if FdsCommandDict.get("verbose"):\r
f51461c8
LG
73 EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
74 GenFdsGlobalVariable.VerboseMode = True\r
f7496d71 75\r
b3497bad 76 if FdsCommandDict.get("FixedAddress"):\r
f51461c8 77 GenFdsGlobalVariable.FixedLoadAddress = True\r
f7496d71 78\r
b3497bad 79 if FdsCommandDict.get("quiet"):\r
f51461c8 80 EdkLogger.SetLevel(EdkLogger.QUIET)\r
b3497bad
ZZ
81 if FdsCommandDict.get("debug"):\r
82 EdkLogger.SetLevel(FdsCommandDict.get("debug") + 1)\r
83 GenFdsGlobalVariable.DebugLevel = FdsCommandDict.get("debug")\r
f51461c8
LG
84 else:\r
85 EdkLogger.SetLevel(EdkLogger.INFO)\r
86\r
b3497bad 87 if not FdsCommandDict.get("Workspace",os.environ.get('WORKSPACE')):\r
f51461c8
LG
88 EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined",\r
89 ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
b3497bad 90 elif not os.path.exists(FdsCommandDict.get("Workspace",os.environ.get('WORKSPACE'))):\r
f51461c8
LG
91 EdkLogger.error("GenFds", PARAMETER_INVALID, "WORKSPACE is invalid",\r
92 ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.")\r
93 else:\r
b3497bad 94 Workspace = os.path.normcase(FdsCommandDict.get("Workspace",os.environ.get('WORKSPACE')))\r
f51461c8 95 GenFdsGlobalVariable.WorkSpaceDir = Workspace\r
9eb87141 96 if 'EDK_SOURCE' in os.environ:\r
f51461c8 97 GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE'])\r
b3497bad 98 if FdsCommandDict.get("debug"):\r
47fea6af 99 GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace)\r
b3497bad 100 if FdsCommandDict.get("GenfdsMultiThread"):\r
37de70b7 101 GenFdsGlobalVariable.EnableGenfdsMultiThread = True\r
f51461c8 102 os.chdir(GenFdsGlobalVariable.WorkSpaceDir)\r
f7496d71 103\r
05cc51ad
LY
104 # set multiple workspace\r
105 PackagesPath = os.getenv("PACKAGES_PATH")\r
106 mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath)\r
f51461c8 107\r
b3497bad
ZZ
108 if FdsCommandDict.get("fdf_file"):\r
109 FdfFilename = FdsCommandDict.get("fdf_file")[0].Path\r
f51461c8
LG
110 FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename)\r
111\r
112 if FdfFilename[0:2] == '..':\r
113 FdfFilename = os.path.realpath(FdfFilename)\r
47fea6af 114 if not os.path.isabs(FdfFilename):\r
05cc51ad 115 FdfFilename = mws.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename)\r
f51461c8
LG
116 if not os.path.exists(FdfFilename):\r
117 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=FdfFilename)\r
f51461c8
LG
118\r
119 GenFdsGlobalVariable.FdfFile = FdfFilename\r
120 GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename)\r
121 else:\r
122 EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF filename")\r
123\r
b3497bad
ZZ
124 if FdsCommandDict.get("build_target"):\r
125 GenFdsGlobalVariable.TargetName = FdsCommandDict.get("build_target")\r
f51461c8 126\r
b3497bad
ZZ
127 if FdsCommandDict.get("toolchain_tag"):\r
128 GenFdsGlobalVariable.ToolChainTag = FdsCommandDict.get("toolchain_tag")\r
f51461c8 129\r
b3497bad
ZZ
130 if FdsCommandDict.get("active_platform"):\r
131 ActivePlatform = FdsCommandDict.get("active_platform")\r
f51461c8
LG
132 ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform)\r
133\r
134 if ActivePlatform[0:2] == '..':\r
135 ActivePlatform = os.path.realpath(ActivePlatform)\r
136\r
137 if not os.path.isabs (ActivePlatform):\r
05cc51ad 138 ActivePlatform = mws.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform)\r
f51461c8 139\r
9e47e6f9 140 if not os.path.exists(ActivePlatform):\r
f51461c8 141 EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!")\r
f51461c8
LG
142 else:\r
143 EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform")\r
144\r
b3497bad 145 GlobalData.BuildOptionPcd = FdsCommandDict.get("OptionPcd") if FdsCommandDict.get("OptionPcd") else {}\r
e642ceb8 146 GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform))\r
f51461c8 147\r
b3497bad 148 if FdsCommandDict.get("conf_directory"):\r
97fa0ee9 149 # Get alternate Conf location, if it is absolute, then just use the absolute directory name\r
b3497bad 150 ConfDirectoryPath = os.path.normpath(FdsCommandDict.get("conf_directory"))\r
97fa0ee9
YL
151 if ConfDirectoryPath.startswith('"'):\r
152 ConfDirectoryPath = ConfDirectoryPath[1:]\r
153 if ConfDirectoryPath.endswith('"'):\r
154 ConfDirectoryPath = ConfDirectoryPath[:-1]\r
155 if not os.path.isabs(ConfDirectoryPath):\r
156 # Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE\r
157 # This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf\r
158 ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ConfDirectoryPath)\r
159 else:\r
9eb87141 160 if "CONF_PATH" in os.environ:\r
00bcb5c2
YZ
161 ConfDirectoryPath = os.path.normcase(os.environ["CONF_PATH"])\r
162 else:\r
163 # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf\r
164 ConfDirectoryPath = mws.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf')\r
97fa0ee9 165 GenFdsGlobalVariable.ConfDir = ConfDirectoryPath\r
541a3f58
FY
166 if not GlobalData.gConfDirectory:\r
167 GlobalData.gConfDirectory = GenFdsGlobalVariable.ConfDir\r
97fa0ee9 168 BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, "target.txt"))\r
f51461c8 169 if os.path.isfile(BuildConfigurationFile) == True:\r
9e47e6f9 170 TargetTxt = TargetTxtClassObject()\r
e4979bee
YZ
171 TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)\r
172 # if no build target given in command line, get it from target.txt\r
173 if not GenFdsGlobalVariable.TargetName:\r
b3497bad 174 BuildTargetList = TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_TARGET]\r
e4979bee
YZ
175 if len(BuildTargetList) != 1:\r
176 EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for Target.")\r
177 GenFdsGlobalVariable.TargetName = BuildTargetList[0]\r
178\r
179 # if no tool chain given in command line, get it from target.txt\r
180 if not GenFdsGlobalVariable.ToolChainTag:\r
b3497bad 181 ToolChainList = TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_TOOL_CHAIN_TAG]\r
4231a819 182 if ToolChainList is None or len(ToolChainList) == 0:\r
e4979bee
YZ
183 EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build.")\r
184 if len(ToolChainList) != 1:\r
185 EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for ToolChain.")\r
186 GenFdsGlobalVariable.ToolChainTag = ToolChainList[0]\r
f51461c8
LG
187 else:\r
188 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile)\r
189\r
97fa0ee9 190 #Set global flag for build mode\r
b3497bad 191 GlobalData.gIgnoreSource = FdsCommandDict.get("IgnoreSources")\r
97fa0ee9 192\r
b3497bad
ZZ
193 if FdsCommandDict.get("macro"):\r
194 for Pair in FdsCommandDict.get("macro"):\r
97fa0ee9
YL
195 if Pair.startswith('"'):\r
196 Pair = Pair[1:]\r
197 if Pair.endswith('"'):\r
198 Pair = Pair[:-1]\r
f51461c8
LG
199 List = Pair.split('=')\r
200 if len(List) == 2:\r
e4979bee
YZ
201 if not List[1].strip():\r
202 EdkLogger.error("GenFds", OPTION_VALUE_INVALID, ExtraData="No Value given for Macro %s" %List[0])\r
f51461c8
LG
203 if List[0].strip() == "EFI_SOURCE":\r
204 GlobalData.gEfiSource = List[1].strip()\r
205 GlobalData.gGlobalDefines["EFI_SOURCE"] = GlobalData.gEfiSource\r
206 continue\r
207 elif List[0].strip() == "EDK_SOURCE":\r
208 GlobalData.gEdkSource = List[1].strip()\r
209 GlobalData.gGlobalDefines["EDK_SOURCE"] = GlobalData.gEdkSource\r
210 continue\r
211 elif List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]:\r
212 GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip()\r
213 else:\r
214 GlobalData.gCommandLineDefines[List[0].strip()] = List[1].strip()\r
215 else:\r
216 GlobalData.gCommandLineDefines[List[0].strip()] = "TRUE"\r
217 os.environ["WORKSPACE"] = Workspace\r
218\r
e4979bee 219 # Use the -t and -b option as gGlobalDefines's TOOLCHAIN and TARGET if they are not defined\r
9eb87141 220 if "TARGET" not in GlobalData.gGlobalDefines:\r
e4979bee 221 GlobalData.gGlobalDefines["TARGET"] = GenFdsGlobalVariable.TargetName\r
9eb87141 222 if "TOOLCHAIN" not in GlobalData.gGlobalDefines:\r
e4979bee 223 GlobalData.gGlobalDefines["TOOLCHAIN"] = GenFdsGlobalVariable.ToolChainTag\r
9eb87141 224 if "TOOL_CHAIN_TAG" not in GlobalData.gGlobalDefines:\r
e4979bee
YZ
225 GlobalData.gGlobalDefines['TOOL_CHAIN_TAG'] = GenFdsGlobalVariable.ToolChainTag\r
226\r
f51461c8 227 """call Workspace build create database"""\r
97fa0ee9 228 GlobalData.gDatabasePath = os.path.normpath(os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath))\r
b3497bad
ZZ
229 if WorkSpaceDataBase:\r
230 BuildWorkSpace = WorkSpaceDataBase\r
231 else:\r
232 BuildWorkSpace = WorkspaceDatabase(GlobalData.gDatabasePath)\r
233 BuildWorkSpace.InitDatabase()\r
f7496d71 234\r
f51461c8
LG
235 #\r
236 # Get files real name in workspace dir\r
237 #\r
238 GlobalData.gAllFiles = DirCache(Workspace)\r
239 GlobalData.gWorkspace = Workspace\r
240\r
b3497bad
ZZ
241 if FdsCommandDict.get("build_architecture_list"):\r
242 ArchList = FdsCommandDict.get("build_architecture_list").split(',')\r
f51461c8 243 else:\r
b3497bad 244 ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].SupArchList\r
f51461c8 245\r
b3497bad 246 TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].SupArchList) & set(ArchList)\r
f51461c8 247 if len(TargetArchList) == 0:\r
55c84777 248 EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON].SupArchList)))\r
f7496d71 249\r
f51461c8 250 for Arch in ArchList:\r
b3497bad 251 GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].OutputDirectory)\r
f51461c8 252\r
9e47e6f9 253 # assign platform name based on last entry in ArchList\r
b3497bad 254 GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, ArchList[-1], FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].PlatformName\r
9e47e6f9 255\r
b3497bad
ZZ
256 if FdsCommandDict.get("platform_build_directory"):\r
257 OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdsCommandDict.get("platform_build_directory"))\r
f51461c8
LG
258 if not os.path.isabs (OutputDirFromCommandLine):\r
259 OutputDirFromCommandLine = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, OutputDirFromCommandLine)\r
260 for Arch in ArchList:\r
261 GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine\r
262 else:\r
263 for Arch in ArchList:\r
264 GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag)\r
265\r
266 for Key in GenFdsGlobalVariable.OutputDirDict:\r
267 OutputDir = GenFdsGlobalVariable.OutputDirDict[Key]\r
268 if OutputDir[0:2] == '..':\r
269 OutputDir = os.path.realpath(OutputDir)\r
270\r
271 if OutputDir[1] != ':':\r
272 OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir)\r
273\r
274 if not os.path.exists(OutputDir):\r
275 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=OutputDir)\r
276 GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir\r
277\r
278 """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """\r
b3497bad
ZZ
279 if WorkSpaceDataBase:\r
280 FdfParserObj = GlobalData.gFdfParser\r
281 else:\r
282 FdfParserObj = FdfParser(FdfFilename)\r
283 FdfParserObj.ParseFile()\r
f51461c8
LG
284\r
285 if FdfParserObj.CycleReferenceCheck():\r
286 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file")\r
287\r
b3497bad
ZZ
288 if FdsCommandDict.get("fd"):\r
289 if FdsCommandDict.get("fd")[0].upper() in FdfParserObj.Profile.FdDict:\r
290 GenFds.OnlyGenerateThisFd = FdsCommandDict.get("fd")[0]\r
f51461c8
LG
291 else:\r
292 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
b3497bad 293 "No such an FD in FDF file: %s" % FdsCommandDict.get("fd")[0])\r
f51461c8 294\r
b3497bad
ZZ
295 if FdsCommandDict.get("fv"):\r
296 if FdsCommandDict.get("fv")[0].upper() in FdfParserObj.Profile.FvDict:\r
297 GenFds.OnlyGenerateThisFv = FdsCommandDict.get("fv")[0]\r
f51461c8
LG
298 else:\r
299 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
b3497bad 300 "No such an FV in FDF file: %s" % FdsCommandDict.get("fv")[0])\r
f51461c8 301\r
b3497bad
ZZ
302 if FdsCommandDict.get("cap"):\r
303 if FdsCommandDict.get("cap")[0].upper() in FdfParserObj.Profile.CapsuleDict:\r
304 GenFds.OnlyGenerateThisCap = FdsCommandDict.get("cap")[0]\r
f51461c8
LG
305 else:\r
306 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
b3497bad 307 "No such a Capsule in FDF file: %s" % FdsCommandDict.get("cap")[0])\r
f51461c8 308\r
6b17c11b 309 GenFdsGlobalVariable.WorkSpace = BuildWorkSpace\r
9e47e6f9 310 if ArchList:\r
6b17c11b
YZ
311 GenFdsGlobalVariable.ArchList = ArchList\r
312\r
6f49996c 313 # Dsc Build Data will handle Pcd Settings from CommandLine.\r
6b17c11b 314\r
f51461c8
LG
315 """Modify images from build output if the feature of loading driver at fixed address is on."""\r
316 if GenFdsGlobalVariable.FixedLoadAddress:\r
317 GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform)\r
135ae8c8
YZ
318\r
319 # Record the FV Region info that may specific in the FD\r
320 if FdfParserObj.Profile.FvDict and FdfParserObj.Profile.FdDict:\r
9e47e6f9
CJ
321 for FvObj in FdfParserObj.Profile.FvDict.values():\r
322 for FdObj in FdfParserObj.Profile.FdDict.values():\r
135ae8c8 323 for RegionObj in FdObj.RegionList:\r
91fa33ee 324 if RegionObj.RegionType != BINARY_FILE_TYPE_FV:\r
135ae8c8
YZ
325 continue\r
326 for RegionData in RegionObj.RegionDataList:\r
327 if FvObj.UiFvName.upper() == RegionData.upper():\r
328 if FvObj.FvRegionInFD:\r
329 if FvObj.FvRegionInFD != RegionObj.Size:\r
330 EdkLogger.error("GenFds", FORMAT_INVALID, "The FV %s's region is specified in multiple FD with different value." %FvObj.UiFvName)\r
331 else:\r
332 FvObj.FvRegionInFD = RegionObj.Size\r
333 RegionObj.BlockInfoOfRegion(FdObj.BlockSizeList, FvObj)\r
334\r
f51461c8
LG
335 """Call GenFds"""\r
336 GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)\r
337\r
338 """Generate GUID cross reference file"""\r
5e9256cd 339 GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList, FdfParserObj)\r
f51461c8
LG
340\r
341 """Display FV space info."""\r
342 GenFds.DisplayFvSpaceInfo(FdfParserObj)\r
343\r
9e47e6f9 344 except Warning as X:\r
47fea6af 345 EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)\r
f51461c8 346 ReturnCode = FORMAT_INVALID\r
5b0671c1 347 except FatalError as X:\r
b3497bad 348 if FdsCommandDict.get("debug") is not None:\r
f51461c8
LG
349 import traceback\r
350 EdkLogger.quiet(traceback.format_exc())\r
351 ReturnCode = X.args[0]\r
352 except:\r
353 import traceback\r
354 EdkLogger.error(\r
355 "\nPython",\r
356 CODE_ERROR,\r
357 "Tools code failure",\r
3a0f8bde 358 ExtraData="Please send email to edk2-devel@lists.01.org for help, attaching following call stack trace!\n",\r
f51461c8
LG
359 RaiseError=False\r
360 )\r
361 EdkLogger.quiet(traceback.format_exc())\r
362 ReturnCode = CODE_ERROR\r
97fa0ee9
YL
363 finally:\r
364 ClearDuplicatedInf()\r
f51461c8
LG
365 return ReturnCode\r
366\r
b3497bad
ZZ
367def OptionsToCommandDict(Options):\r
368 FdsCommandDict = {}\r
369 FdsCommandDict["verbose"] = Options.verbose\r
370 FdsCommandDict["FixedAddress"] = Options.FixedAddress\r
371 FdsCommandDict["quiet"] = Options.quiet\r
372 FdsCommandDict["debug"] = Options.debug\r
373 FdsCommandDict["Workspace"] = Options.Workspace\r
374 FdsCommandDict["GenfdsMultiThread"] = Options.GenfdsMultiThread\r
375 FdsCommandDict["fdf_file"] = [PathClass(Options.filename)] if Options.filename else []\r
376 FdsCommandDict["build_target"] = Options.BuildTarget\r
377 FdsCommandDict["toolchain_tag"] = Options.ToolChain\r
378 FdsCommandDict["active_platform"] = Options.activePlatform\r
379 FdsCommandDict["OptionPcd"] = Options.OptionPcd\r
380 FdsCommandDict["conf_directory"] = Options.ConfDirectory\r
381 FdsCommandDict["IgnoreSources"] = Options.IgnoreSources\r
382 FdsCommandDict["macro"] = Options.Macros\r
383 FdsCommandDict["build_architecture_list"] = Options.archList\r
384 FdsCommandDict["platform_build_directory"] = Options.outputDir\r
385 FdsCommandDict["fd"] = [Options.uiFdName] if Options.uiFdName else []\r
386 FdsCommandDict["fv"] = [Options.uiFvName] if Options.uiFvName else []\r
387 FdsCommandDict["cap"] = [Options.uiCapName] if Options.uiCapName else []\r
388 return FdsCommandDict\r
389\r
390\r
f51461c8
LG
391gParamCheck = []\r
392def SingleCheckCallback(option, opt_str, value, parser):\r
393 if option not in gParamCheck:\r
394 setattr(parser.values, option.dest, value)\r
395 gParamCheck.append(option)\r
396 else:\r
397 parser.error("Option %s only allows one instance in command line!" % option)\r
6b17c11b 398\r
f51461c8
LG
399## Parse command line options\r
400#\r
401# Using standard Python module optparse to parse command line option of this tool.\r
402#\r
403# @retval Opt A optparse.Values object containing the parsed options\r
f51461c8
LG
404#\r
405def myOptionParser():\r
406 usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""\r
47fea6af 407 Parser = OptionParser(usage=usage, description=__copyright__, version="%prog " + str(versionNumber))\r
f51461c8
LG
408 Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback)\r
409 Parser.add_option("-a", "--arch", dest="archList", help="comma separated list containing one or more of: IA32, X64, IPF, ARM, AARCH64 or EBC which should be built, overrides target.txt?s TARGET_ARCH")\r
410 Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
411 Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")\r
412 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
413 Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",\r
414 action="callback", callback=SingleCheckCallback)\r
415 Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE",\r
416 action="callback", callback=SingleCheckCallback)\r
417 Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory",\r
418 action="callback", callback=SingleCheckCallback)\r
419 Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")\r
420 Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Build the FV image using the [FV] section named by UiFvName")\r
421 Parser.add_option("-C", "--CapsuleImage", dest="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName")\r
422 Parser.add_option("-b", "--buildtarget", type="string", dest="BuildTarget", help="Set the build TARGET, overrides target.txt TARGET setting.",\r
423 action="callback", callback=SingleCheckCallback)\r
424 Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",\r
425 action="callback", callback=SingleCheckCallback)\r
426 Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")\r
427 Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")\r
97fa0ee9
YL
428 Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")\r
429 Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files")\r
6b17c11b 430 Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")\r
37de70b7 431 Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=False, help="Enable GenFds multi thread to generate ffs file.")\r
97fa0ee9 432\r
9e47e6f9 433 Options, _ = Parser.parse_args()\r
f51461c8
LG
434 return Options\r
435\r
436## The class implementing the EDK2 flash image generation process\r
437#\r
438# This process includes:\r
439# 1. Collect workspace information, includes platform and module information\r
440# 2. Call methods of Fd class to generate FD\r
441# 3. Call methods of Fv class to generate FV that not belong to FD\r
442#\r
9e47e6f9 443class GenFds(object):\r
f51461c8 444 FdfParsef = None\r
f51461c8
LG
445 OnlyGenerateThisFd = None\r
446 OnlyGenerateThisFv = None\r
447 OnlyGenerateThisCap = None\r
448\r
449 ## GenFd()\r
450 #\r
451 # @param OutputDir Output directory\r
9e47e6f9 452 # @param FdfParserObject FDF contents parser\r
f51461c8
LG
453 # @param Workspace The directory of workspace\r
454 # @param ArchList The Arch list of platform\r
455 #\r
9e47e6f9
CJ
456 @staticmethod\r
457 def GenFd (OutputDir, FdfParserObject, WorkSpace, ArchList):\r
458 GenFdsGlobalVariable.SetDir ('', FdfParserObject, WorkSpace, ArchList)\r
f51461c8
LG
459\r
460 GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")\r
9eb87141
CJ
461 if GenFds.OnlyGenerateThisCap is not None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict:\r
462 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[GenFds.OnlyGenerateThisCap.upper()]\r
4231a819 463 if CapsuleObj is not None:\r
f51461c8
LG
464 CapsuleObj.GenCapsule()\r
465 return\r
466\r
9eb87141
CJ
467 if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict:\r
468 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
4231a819 469 if FdObj is not None:\r
f51461c8
LG
470 FdObj.GenFd()\r
471 return\r
4231a819 472 elif GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisFv is None:\r
9eb87141 473 for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
f51461c8
LG
474 FdObj.GenFd()\r
475\r
476 GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")\r
9eb87141
CJ
477 if GenFds.OnlyGenerateThisFv is not None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict:\r
478 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[GenFds.OnlyGenerateThisFv.upper()]\r
4231a819 479 if FvObj is not None:\r
86379ac4 480 Buffer = BytesIO()\r
f51461c8
LG
481 FvObj.AddToBuffer(Buffer)\r
482 Buffer.close()\r
483 return\r
4231a819 484 elif GenFds.OnlyGenerateThisFv is None:\r
9eb87141 485 for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict.values():\r
1ccc4d89 486 Buffer = BytesIO('')\r
f51461c8
LG
487 FvObj.AddToBuffer(Buffer)\r
488 Buffer.close()\r
f7496d71 489\r
4231a819 490 if GenFds.OnlyGenerateThisFv is None and GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisCap is None:\r
f51461c8
LG
491 if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:\r
492 GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")\r
9eb87141 493 for CapsuleObj in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.values():\r
f51461c8
LG
494 CapsuleObj.GenCapsule()\r
495\r
496 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
497 GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")\r
9eb87141 498 for OptRomObj in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.values():\r
f51461c8 499 OptRomObj.AddToBuffer(None)\r
9e47e6f9 500\r
37de70b7 501 @staticmethod\r
9e47e6f9
CJ
502 def GenFfsMakefile(OutputDir, FdfParserObject, WorkSpace, ArchList, GlobalData):\r
503 GenFdsGlobalVariable.SetEnv(FdfParserObject, WorkSpace, ArchList, GlobalData)\r
9eb87141 504 for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
37de70b7
YZ
505 FdObj.GenFd(Flag=True)\r
506\r
9eb87141 507 for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict.values():\r
37de70b7
YZ
508 FvObj.AddToBuffer(Buffer=None, Flag=True)\r
509\r
510 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
9eb87141 511 for OptRomObj in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.values():\r
37de70b7
YZ
512 OptRomObj.AddToBuffer(Buffer=None, Flag=True)\r
513\r
514 return GenFdsGlobalVariable.FfsCmdDict\r
f51461c8
LG
515\r
516 ## GetFvBlockSize()\r
517 #\r
518 # @param FvObj Whose block size to get\r
519 # @retval int Block size value\r
520 #\r
9e47e6f9 521 @staticmethod\r
f51461c8
LG
522 def GetFvBlockSize(FvObj):\r
523 DefaultBlockSize = 0x1\r
524 FdObj = None\r
9eb87141 525 if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict:\r
f51461c8 526 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
4231a819 527 if FdObj is None:\r
f51461c8
LG
528 for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
529 for ElementRegion in ElementFd.RegionList:\r
91fa33ee 530 if ElementRegion.RegionType == BINARY_FILE_TYPE_FV:\r
f51461c8 531 for ElementRegionData in ElementRegion.RegionDataList:\r
4231a819 532 if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:\r
f51461c8
LG
533 if FvObj.BlockSizeList != []:\r
534 return FvObj.BlockSizeList[0][0]\r
535 else:\r
536 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
537 if FvObj.BlockSizeList != []:\r
538 return FvObj.BlockSizeList[0][0]\r
539 return DefaultBlockSize\r
540 else:\r
541 for ElementRegion in FdObj.RegionList:\r
91fa33ee 542 if ElementRegion.RegionType == BINARY_FILE_TYPE_FV:\r
f51461c8 543 for ElementRegionData in ElementRegion.RegionDataList:\r
4231a819 544 if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:\r
f51461c8
LG
545 if FvObj.BlockSizeList != []:\r
546 return FvObj.BlockSizeList[0][0]\r
547 else:\r
548 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
549 return DefaultBlockSize\r
550\r
551 ## DisplayFvSpaceInfo()\r
552 #\r
553 # @param FvObj Whose block size to get\r
554 # @retval None\r
555 #\r
9e47e6f9
CJ
556 @staticmethod\r
557 def DisplayFvSpaceInfo(FdfParserObject):\r
f7496d71 558\r
f51461c8
LG
559 FvSpaceInfoList = []\r
560 MaxFvNameLength = 0\r
9e47e6f9 561 for FvName in FdfParserObject.Profile.FvDict:\r
f51461c8
LG
562 if len(FvName) > MaxFvNameLength:\r
563 MaxFvNameLength = len(FvName)\r
564 FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map')\r
565 if os.path.exists(FvSpaceInfoFileName):\r
9e47e6f9 566 FileLinesList = getlines(FvSpaceInfoFileName)\r
f51461c8
LG
567 TotalFound = False\r
568 Total = ''\r
569 UsedFound = False\r
570 Used = ''\r
571 FreeFound = False\r
572 Free = ''\r
573 for Line in FileLinesList:\r
574 NameValue = Line.split('=')\r
575 if len(NameValue) == 2:\r
576 if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE':\r
577 TotalFound = True\r
578 Total = NameValue[1].strip()\r
579 if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE':\r
580 UsedFound = True\r
581 Used = NameValue[1].strip()\r
582 if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE':\r
583 FreeFound = True\r
584 Free = NameValue[1].strip()\r
f7496d71 585\r
f51461c8
LG
586 if TotalFound and UsedFound and FreeFound:\r
587 FvSpaceInfoList.append((FvName, Total, Used, Free))\r
f7496d71 588\r
f51461c8
LG
589 GenFdsGlobalVariable.InfLogger('\nFV Space Information')\r
590 for FvSpaceInfo in FvSpaceInfoList:\r
591 Name = FvSpaceInfo[0]\r
1ccc4d89
LG
592 TotalSizeValue = long(FvSpaceInfo[1], 0)\r
593 UsedSizeValue = long(FvSpaceInfo[2], 0)\r
594 FreeSizeValue = long(FvSpaceInfo[3], 0)\r
f51461c8
LG
595 if UsedSizeValue == TotalSizeValue:\r
596 Percentage = '100'\r
597 else:\r
47fea6af
YZ
598 Percentage = str((UsedSizeValue + 0.0) / TotalSizeValue)[0:4].lstrip('0.')\r
599\r
f51461c8
LG
600 GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + Percentage + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free')\r
601\r
602 ## PreprocessImage()\r
603 #\r
604 # @param BuildDb Database from build meta data files\r
605 # @param DscFile modules from dsc file will be preprocessed\r
606 # @retval None\r
607 #\r
9e47e6f9 608 @staticmethod\r
f51461c8 609 def PreprocessImage(BuildDb, DscFile):\r
55c84777 610 PcdDict = BuildDb.BuildObject[DscFile, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds\r
f51461c8
LG
611 PcdValue = ''\r
612 for Key in PcdDict:\r
613 PcdObj = PcdDict[Key]\r
614 if PcdObj.TokenCName == 'PcdBsBaseAddress':\r
615 PcdValue = PcdObj.DefaultValue\r
616 break\r
f7496d71 617\r
f51461c8
LG
618 if PcdValue == '':\r
619 return\r
f7496d71 620\r
1ccc4d89 621 Int64PcdValue = long(PcdValue, 0)\r
f7496d71 622 if Int64PcdValue == 0 or Int64PcdValue < -1:\r
f51461c8 623 return\r
f7496d71 624\r
f51461c8
LG
625 TopAddress = 0\r
626 if Int64PcdValue > 0:\r
627 TopAddress = Int64PcdValue\r
f7496d71 628\r
55c84777 629 ModuleDict = BuildDb.BuildObject[DscFile, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Modules\r
f51461c8 630 for Key in ModuleDict:\r
55c84777 631 ModuleObj = BuildDb.BuildObject[Key, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
72443dd2 632 print(ModuleObj.BaseName + ' ' + ModuleObj.ModuleType)\r
f51461c8 633\r
9e47e6f9 634 @staticmethod\r
5e9256cd 635 def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj):\r
f51461c8 636 GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")\r
1ccc4d89 637 GuidXRefFile = BytesIO('')\r
0fece18d 638 PkgGuidDict = {}\r
e4ac870f 639 GuidDict = {}\r
5e9256cd
YZ
640 ModuleList = []\r
641 FileGuidList = []\r
f51461c8
LG
642 for Arch in ArchList:\r
643 PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
0fece18d 644 PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag)\r
645 for P in PkgList:\r
646 PkgGuidDict.update(P.Guids)\r
1ccc4d89 647 for Name, Guid in PlatformDataBase.Pcds:\r
0fece18d 648 Pcd = PlatformDataBase.Pcds[Name, Guid]\r
649 if Pcd.Type in [TAB_PCDS_DYNAMIC_HII, TAB_PCDS_DYNAMIC_EX_HII]:\r
650 for SkuId in Pcd.SkuInfoList:\r
651 Sku = Pcd.SkuInfoList[SkuId]\r
652 if Sku.VariableGuid and Sku.VariableGuid in PkgGuidDict.keys():\r
653 GuidDict[Sku.VariableGuid] = PkgGuidDict[Sku.VariableGuid]\r
f51461c8
LG
654 for ModuleFile in PlatformDataBase.Modules:\r
655 Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
5e9256cd
YZ
656 if Module in ModuleList:\r
657 continue\r
658 else:\r
659 ModuleList.append(Module)\r
9e47e6f9 660 if GlobalData.gGuidPattern.match(ModuleFile.BaseName):\r
1d802e23
YF
661 GuidXRefFile.write("%s %s\n" % (ModuleFile.BaseName, Module.BaseName))\r
662 else:\r
663 GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))\r
9e47e6f9
CJ
664 GuidDict.update(Module.Protocols)\r
665 GuidDict.update(Module.Guids)\r
666 GuidDict.update(Module.Ppis)\r
5e9256cd
YZ
667 for FvName in FdfParserObj.Profile.FvDict:\r
668 for FfsObj in FdfParserObj.Profile.FvDict[FvName].FfsList:\r
9e47e6f9 669 if not isinstance(FfsObj, FileStatement):\r
5e9256cd
YZ
670 InfPath = PathClass(NormPath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, FfsObj.InfFileName)))\r
671 FdfModule = BuildDb.BuildObject[InfPath, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
672 if FdfModule in ModuleList:\r
673 continue\r
674 else:\r
675 ModuleList.append(FdfModule)\r
676 GuidXRefFile.write("%s %s\n" % (FdfModule.Guid, FdfModule.BaseName))\r
9e47e6f9
CJ
677 GuidDict.update(FdfModule.Protocols)\r
678 GuidDict.update(FdfModule.Guids)\r
679 GuidDict.update(FdfModule.Ppis)\r
5e9256cd
YZ
680 else:\r
681 FileStatementGuid = FfsObj.NameGuid\r
682 if FileStatementGuid in FileGuidList:\r
683 continue\r
684 else:\r
685 FileGuidList.append(FileStatementGuid)\r
686 Name = []\r
687 FfsPath = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
bc39c5cb 688 FfsPath = glob(os.path.join(FfsPath, FileStatementGuid) + TAB_STAR)\r
5e9256cd
YZ
689 if not FfsPath:\r
690 continue\r
691 if not os.path.exists(FfsPath[0]):\r
692 continue\r
693 MatchDict = {}\r
9e47e6f9 694 ReFileEnds = compile('\S+(.ui)$|\S+(fv.sec.txt)$|\S+(.pe32.txt)$|\S+(.te.txt)$|\S+(.pic.txt)$|\S+(.raw.txt)$|\S+(.ffs.txt)$')\r
5e9256cd
YZ
695 FileList = os.listdir(FfsPath[0])\r
696 for File in FileList:\r
697 Match = ReFileEnds.search(File)\r
698 if Match:\r
699 for Index in range(1, 8):\r
700 if Match.group(Index) and Match.group(Index) in MatchDict:\r
701 MatchDict[Match.group(Index)].append(File)\r
702 elif Match.group(Index):\r
703 MatchDict[Match.group(Index)] = [File]\r
704 if not MatchDict:\r
705 continue\r
706 if '.ui' in MatchDict:\r
707 for File in MatchDict['.ui']:\r
708 with open(os.path.join(FfsPath[0], File), 'rb') as F:\r
709 F.read()\r
710 length = F.tell()\r
711 F.seek(4)\r
1ccc4d89 712 TmpStr = unpack('%dh' % ((length - 4) / 2), F.read())\r
8252e6bf 713 Name = ''.join(chr(c) for c in TmpStr[:-1])\r
5e9256cd
YZ
714 else:\r
715 FileList = []\r
716 if 'fv.sec.txt' in MatchDict:\r
717 FileList = MatchDict['fv.sec.txt']\r
718 elif '.pe32.txt' in MatchDict:\r
719 FileList = MatchDict['.pe32.txt']\r
720 elif '.te.txt' in MatchDict:\r
721 FileList = MatchDict['.te.txt']\r
722 elif '.pic.txt' in MatchDict:\r
723 FileList = MatchDict['.pic.txt']\r
724 elif '.raw.txt' in MatchDict:\r
725 FileList = MatchDict['.raw.txt']\r
726 elif '.ffs.txt' in MatchDict:\r
727 FileList = MatchDict['.ffs.txt']\r
728 else:\r
729 pass\r
730 for File in FileList:\r
731 with open(os.path.join(FfsPath[0], File), 'r') as F:\r
732 Name.append((F.read().split()[-1]))\r
733 if not Name:\r
734 continue\r
735\r
0d1f5b2b 736 Name = ' '.join(Name) if isinstance(Name, type([])) else Name\r
5e9256cd
YZ
737 GuidXRefFile.write("%s %s\n" %(FileStatementGuid, Name))\r
738\r
e4ac870f
LG
739 # Append GUIDs, Protocols, and PPIs to the Xref file\r
740 GuidXRefFile.write("\n")\r
741 for key, item in GuidDict.items():\r
742 GuidXRefFile.write("%s %s\n" % (GuidStructureStringToGuidString(item).upper(), key))\r
743\r
f51461c8
LG
744 if GuidXRefFile.getvalue():\r
745 SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False)\r
746 GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)\r
747 elif os.path.exists(GuidXRefFileName):\r
748 os.remove(GuidXRefFileName)\r
749 GuidXRefFile.close()\r
750\r
b3497bad 751\r
f51461c8
LG
752if __name__ == '__main__':\r
753 r = main()\r
754 ## 0-127 is a safe return range, and 1 is a standard default error\r
9e47e6f9
CJ
755 if r < 0 or r > 127:\r
756 r = 1\r
757 exit(r)\r
f51461c8 758\r