# This module contains the functionality to generate build report after\r
# build all target completes successfully.\r
#\r
-# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.<BR>\r
# This program and the accompanying materials\r
# are licensed and made available under the terms and conditions of the BSD License\r
# which accompanies this distribution. The full text of the license may be found at\r
import traceback\r
import sys\r
import time\r
+import struct\r
from datetime import datetime\r
from StringIO import StringIO\r
from Common import EdkLogger\r
'SMM_DRIVER' : '0xA (SMM)', # Extension of module type to support PI 1.1 SMM drivers\r
}\r
\r
+## The look up table of the supported opcode in the dependency expression binaries\r
+gOpCodeList = ["BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "TRUE", "FALSE", "END", "SOR"]\r
+\r
##\r
# Writes a string to the file object.\r
#\r
IncludeFiles[FullFileName.lower().replace("\\", "/")] = FullFileName\r
break\r
\r
+##\r
+# Parse binary dependency expression section\r
+#\r
+# This utility class parses the dependency expression section and translate the readable\r
+# GUID name and value.\r
+#\r
+class DepexParser(object):\r
+ ##\r
+ # Constructor function for class DepexParser\r
+ #\r
+ # This constructor function collect GUID values so that the readable\r
+ # GUID name can be translated.\r
+ #\r
+ # @param self The object pointer\r
+ # @param Wa Workspace context information\r
+ #\r
+ def __init__(self, Wa):\r
+ self._GuidDb = {}\r
+ for Package in Wa.BuildDatabase.WorkspaceDb.PackageList:\r
+ for Protocol in Package.Protocols:\r
+ GuidValue = GuidStructureStringToGuidString(Package.Protocols[Protocol])\r
+ self._GuidDb[GuidValue.upper()] = Protocol\r
+ for Ppi in Package.Ppis:\r
+ GuidValue = GuidStructureStringToGuidString(Package.Ppis[Ppi])\r
+ self._GuidDb[GuidValue.upper()] = Ppi\r
+ for Guid in Package.Guids:\r
+ GuidValue = GuidStructureStringToGuidString(Package.Guids[Guid])\r
+ self._GuidDb[GuidValue.upper()] = Guid\r
+ \r
+ ##\r
+ # Parse the binary dependency expression files.\r
+ # \r
+ # This function parses the binary dependency expression file and translate it\r
+ # to the instruction list.\r
+ #\r
+ # @param self The object pointer\r
+ # @param DepexFileName The file name of binary dependency expression file.\r
+ #\r
+ def ParseDepexFile(self, DepexFileName):\r
+ DepexFile = open(DepexFileName, "rb")\r
+ DepexStatement = []\r
+ OpCode = DepexFile.read(1)\r
+ while OpCode:\r
+ Statement = gOpCodeList[struct.unpack("B", OpCode)[0]]\r
+ if Statement in ["BEFORE", "AFTER", "PUSH"]:\r
+ GuidValue = "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X" % \\r
+ struct.unpack("LHHBBBBBBBB", DepexFile.read(16))\r
+ GuidString = self._GuidDb.get(GuidValue, GuidValue)\r
+ Statement = "%s %s" % (Statement, GuidString)\r
+ DepexStatement.append(Statement)\r
+ OpCode = DepexFile.read(1) \r
+ \r
+ return DepexStatement\r
+ \r
##\r
# Reports library information\r
#\r
#\r
def __init__(self, M):\r
self.Depex = ""\r
+ self._DepexFileName = os.path.join(M.BuildDir, "OUTPUT", M.Module.BaseName + ".depex") \r
ModuleType = M.ModuleType\r
if not ModuleType:\r
ModuleType = gComponentType2ModuleType.get(M.ComponentType, "")\r
#\r
# This function generates report for the module dependency expression.\r
#\r
- # @param self The object pointer\r
- # @param File The file object for report\r
+ # @param self The object pointer\r
+ # @param File The file object for report\r
+ # @param GlobalDepexParser The platform global Dependency expression parser object\r
#\r
- def GenerateReport(self, File):\r
+ def GenerateReport(self, File, GlobalDepexParser):\r
if not self.Depex:\r
return\r
- \r
+\r
FileWrite(File, gSubSectionStart)\r
+ if os.path.isfile(self._DepexFileName):\r
+ try:\r
+ DepexStatements = GlobalDepexParser.ParseDepexFile(self._DepexFileName)\r
+ FileWrite(File, "Final Dependency Expression (DEPEX) Instructions")\r
+ for DepexStatement in DepexStatements:\r
+ FileWrite(File, " %s" % DepexStatement)\r
+ FileWrite(File, gSubSectionSep)\r
+ except:\r
+ EdkLogger.warn(None, "Dependency expression file is corrupted", self._DepexFileName)\r
+ \r
FileWrite(File, "Dependency Expression (DEPEX) from %s" % self.Source)\r
\r
if self.Source == "INF":\r
#\r
if ModuleType == "DXE_SMM_DRIVER":\r
PiSpec = M.Module.Specification.get("PI_SPECIFICATION_VERSION", "0x00010000")\r
- if int(PiSpec, 0) >= 0x0001000A:\r
+ if int(PiSpec, 16) >= 0x0001000A:\r
ModuleType = "SMM_DRIVER"\r
self.DriverType = gDriverTypeMap.get(ModuleType, "0x2 (FREE_FORM)")\r
self.UefiSpecVersion = M.Module.Specification.get("UEFI_SPECIFICATION_VERSION", "")\r
# This function generates report for separate module expression\r
# in a platform build.\r
#\r
- # @param self The object pointer\r
- # @param File The file object for report\r
- # @param GlobalPcdReport The platform global PCD class object\r
- # @param ReportType The kind of report items in the final report file\r
+ # @param self The object pointer\r
+ # @param File The file object for report\r
+ # @param GlobalPcdReport The platform global PCD report object\r
+ # @param GlobalPredictionReport The platform global Prediction report object\r
+ # @param GlobalDepexParser The platform global Dependency expression parser object\r
+ # @param ReportType The kind of report items in the final report file\r
#\r
- def GenerateReport(self, File, GlobalPcdReport, GlobalPredictionReport, ReportType):\r
+ def GenerateReport(self, File, GlobalPcdReport, GlobalPredictionReport, GlobalDepexParser, ReportType):\r
FileWrite(File, gSectionStart)\r
\r
FwReportFileName = os.path.join(self._BuildDir, "DEBUG", self.ModuleName + ".txt")\r
self.LibraryReport.GenerateReport(File)\r
\r
if "DEPEX" in ReportType:\r
- self.DepexReport.GenerateReport(File)\r
+ self.DepexReport.GenerateReport(File, GlobalDepexParser)\r
\r
if "BUILD_FLAGS" in ReportType:\r
self.BuildFlagsReport.GenerateReport(File)\r
FvTotalSize = 0\r
FvTakenSize = 0\r
FvFreeSize = 0\r
- FvReportFileName = os.path.join(self._FvDir, FvName + ".fv.txt")\r
+ FvReportFileName = os.path.join(self._FvDir, FvName + ".Fv.txt")\r
try:\r
#\r
# Collect size info in the firmware volume.\r
if "FIXED_ADDRESS" in ReportType or "EXECUTION_ORDER" in ReportType:\r
self.PredictionReport = PredictionReport(Wa)\r
\r
+ self.DepexParser = None\r
+ if "DEPEX" in ReportType:\r
+ self.DepexParser = DepexParser(Wa)\r
+ \r
self.ModuleReportList = []\r
if MaList != None:\r
self._IsModuleBuild = True\r
FdReportListItem.GenerateReport(File)\r
\r
for ModuleReportItem in self.ModuleReportList:\r
- ModuleReportItem.GenerateReport(File, self.PcdReport, self.PredictionReport, ReportType)\r
+ ModuleReportItem.GenerateReport(File, self.PcdReport, self.PredictionReport, self.DepexParser, ReportType)\r
\r
if not self._IsModuleBuild:\r
if "EXECUTION_ORDER" in ReportType:\r