X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2Fbuild%2FBuildReport.py;h=c6e49f9999683159eb53e1d00e11188f114869d3;hb=b36d134faf4305247830522b8e2bb255e98c5699;hp=af03e1f982d04291f4b94e6702dce847e30e47df;hpb=40d841f6a8f84e75409178e19e69b95e01bada0f;p=mirror_edk2.git
diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py
index af03e1f982..c6e49f9999 100644
--- a/BaseTools/Source/Python/build/BuildReport.py
+++ b/BaseTools/Source/Python/build/BuildReport.py
@@ -4,7 +4,7 @@
# This module contains the functionality to generate build report after
# build all target completes successfully.
#
-# Copyright (c) 2010, Intel Corporation. All rights reserved.
+# Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
@@ -23,6 +23,7 @@ import textwrap
import traceback
import sys
import time
+import struct
from datetime import datetime
from StringIO import StringIO
from Common import EdkLogger
@@ -101,6 +102,9 @@ gDriverTypeMap = {
'SMM_DRIVER' : '0xA (SMM)', # Extension of module type to support PI 1.1 SMM drivers
}
+## The look up table of the supported opcode in the dependency expression binaries
+gOpCodeList = ["BEFORE", "AFTER", "PUSH", "AND", "OR", "NOT", "TRUE", "FALSE", "END", "SOR"]
+
##
# Writes a string to the file object.
#
@@ -162,6 +166,60 @@ def FindIncludeFiles(Source, IncludePathList, IncludeFiles):
IncludeFiles[FullFileName.lower().replace("\\", "/")] = FullFileName
break
+##
+# Parse binary dependency expression section
+#
+# This utility class parses the dependency expression section and translate the readable
+# GUID name and value.
+#
+class DepexParser(object):
+ ##
+ # Constructor function for class DepexParser
+ #
+ # This constructor function collect GUID values so that the readable
+ # GUID name can be translated.
+ #
+ # @param self The object pointer
+ # @param Wa Workspace context information
+ #
+ def __init__(self, Wa):
+ self._GuidDb = {}
+ for Package in Wa.BuildDatabase.WorkspaceDb.PackageList:
+ for Protocol in Package.Protocols:
+ GuidValue = GuidStructureStringToGuidString(Package.Protocols[Protocol])
+ self._GuidDb[GuidValue.upper()] = Protocol
+ for Ppi in Package.Ppis:
+ GuidValue = GuidStructureStringToGuidString(Package.Ppis[Ppi])
+ self._GuidDb[GuidValue.upper()] = Ppi
+ for Guid in Package.Guids:
+ GuidValue = GuidStructureStringToGuidString(Package.Guids[Guid])
+ self._GuidDb[GuidValue.upper()] = Guid
+
+ ##
+ # Parse the binary dependency expression files.
+ #
+ # This function parses the binary dependency expression file and translate it
+ # to the instruction list.
+ #
+ # @param self The object pointer
+ # @param DepexFileName The file name of binary dependency expression file.
+ #
+ def ParseDepexFile(self, DepexFileName):
+ DepexFile = open(DepexFileName, "rb")
+ DepexStatement = []
+ OpCode = DepexFile.read(1)
+ while OpCode:
+ Statement = gOpCodeList[struct.unpack("B", OpCode)[0]]
+ if Statement in ["BEFORE", "AFTER", "PUSH"]:
+ GuidValue = "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X" % \
+ struct.unpack("LHHBBBBBBBB", DepexFile.read(16))
+ GuidString = self._GuidDb.get(GuidValue, GuidValue)
+ Statement = "%s %s" % (Statement, GuidString)
+ DepexStatement.append(Statement)
+ OpCode = DepexFile.read(1)
+
+ return DepexStatement
+
##
# Reports library information
#
@@ -254,6 +312,7 @@ class DepexReport(object):
#
def __init__(self, M):
self.Depex = ""
+ self._DepexFileName = os.path.join(M.BuildDir, "OUTPUT", M.Module.BaseName + ".depex")
ModuleType = M.ModuleType
if not ModuleType:
ModuleType = gComponentType2ModuleType.get(M.ComponentType, "")
@@ -289,14 +348,25 @@ class DepexReport(object):
#
# This function generates report for the module dependency expression.
#
- # @param self The object pointer
- # @param File The file object for report
+ # @param self The object pointer
+ # @param File The file object for report
+ # @param GlobalDepexParser The platform global Dependency expression parser object
#
- def GenerateReport(self, File):
+ def GenerateReport(self, File, GlobalDepexParser):
if not self.Depex:
return
-
+
FileWrite(File, gSubSectionStart)
+ if os.path.isfile(self._DepexFileName):
+ try:
+ DepexStatements = GlobalDepexParser.ParseDepexFile(self._DepexFileName)
+ FileWrite(File, "Final Dependency Expression (DEPEX) Instructions")
+ for DepexStatement in DepexStatements:
+ FileWrite(File, " %s" % DepexStatement)
+ FileWrite(File, gSubSectionSep)
+ except:
+ EdkLogger.warn(None, "Dependency expression file is corrupted", self._DepexFileName)
+
FileWrite(File, "Dependency Expression (DEPEX) from %s" % self.Source)
if self.Source == "INF":
@@ -416,7 +486,7 @@ class ModuleReport(object):
#
if ModuleType == "DXE_SMM_DRIVER":
PiSpec = M.Module.Specification.get("PI_SPECIFICATION_VERSION", "0x00010000")
- if int(PiSpec, 0) >= 0x0001000A:
+ if int(PiSpec, 16) >= 0x0001000A:
ModuleType = "SMM_DRIVER"
self.DriverType = gDriverTypeMap.get(ModuleType, "0x2 (FREE_FORM)")
self.UefiSpecVersion = M.Module.Specification.get("UEFI_SPECIFICATION_VERSION", "")
@@ -453,12 +523,14 @@ class ModuleReport(object):
# This function generates report for separate module expression
# in a platform build.
#
- # @param self The object pointer
- # @param File The file object for report
- # @param GlobalPcdReport The platform global PCD class object
- # @param ReportType The kind of report items in the final report file
+ # @param self The object pointer
+ # @param File The file object for report
+ # @param GlobalPcdReport The platform global PCD report object
+ # @param GlobalPredictionReport The platform global Prediction report object
+ # @param GlobalDepexParser The platform global Dependency expression parser object
+ # @param ReportType The kind of report items in the final report file
#
- def GenerateReport(self, File, GlobalPcdReport, GlobalPredictionReport, ReportType):
+ def GenerateReport(self, File, GlobalPcdReport, GlobalPredictionReport, GlobalDepexParser, ReportType):
FileWrite(File, gSectionStart)
FwReportFileName = os.path.join(self._BuildDir, "DEBUG", self.ModuleName + ".txt")
@@ -505,7 +577,7 @@ class ModuleReport(object):
self.LibraryReport.GenerateReport(File)
if "DEPEX" in ReportType:
- self.DepexReport.GenerateReport(File)
+ self.DepexReport.GenerateReport(File, GlobalDepexParser)
if "BUILD_FLAGS" in ReportType:
self.BuildFlagsReport.GenerateReport(File)
@@ -1184,7 +1256,7 @@ class FdRegionReport(object):
FvTotalSize = 0
FvTakenSize = 0
FvFreeSize = 0
- FvReportFileName = os.path.join(self._FvDir, FvName + ".fv.txt")
+ FvReportFileName = os.path.join(self._FvDir, FvName + ".Fv.txt")
try:
#
# Collect size info in the firmware volume.
@@ -1325,6 +1397,10 @@ class PlatformReport(object):
if "FIXED_ADDRESS" in ReportType or "EXECUTION_ORDER" in ReportType:
self.PredictionReport = PredictionReport(Wa)
+ self.DepexParser = None
+ if "DEPEX" in ReportType:
+ self.DepexParser = DepexParser(Wa)
+
self.ModuleReportList = []
if MaList != None:
self._IsModuleBuild = True
@@ -1371,7 +1447,7 @@ class PlatformReport(object):
FdReportListItem.GenerateReport(File)
for ModuleReportItem in self.ModuleReportList:
- ModuleReportItem.GenerateReport(File, self.PcdReport, self.PredictionReport, ReportType)
+ ModuleReportItem.GenerateReport(File, self.PcdReport, self.PredictionReport, self.DepexParser, ReportType)
if not self._IsModuleBuild:
if "EXECUTION_ORDER" in ReportType: