]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/GenFds/GenFds.py
BaseTools: Replace the sqlite database with list
[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
2f818ed0 229\r
b3497bad
ZZ
230 if WorkSpaceDataBase:\r
231 BuildWorkSpace = WorkSpaceDataBase\r
232 else:\r
2f818ed0 233 BuildWorkSpace = WorkspaceDatabase()\r
f51461c8
LG
234 #\r
235 # Get files real name in workspace dir\r
236 #\r
237 GlobalData.gAllFiles = DirCache(Workspace)\r
238 GlobalData.gWorkspace = Workspace\r
239\r
b3497bad
ZZ
240 if FdsCommandDict.get("build_architecture_list"):\r
241 ArchList = FdsCommandDict.get("build_architecture_list").split(',')\r
f51461c8 242 else:\r
b3497bad 243 ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].SupArchList\r
f51461c8 244\r
b3497bad 245 TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].SupArchList) & set(ArchList)\r
f51461c8 246 if len(TargetArchList) == 0:\r
55c84777 247 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 248\r
f51461c8 249 for Arch in ArchList:\r
b3497bad 250 GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].OutputDirectory)\r
f51461c8 251\r
9e47e6f9 252 # assign platform name based on last entry in ArchList\r
b3497bad 253 GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, ArchList[-1], FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].PlatformName\r
9e47e6f9 254\r
b3497bad
ZZ
255 if FdsCommandDict.get("platform_build_directory"):\r
256 OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdsCommandDict.get("platform_build_directory"))\r
f51461c8
LG
257 if not os.path.isabs (OutputDirFromCommandLine):\r
258 OutputDirFromCommandLine = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, OutputDirFromCommandLine)\r
259 for Arch in ArchList:\r
260 GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine\r
261 else:\r
262 for Arch in ArchList:\r
263 GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag)\r
264\r
265 for Key in GenFdsGlobalVariable.OutputDirDict:\r
266 OutputDir = GenFdsGlobalVariable.OutputDirDict[Key]\r
267 if OutputDir[0:2] == '..':\r
268 OutputDir = os.path.realpath(OutputDir)\r
269\r
270 if OutputDir[1] != ':':\r
271 OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir)\r
272\r
273 if not os.path.exists(OutputDir):\r
274 EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=OutputDir)\r
275 GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir\r
276\r
277 """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """\r
b3497bad
ZZ
278 if WorkSpaceDataBase:\r
279 FdfParserObj = GlobalData.gFdfParser\r
280 else:\r
281 FdfParserObj = FdfParser(FdfFilename)\r
282 FdfParserObj.ParseFile()\r
f51461c8
LG
283\r
284 if FdfParserObj.CycleReferenceCheck():\r
285 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file")\r
286\r
b3497bad
ZZ
287 if FdsCommandDict.get("fd"):\r
288 if FdsCommandDict.get("fd")[0].upper() in FdfParserObj.Profile.FdDict:\r
289 GenFds.OnlyGenerateThisFd = FdsCommandDict.get("fd")[0]\r
f51461c8
LG
290 else:\r
291 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
b3497bad 292 "No such an FD in FDF file: %s" % FdsCommandDict.get("fd")[0])\r
f51461c8 293\r
b3497bad
ZZ
294 if FdsCommandDict.get("fv"):\r
295 if FdsCommandDict.get("fv")[0].upper() in FdfParserObj.Profile.FvDict:\r
296 GenFds.OnlyGenerateThisFv = FdsCommandDict.get("fv")[0]\r
f51461c8
LG
297 else:\r
298 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
b3497bad 299 "No such an FV in FDF file: %s" % FdsCommandDict.get("fv")[0])\r
f51461c8 300\r
b3497bad
ZZ
301 if FdsCommandDict.get("cap"):\r
302 if FdsCommandDict.get("cap")[0].upper() in FdfParserObj.Profile.CapsuleDict:\r
303 GenFds.OnlyGenerateThisCap = FdsCommandDict.get("cap")[0]\r
f51461c8
LG
304 else:\r
305 EdkLogger.error("GenFds", OPTION_VALUE_INVALID,\r
b3497bad 306 "No such a Capsule in FDF file: %s" % FdsCommandDict.get("cap")[0])\r
f51461c8 307\r
6b17c11b 308 GenFdsGlobalVariable.WorkSpace = BuildWorkSpace\r
9e47e6f9 309 if ArchList:\r
6b17c11b
YZ
310 GenFdsGlobalVariable.ArchList = ArchList\r
311\r
6f49996c 312 # Dsc Build Data will handle Pcd Settings from CommandLine.\r
6b17c11b 313\r
f51461c8
LG
314 """Modify images from build output if the feature of loading driver at fixed address is on."""\r
315 if GenFdsGlobalVariable.FixedLoadAddress:\r
316 GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform)\r
135ae8c8
YZ
317\r
318 # Record the FV Region info that may specific in the FD\r
319 if FdfParserObj.Profile.FvDict and FdfParserObj.Profile.FdDict:\r
9e47e6f9
CJ
320 for FvObj in FdfParserObj.Profile.FvDict.values():\r
321 for FdObj in FdfParserObj.Profile.FdDict.values():\r
135ae8c8 322 for RegionObj in FdObj.RegionList:\r
91fa33ee 323 if RegionObj.RegionType != BINARY_FILE_TYPE_FV:\r
135ae8c8
YZ
324 continue\r
325 for RegionData in RegionObj.RegionDataList:\r
326 if FvObj.UiFvName.upper() == RegionData.upper():\r
327 if FvObj.FvRegionInFD:\r
328 if FvObj.FvRegionInFD != RegionObj.Size:\r
329 EdkLogger.error("GenFds", FORMAT_INVALID, "The FV %s's region is specified in multiple FD with different value." %FvObj.UiFvName)\r
330 else:\r
331 FvObj.FvRegionInFD = RegionObj.Size\r
332 RegionObj.BlockInfoOfRegion(FdObj.BlockSizeList, FvObj)\r
333\r
f51461c8
LG
334 """Call GenFds"""\r
335 GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList)\r
336\r
337 """Generate GUID cross reference file"""\r
5e9256cd 338 GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList, FdfParserObj)\r
f51461c8
LG
339\r
340 """Display FV space info."""\r
341 GenFds.DisplayFvSpaceInfo(FdfParserObj)\r
342\r
9e47e6f9 343 except Warning as X:\r
47fea6af 344 EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False)\r
f51461c8 345 ReturnCode = FORMAT_INVALID\r
5b0671c1 346 except FatalError as X:\r
b3497bad 347 if FdsCommandDict.get("debug") is not None:\r
f51461c8
LG
348 import traceback\r
349 EdkLogger.quiet(traceback.format_exc())\r
350 ReturnCode = X.args[0]\r
351 except:\r
352 import traceback\r
353 EdkLogger.error(\r
354 "\nPython",\r
355 CODE_ERROR,\r
356 "Tools code failure",\r
3a0f8bde 357 ExtraData="Please send email to edk2-devel@lists.01.org for help, attaching following call stack trace!\n",\r
f51461c8
LG
358 RaiseError=False\r
359 )\r
360 EdkLogger.quiet(traceback.format_exc())\r
361 ReturnCode = CODE_ERROR\r
97fa0ee9
YL
362 finally:\r
363 ClearDuplicatedInf()\r
f51461c8
LG
364 return ReturnCode\r
365\r
b3497bad
ZZ
366def OptionsToCommandDict(Options):\r
367 FdsCommandDict = {}\r
368 FdsCommandDict["verbose"] = Options.verbose\r
369 FdsCommandDict["FixedAddress"] = Options.FixedAddress\r
370 FdsCommandDict["quiet"] = Options.quiet\r
371 FdsCommandDict["debug"] = Options.debug\r
372 FdsCommandDict["Workspace"] = Options.Workspace\r
373 FdsCommandDict["GenfdsMultiThread"] = Options.GenfdsMultiThread\r
374 FdsCommandDict["fdf_file"] = [PathClass(Options.filename)] if Options.filename else []\r
375 FdsCommandDict["build_target"] = Options.BuildTarget\r
376 FdsCommandDict["toolchain_tag"] = Options.ToolChain\r
377 FdsCommandDict["active_platform"] = Options.activePlatform\r
378 FdsCommandDict["OptionPcd"] = Options.OptionPcd\r
379 FdsCommandDict["conf_directory"] = Options.ConfDirectory\r
380 FdsCommandDict["IgnoreSources"] = Options.IgnoreSources\r
381 FdsCommandDict["macro"] = Options.Macros\r
382 FdsCommandDict["build_architecture_list"] = Options.archList\r
383 FdsCommandDict["platform_build_directory"] = Options.outputDir\r
384 FdsCommandDict["fd"] = [Options.uiFdName] if Options.uiFdName else []\r
385 FdsCommandDict["fv"] = [Options.uiFvName] if Options.uiFvName else []\r
386 FdsCommandDict["cap"] = [Options.uiCapName] if Options.uiCapName else []\r
387 return FdsCommandDict\r
388\r
389\r
f51461c8
LG
390gParamCheck = []\r
391def SingleCheckCallback(option, opt_str, value, parser):\r
392 if option not in gParamCheck:\r
393 setattr(parser.values, option.dest, value)\r
394 gParamCheck.append(option)\r
395 else:\r
396 parser.error("Option %s only allows one instance in command line!" % option)\r
6b17c11b 397\r
f51461c8
LG
398## Parse command line options\r
399#\r
400# Using standard Python module optparse to parse command line option of this tool.\r
401#\r
402# @retval Opt A optparse.Values object containing the parsed options\r
f51461c8
LG
403#\r
404def myOptionParser():\r
405 usage = "%prog [options] -f input_file -a arch_list -b build_target -p active_platform -t tool_chain_tag -D \"MacroName [= MacroValue]\""\r
47fea6af 406 Parser = OptionParser(usage=usage, description=__copyright__, version="%prog " + str(versionNumber))\r
f51461c8
LG
407 Parser.add_option("-f", "--file", dest="filename", type="string", help="Name of FDF file to convert", action="callback", callback=SingleCheckCallback)\r
408 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
409 Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
410 Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed.")\r
411 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
412 Parser.add_option("-p", "--platform", type="string", dest="activePlatform", help="Set the ACTIVE_PLATFORM, overrides target.txt ACTIVE_PLATFORM setting.",\r
413 action="callback", callback=SingleCheckCallback)\r
414 Parser.add_option("-w", "--workspace", type="string", dest="Workspace", default=os.environ.get('WORKSPACE'), help="Set the WORKSPACE",\r
415 action="callback", callback=SingleCheckCallback)\r
416 Parser.add_option("-o", "--outputDir", type="string", dest="outputDir", help="Name of Build Output directory",\r
417 action="callback", callback=SingleCheckCallback)\r
418 Parser.add_option("-r", "--rom_image", dest="uiFdName", help="Build the image using the [FD] section named by FdUiName.")\r
419 Parser.add_option("-i", "--FvImage", dest="uiFvName", help="Build the FV image using the [FV] section named by UiFvName")\r
420 Parser.add_option("-C", "--CapsuleImage", dest="uiCapName", help="Build the Capsule image using the [Capsule] section named by UiCapName")\r
421 Parser.add_option("-b", "--buildtarget", type="string", dest="BuildTarget", help="Set the build TARGET, overrides target.txt TARGET setting.",\r
422 action="callback", callback=SingleCheckCallback)\r
423 Parser.add_option("-t", "--tagname", type="string", dest="ToolChain", help="Using the tools: TOOL_CHAIN_TAG name to build the platform.",\r
424 action="callback", callback=SingleCheckCallback)\r
425 Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")\r
426 Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")\r
97fa0ee9
YL
427 Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")\r
428 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 429 Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: \"PcdName=Value\" ")\r
37de70b7 430 Parser.add_option("--genfds-multi-thread", action="store_true", dest="GenfdsMultiThread", default=False, help="Enable GenFds multi thread to generate ffs file.")\r
97fa0ee9 431\r
9e47e6f9 432 Options, _ = Parser.parse_args()\r
f51461c8
LG
433 return Options\r
434\r
435## The class implementing the EDK2 flash image generation process\r
436#\r
437# This process includes:\r
438# 1. Collect workspace information, includes platform and module information\r
439# 2. Call methods of Fd class to generate FD\r
440# 3. Call methods of Fv class to generate FV that not belong to FD\r
441#\r
9e47e6f9 442class GenFds(object):\r
f51461c8 443 FdfParsef = None\r
f51461c8
LG
444 OnlyGenerateThisFd = None\r
445 OnlyGenerateThisFv = None\r
446 OnlyGenerateThisCap = None\r
447\r
448 ## GenFd()\r
449 #\r
450 # @param OutputDir Output directory\r
9e47e6f9 451 # @param FdfParserObject FDF contents parser\r
f51461c8
LG
452 # @param Workspace The directory of workspace\r
453 # @param ArchList The Arch list of platform\r
454 #\r
9e47e6f9
CJ
455 @staticmethod\r
456 def GenFd (OutputDir, FdfParserObject, WorkSpace, ArchList):\r
457 GenFdsGlobalVariable.SetDir ('', FdfParserObject, WorkSpace, ArchList)\r
f51461c8
LG
458\r
459 GenFdsGlobalVariable.VerboseLogger(" Generate all Fd images and their required FV and Capsule images!")\r
9eb87141
CJ
460 if GenFds.OnlyGenerateThisCap is not None and GenFds.OnlyGenerateThisCap.upper() in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict:\r
461 CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[GenFds.OnlyGenerateThisCap.upper()]\r
4231a819 462 if CapsuleObj is not None:\r
f51461c8
LG
463 CapsuleObj.GenCapsule()\r
464 return\r
465\r
9eb87141
CJ
466 if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict:\r
467 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
4231a819 468 if FdObj is not None:\r
f51461c8
LG
469 FdObj.GenFd()\r
470 return\r
4231a819 471 elif GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisFv is None:\r
9eb87141 472 for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
f51461c8
LG
473 FdObj.GenFd()\r
474\r
475 GenFdsGlobalVariable.VerboseLogger("\n Generate other FV images! ")\r
9eb87141
CJ
476 if GenFds.OnlyGenerateThisFv is not None and GenFds.OnlyGenerateThisFv.upper() in GenFdsGlobalVariable.FdfParser.Profile.FvDict:\r
477 FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[GenFds.OnlyGenerateThisFv.upper()]\r
4231a819 478 if FvObj is not None:\r
86379ac4 479 Buffer = BytesIO()\r
f51461c8
LG
480 FvObj.AddToBuffer(Buffer)\r
481 Buffer.close()\r
482 return\r
4231a819 483 elif GenFds.OnlyGenerateThisFv is None:\r
9eb87141 484 for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict.values():\r
1ccc4d89 485 Buffer = BytesIO('')\r
f51461c8
LG
486 FvObj.AddToBuffer(Buffer)\r
487 Buffer.close()\r
f7496d71 488\r
4231a819 489 if GenFds.OnlyGenerateThisFv is None and GenFds.OnlyGenerateThisFd is None and GenFds.OnlyGenerateThisCap is None:\r
f51461c8
LG
490 if GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict != {}:\r
491 GenFdsGlobalVariable.VerboseLogger("\n Generate other Capsule images!")\r
9eb87141 492 for CapsuleObj in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.values():\r
f51461c8
LG
493 CapsuleObj.GenCapsule()\r
494\r
495 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
496 GenFdsGlobalVariable.VerboseLogger("\n Generate all Option ROM!")\r
9eb87141 497 for OptRomObj in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.values():\r
f51461c8 498 OptRomObj.AddToBuffer(None)\r
9e47e6f9 499\r
37de70b7 500 @staticmethod\r
9e47e6f9
CJ
501 def GenFfsMakefile(OutputDir, FdfParserObject, WorkSpace, ArchList, GlobalData):\r
502 GenFdsGlobalVariable.SetEnv(FdfParserObject, WorkSpace, ArchList, GlobalData)\r
9eb87141 503 for FdObj in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
37de70b7
YZ
504 FdObj.GenFd(Flag=True)\r
505\r
9eb87141 506 for FvObj in GenFdsGlobalVariable.FdfParser.Profile.FvDict.values():\r
37de70b7
YZ
507 FvObj.AddToBuffer(Buffer=None, Flag=True)\r
508\r
509 if GenFdsGlobalVariable.FdfParser.Profile.OptRomDict != {}:\r
9eb87141 510 for OptRomObj in GenFdsGlobalVariable.FdfParser.Profile.OptRomDict.values():\r
37de70b7
YZ
511 OptRomObj.AddToBuffer(Buffer=None, Flag=True)\r
512\r
513 return GenFdsGlobalVariable.FfsCmdDict\r
f51461c8
LG
514\r
515 ## GetFvBlockSize()\r
516 #\r
517 # @param FvObj Whose block size to get\r
518 # @retval int Block size value\r
519 #\r
9e47e6f9 520 @staticmethod\r
f51461c8
LG
521 def GetFvBlockSize(FvObj):\r
522 DefaultBlockSize = 0x1\r
523 FdObj = None\r
9eb87141 524 if GenFds.OnlyGenerateThisFd is not None and GenFds.OnlyGenerateThisFd.upper() in GenFdsGlobalVariable.FdfParser.Profile.FdDict:\r
f51461c8 525 FdObj = GenFdsGlobalVariable.FdfParser.Profile.FdDict[GenFds.OnlyGenerateThisFd.upper()]\r
4231a819 526 if FdObj is None:\r
f51461c8
LG
527 for ElementFd in GenFdsGlobalVariable.FdfParser.Profile.FdDict.values():\r
528 for ElementRegion in ElementFd.RegionList:\r
91fa33ee 529 if ElementRegion.RegionType == BINARY_FILE_TYPE_FV:\r
f51461c8 530 for ElementRegionData in ElementRegion.RegionDataList:\r
4231a819 531 if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:\r
f51461c8
LG
532 if FvObj.BlockSizeList != []:\r
533 return FvObj.BlockSizeList[0][0]\r
534 else:\r
535 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
536 if FvObj.BlockSizeList != []:\r
537 return FvObj.BlockSizeList[0][0]\r
538 return DefaultBlockSize\r
539 else:\r
540 for ElementRegion in FdObj.RegionList:\r
91fa33ee 541 if ElementRegion.RegionType == BINARY_FILE_TYPE_FV:\r
f51461c8 542 for ElementRegionData in ElementRegion.RegionDataList:\r
4231a819 543 if ElementRegionData is not None and ElementRegionData.upper() == FvObj.UiFvName:\r
f51461c8
LG
544 if FvObj.BlockSizeList != []:\r
545 return FvObj.BlockSizeList[0][0]\r
546 else:\r
547 return ElementRegion.BlockSizeOfRegion(ElementFd.BlockSizeList)\r
548 return DefaultBlockSize\r
549\r
550 ## DisplayFvSpaceInfo()\r
551 #\r
552 # @param FvObj Whose block size to get\r
553 # @retval None\r
554 #\r
9e47e6f9
CJ
555 @staticmethod\r
556 def DisplayFvSpaceInfo(FdfParserObject):\r
f7496d71 557\r
f51461c8
LG
558 FvSpaceInfoList = []\r
559 MaxFvNameLength = 0\r
9e47e6f9 560 for FvName in FdfParserObject.Profile.FvDict:\r
f51461c8
LG
561 if len(FvName) > MaxFvNameLength:\r
562 MaxFvNameLength = len(FvName)\r
563 FvSpaceInfoFileName = os.path.join(GenFdsGlobalVariable.FvDir, FvName.upper() + '.Fv.map')\r
564 if os.path.exists(FvSpaceInfoFileName):\r
9e47e6f9 565 FileLinesList = getlines(FvSpaceInfoFileName)\r
f51461c8
LG
566 TotalFound = False\r
567 Total = ''\r
568 UsedFound = False\r
569 Used = ''\r
570 FreeFound = False\r
571 Free = ''\r
572 for Line in FileLinesList:\r
573 NameValue = Line.split('=')\r
574 if len(NameValue) == 2:\r
575 if NameValue[0].strip() == 'EFI_FV_TOTAL_SIZE':\r
576 TotalFound = True\r
577 Total = NameValue[1].strip()\r
578 if NameValue[0].strip() == 'EFI_FV_TAKEN_SIZE':\r
579 UsedFound = True\r
580 Used = NameValue[1].strip()\r
581 if NameValue[0].strip() == 'EFI_FV_SPACE_SIZE':\r
582 FreeFound = True\r
583 Free = NameValue[1].strip()\r
f7496d71 584\r
f51461c8
LG
585 if TotalFound and UsedFound and FreeFound:\r
586 FvSpaceInfoList.append((FvName, Total, Used, Free))\r
f7496d71 587\r
f51461c8
LG
588 GenFdsGlobalVariable.InfLogger('\nFV Space Information')\r
589 for FvSpaceInfo in FvSpaceInfoList:\r
590 Name = FvSpaceInfo[0]\r
1ccc4d89
LG
591 TotalSizeValue = long(FvSpaceInfo[1], 0)\r
592 UsedSizeValue = long(FvSpaceInfo[2], 0)\r
593 FreeSizeValue = long(FvSpaceInfo[3], 0)\r
f51461c8
LG
594 if UsedSizeValue == TotalSizeValue:\r
595 Percentage = '100'\r
596 else:\r
47fea6af
YZ
597 Percentage = str((UsedSizeValue + 0.0) / TotalSizeValue)[0:4].lstrip('0.')\r
598\r
f51461c8
LG
599 GenFdsGlobalVariable.InfLogger(Name + ' ' + '[' + Percentage + '%Full] ' + str(TotalSizeValue) + ' total, ' + str(UsedSizeValue) + ' used, ' + str(FreeSizeValue) + ' free')\r
600\r
601 ## PreprocessImage()\r
602 #\r
603 # @param BuildDb Database from build meta data files\r
604 # @param DscFile modules from dsc file will be preprocessed\r
605 # @retval None\r
606 #\r
9e47e6f9 607 @staticmethod\r
f51461c8 608 def PreprocessImage(BuildDb, DscFile):\r
55c84777 609 PcdDict = BuildDb.BuildObject[DscFile, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Pcds\r
f51461c8
LG
610 PcdValue = ''\r
611 for Key in PcdDict:\r
612 PcdObj = PcdDict[Key]\r
613 if PcdObj.TokenCName == 'PcdBsBaseAddress':\r
614 PcdValue = PcdObj.DefaultValue\r
615 break\r
f7496d71 616\r
f51461c8
LG
617 if PcdValue == '':\r
618 return\r
f7496d71 619\r
1ccc4d89 620 Int64PcdValue = long(PcdValue, 0)\r
f7496d71 621 if Int64PcdValue == 0 or Int64PcdValue < -1:\r
f51461c8 622 return\r
f7496d71 623\r
f51461c8
LG
624 TopAddress = 0\r
625 if Int64PcdValue > 0:\r
626 TopAddress = Int64PcdValue\r
f7496d71 627\r
55c84777 628 ModuleDict = BuildDb.BuildObject[DscFile, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].Modules\r
f51461c8 629 for Key in ModuleDict:\r
55c84777 630 ModuleObj = BuildDb.BuildObject[Key, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
72443dd2 631 print(ModuleObj.BaseName + ' ' + ModuleObj.ModuleType)\r
f51461c8 632\r
9e47e6f9 633 @staticmethod\r
5e9256cd 634 def GenerateGuidXRefFile(BuildDb, ArchList, FdfParserObj):\r
f51461c8 635 GuidXRefFileName = os.path.join(GenFdsGlobalVariable.FvDir, "Guid.xref")\r
1ccc4d89 636 GuidXRefFile = BytesIO('')\r
0fece18d 637 PkgGuidDict = {}\r
e4ac870f 638 GuidDict = {}\r
5e9256cd
YZ
639 ModuleList = []\r
640 FileGuidList = []\r
f51461c8
LG
641 for Arch in ArchList:\r
642 PlatformDataBase = BuildDb.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
0fece18d 643 PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag)\r
644 for P in PkgList:\r
645 PkgGuidDict.update(P.Guids)\r
1ccc4d89 646 for Name, Guid in PlatformDataBase.Pcds:\r
0fece18d 647 Pcd = PlatformDataBase.Pcds[Name, Guid]\r
648 if Pcd.Type in [TAB_PCDS_DYNAMIC_HII, TAB_PCDS_DYNAMIC_EX_HII]:\r
649 for SkuId in Pcd.SkuInfoList:\r
650 Sku = Pcd.SkuInfoList[SkuId]\r
651 if Sku.VariableGuid and Sku.VariableGuid in PkgGuidDict.keys():\r
652 GuidDict[Sku.VariableGuid] = PkgGuidDict[Sku.VariableGuid]\r
f51461c8
LG
653 for ModuleFile in PlatformDataBase.Modules:\r
654 Module = BuildDb.BuildObject[ModuleFile, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
5e9256cd
YZ
655 if Module in ModuleList:\r
656 continue\r
657 else:\r
658 ModuleList.append(Module)\r
9e47e6f9 659 if GlobalData.gGuidPattern.match(ModuleFile.BaseName):\r
1d802e23
YF
660 GuidXRefFile.write("%s %s\n" % (ModuleFile.BaseName, Module.BaseName))\r
661 else:\r
662 GuidXRefFile.write("%s %s\n" % (Module.Guid, Module.BaseName))\r
9e47e6f9
CJ
663 GuidDict.update(Module.Protocols)\r
664 GuidDict.update(Module.Guids)\r
665 GuidDict.update(Module.Ppis)\r
5e9256cd
YZ
666 for FvName in FdfParserObj.Profile.FvDict:\r
667 for FfsObj in FdfParserObj.Profile.FvDict[FvName].FfsList:\r
9e47e6f9 668 if not isinstance(FfsObj, FileStatement):\r
5e9256cd
YZ
669 InfPath = PathClass(NormPath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, FfsObj.InfFileName)))\r
670 FdfModule = BuildDb.BuildObject[InfPath, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
671 if FdfModule in ModuleList:\r
672 continue\r
673 else:\r
674 ModuleList.append(FdfModule)\r
675 GuidXRefFile.write("%s %s\n" % (FdfModule.Guid, FdfModule.BaseName))\r
9e47e6f9
CJ
676 GuidDict.update(FdfModule.Protocols)\r
677 GuidDict.update(FdfModule.Guids)\r
678 GuidDict.update(FdfModule.Ppis)\r
5e9256cd
YZ
679 else:\r
680 FileStatementGuid = FfsObj.NameGuid\r
681 if FileStatementGuid in FileGuidList:\r
682 continue\r
683 else:\r
684 FileGuidList.append(FileStatementGuid)\r
685 Name = []\r
686 FfsPath = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')\r
bc39c5cb 687 FfsPath = glob(os.path.join(FfsPath, FileStatementGuid) + TAB_STAR)\r
5e9256cd
YZ
688 if not FfsPath:\r
689 continue\r
690 if not os.path.exists(FfsPath[0]):\r
691 continue\r
692 MatchDict = {}\r
9e47e6f9 693 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
694 FileList = os.listdir(FfsPath[0])\r
695 for File in FileList:\r
696 Match = ReFileEnds.search(File)\r
697 if Match:\r
698 for Index in range(1, 8):\r
699 if Match.group(Index) and Match.group(Index) in MatchDict:\r
700 MatchDict[Match.group(Index)].append(File)\r
701 elif Match.group(Index):\r
702 MatchDict[Match.group(Index)] = [File]\r
703 if not MatchDict:\r
704 continue\r
705 if '.ui' in MatchDict:\r
706 for File in MatchDict['.ui']:\r
707 with open(os.path.join(FfsPath[0], File), 'rb') as F:\r
708 F.read()\r
709 length = F.tell()\r
710 F.seek(4)\r
1ccc4d89 711 TmpStr = unpack('%dh' % ((length - 4) / 2), F.read())\r
8252e6bf 712 Name = ''.join(chr(c) for c in TmpStr[:-1])\r
5e9256cd
YZ
713 else:\r
714 FileList = []\r
715 if 'fv.sec.txt' in MatchDict:\r
716 FileList = MatchDict['fv.sec.txt']\r
717 elif '.pe32.txt' in MatchDict:\r
718 FileList = MatchDict['.pe32.txt']\r
719 elif '.te.txt' in MatchDict:\r
720 FileList = MatchDict['.te.txt']\r
721 elif '.pic.txt' in MatchDict:\r
722 FileList = MatchDict['.pic.txt']\r
723 elif '.raw.txt' in MatchDict:\r
724 FileList = MatchDict['.raw.txt']\r
725 elif '.ffs.txt' in MatchDict:\r
726 FileList = MatchDict['.ffs.txt']\r
727 else:\r
728 pass\r
729 for File in FileList:\r
730 with open(os.path.join(FfsPath[0], File), 'r') as F:\r
731 Name.append((F.read().split()[-1]))\r
732 if not Name:\r
733 continue\r
734\r
0d1f5b2b 735 Name = ' '.join(Name) if isinstance(Name, type([])) else Name\r
5e9256cd
YZ
736 GuidXRefFile.write("%s %s\n" %(FileStatementGuid, Name))\r
737\r
e4ac870f
LG
738 # Append GUIDs, Protocols, and PPIs to the Xref file\r
739 GuidXRefFile.write("\n")\r
740 for key, item in GuidDict.items():\r
741 GuidXRefFile.write("%s %s\n" % (GuidStructureStringToGuidString(item).upper(), key))\r
742\r
f51461c8
LG
743 if GuidXRefFile.getvalue():\r
744 SaveFileOnChange(GuidXRefFileName, GuidXRefFile.getvalue(), False)\r
745 GenFdsGlobalVariable.InfLogger("\nGUID cross reference file can be found at %s" % GuidXRefFileName)\r
746 elif os.path.exists(GuidXRefFileName):\r
747 os.remove(GuidXRefFileName)\r
748 GuidXRefFile.close()\r
749\r
b3497bad 750\r
f51461c8
LG
751if __name__ == '__main__':\r
752 r = main()\r
753 ## 0-127 is a safe return range, and 1 is a standard default error\r
9e47e6f9
CJ
754 if r < 0 or r > 127:\r
755 r = 1\r
756 exit(r)\r
f51461c8 757\r