]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/build/BuildReport.py
Sync BaseTools Branch (version r2321) to EDKII main trunk.
[mirror_edk2.git] / BaseTools / Source / Python / build / BuildReport.py
index af03e1f982d04291f4b94e6702dce847e30e47df..c6e49f9999683159eb53e1d00e11188f114869d3 100644 (file)
@@ -4,7 +4,7 @@
 # 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
@@ -23,6 +23,7 @@ import textwrap
 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
@@ -101,6 +102,9 @@ gDriverTypeMap = {
   '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
@@ -162,6 +166,60 @@ def FindIncludeFiles(Source, IncludePathList, IncludeFiles):
                 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
@@ -254,6 +312,7 @@ class DepexReport(object):
     #\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
@@ -289,14 +348,25 @@ class DepexReport(object):
     #\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
@@ -416,7 +486,7 @@ class ModuleReport(object):
             #\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
@@ -453,12 +523,14 @@ class ModuleReport(object):
     # 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
@@ -505,7 +577,7 @@ class ModuleReport(object):
             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
@@ -1184,7 +1256,7 @@ class FdRegionReport(object):
             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
@@ -1325,6 +1397,10 @@ class PlatformReport(object):
         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
@@ -1371,7 +1447,7 @@ class PlatformReport(object):
                     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