## @file
# Routines for generating build report.
#
# This module contains the functionality to generate build report after
# build all target completes successfully.
#
# Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
# 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
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#

## Import Modules
#
import Common.LongFilePathOs as os
import re
import platform
import textwrap
import traceback
import sys
import time
import struct
import hashlib
import subprocess
import threading
from datetime import datetime
from StringIO import StringIO
from Common import EdkLogger
from Common.Misc import SaveFileOnChange
from Common.Misc import GuidStructureByteArrayToGuidString
from Common.Misc import GuidStructureStringToGuidString
from Common.InfClassObject import gComponentType2ModuleType
from Common.BuildToolError import FILE_WRITE_FAILURE
from Common.BuildToolError import CODE_ERROR
from Common.BuildToolError import COMMAND_FAILURE
from Common.DataType import TAB_LINE_BREAK
from Common.DataType import TAB_DEPEX
from Common.DataType import TAB_SLASH
from Common.DataType import TAB_SPACE_SPLIT
from Common.DataType import TAB_BRG_PCD
from Common.DataType import TAB_BRG_LIBRARY
from Common.DataType import TAB_BACK_SLASH
from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
import Common.GlobalData as GlobalData

## Pattern to extract contents in EDK DXS files
gDxsDependencyPattern = re.compile(r"DEPENDENCY_START(.+)DEPENDENCY_END", re.DOTALL)

## Pattern to find total FV total size, occupied size in flash report intermediate file
gFvTotalSizePattern = re.compile(r"EFI_FV_TOTAL_SIZE = (0x[0-9a-fA-F]+)")
gFvTakenSizePattern = re.compile(r"EFI_FV_TAKEN_SIZE = (0x[0-9a-fA-F]+)")

## Pattern to find module size and time stamp in module summary report intermediate file
gModuleSizePattern = re.compile(r"MODULE_SIZE = (\d+)")
gTimeStampPattern  = re.compile(r"TIME_STAMP = (\d+)")

## Pattern to find GUID value in flash description files
gPcdGuidPattern = re.compile(r"PCD\((\w+)[.](\w+)\)")

## Pattern to collect offset, GUID value pair in the flash report intermediate file
gOffsetGuidPattern = re.compile(r"(0x[0-9A-Fa-f]+) ([-A-Fa-f0-9]+)")

## Pattern to find module base address and entry point in fixed flash map file
gModulePattern = r"\n[-\w]+\s*\(([^,]+),\s*BaseAddress=%(Address)s,\s*EntryPoint=%(Address)s\)\s*\(GUID=([-0-9A-Fa-f]+)[^)]*\)"
gMapFileItemPattern = re.compile(gModulePattern % {"Address" : "(-?0[xX][0-9A-Fa-f]+)"})

## Pattern to find all module referenced header files in source files
gIncludePattern  = re.compile(r'#include\s*["<]([^">]+)[">]')
gIncludePattern2 = re.compile(r"#include\s+EFI_([A-Z_]+)\s*[(]\s*(\w+)\s*[)]")

## Pattern to find the entry point for EDK module using EDKII Glue library
gGlueLibEntryPoint = re.compile(r"__EDKII_GLUE_MODULE_ENTRY_POINT__\s*=\s*(\w+)")

## Tags for MaxLength of line in report
gLineMaxLength = 120

## Tags for end of line in report
gEndOfLine = "\r\n"

## Tags for section start, end and separator
gSectionStart = ">" + "=" * (gLineMaxLength - 2) + "<"
gSectionEnd = "<" + "=" * (gLineMaxLength - 2) + ">" + "\n"
gSectionSep = "=" * gLineMaxLength

## Tags for subsection start, end and separator
gSubSectionStart = ">" + "-" * (gLineMaxLength - 2) + "<"
gSubSectionEnd = "<" + "-" * (gLineMaxLength - 2) + ">"
gSubSectionSep = "-" * gLineMaxLength


## The look up table to map PCD type to pair of report display type and DEC type
gPcdTypeMap = {
  'FixedAtBuild'     : ('FIXED',  'FixedAtBuild'),
  'PatchableInModule': ('PATCH',  'PatchableInModule'),
  'FeatureFlag'      : ('FLAG',   'FeatureFlag'),
  'Dynamic'          : ('DYN',    'Dynamic'),
  'DynamicHii'       : ('DYNHII', 'Dynamic'),
  'DynamicVpd'       : ('DYNVPD', 'Dynamic'),
  'DynamicEx'        : ('DEX',    'DynamicEx'),
  'DynamicExHii'     : ('DEXHII', 'DynamicEx'),
  'DynamicExVpd'     : ('DEXVPD', 'DynamicEx'),
  }

## The look up table to map module type to driver type
gDriverTypeMap = {
  'SEC'               : '0x3 (SECURITY_CORE)',
  'PEI_CORE'          : '0x4 (PEI_CORE)',
  'PEIM'              : '0x6 (PEIM)',
  'DXE_CORE'          : '0x5 (DXE_CORE)',
  'DXE_DRIVER'        : '0x7 (DRIVER)',
  'DXE_SAL_DRIVER'    : '0x7 (DRIVER)',
  'DXE_SMM_DRIVER'    : '0x7 (DRIVER)',
  'DXE_RUNTIME_DRIVER': '0x7 (DRIVER)',
  'UEFI_DRIVER'       : '0x7 (DRIVER)',
  'UEFI_APPLICATION'  : '0x9 (APPLICATION)',
  'SMM_CORE'          : '0xD (SMM_CORE)',
  '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.
#
# This function writes a string to the file object and a new line is appended
# afterwards. It may optionally wraps the string for better readability.
#
# @File                      The file object to write
# @String                    The string to be written to the file
# @Wrapper                   Indicates whether to wrap the string
#
def FileWrite(File, String, Wrapper=False):
    if Wrapper:
        String = textwrap.fill(String, 120)
    File.write(String + gEndOfLine)

##
# Find all the header file that the module source directly includes.
#
# This function scans source code to find all header files the module may
# include. This is not accurate but very effective to find all the header
# file the module might include with #include statement.
#
# @Source                    The source file name
# @IncludePathList           The list of include path to find the source file.
# @IncludeFiles              The dictionary of current found include files.
#
def FindIncludeFiles(Source, IncludePathList, IncludeFiles):
    FileContents = open(Source).read()
    #
    # Find header files with pattern #include "XXX.h" or #include <XXX.h>
    #
    for Match in gIncludePattern.finditer(FileContents):
        FileName = Match.group(1).strip()
        for Dir in [os.path.dirname(Source)] + IncludePathList:
            FullFileName = os.path.normpath(os.path.join(Dir, FileName))
            if os.path.exists(FullFileName):
                IncludeFiles[FullFileName.lower().replace("\\", "/")] = FullFileName
                break

    #
    # Find header files with pattern like #include EFI_PPI_CONSUMER(XXX)
    #
    for Match in gIncludePattern2.finditer(FileContents):
        Key = Match.group(2)
        Type = Match.group(1)
        if "ARCH_PROTOCOL" in Type:
            FileName = "ArchProtocol/%(Key)s/%(Key)s.h" % {"Key" : Key}
        elif "PROTOCOL" in Type:
            FileName = "Protocol/%(Key)s/%(Key)s.h" % {"Key" : Key}
        elif "PPI" in Type:
            FileName = "Ppi/%(Key)s/%(Key)s.h" % {"Key" : Key}
        elif "GUID" in Type:
            FileName = "Guid/%(Key)s/%(Key)s.h" % {"Key" : Key}
        else:
            continue
        for Dir in IncludePathList:
            FullFileName = os.path.normpath(os.path.join(Dir, FileName))
            if os.path.exists(FullFileName):
                IncludeFiles[FullFileName.lower().replace("\\", "/")] = FullFileName
                break

## Split each lines in file
#
#  This method is used to split the lines in file to make the length of each line 
#  less than MaxLength.
#
#  @param      Content           The content of file
#  @param      MaxLength         The Max Length of the line
#
def FileLinesSplit(Content=None, MaxLength=None):
    ContentList = Content.split(TAB_LINE_BREAK)
    NewContent = ''
    NewContentList = []
    for Line in ContentList:
        while len(Line.rstrip()) > MaxLength:
            LineSpaceIndex = Line.rfind(TAB_SPACE_SPLIT, 0, MaxLength)
            LineSlashIndex = Line.rfind(TAB_SLASH, 0, MaxLength)
            LineBackSlashIndex = Line.rfind(TAB_BACK_SLASH, 0, MaxLength)
            if max(LineSpaceIndex, LineSlashIndex, LineBackSlashIndex) > 0:
                LineBreakIndex = max(LineSpaceIndex, LineSlashIndex, LineBackSlashIndex)
            else:
                LineBreakIndex = MaxLength
            NewContentList.append(Line[:LineBreakIndex])
            Line = Line[LineBreakIndex:]
        if Line:
            NewContentList.append(Line)
    for NewLine in NewContentList:
        NewContent += NewLine + TAB_LINE_BREAK
    
    NewContent = NewContent.replace(TAB_LINE_BREAK, gEndOfLine).replace('\r\r\n', gEndOfLine)
    return NewContent
    
    
    
##
# 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 Pa in Wa.AutoGenObjectList:
            for Package in Pa.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
#
# This class reports the module library subsection in the build report file.
#
class LibraryReport(object):
    ##
    # Constructor function for class LibraryReport
    #
    # This constructor function generates LibraryReport object for
    # a module.
    #
    # @param self            The object pointer
    # @param M               Module context information
    #
    def __init__(self, M):
        self.LibraryList = []
        if int(str(M.AutoGenVersion), 0) >= 0x00010005:
            self._EdkIIModule = True
        else:
            self._EdkIIModule = False

        for Lib in M.DependentLibraryList:
            LibInfPath = str(Lib)
            LibClassList = Lib.LibraryClass[0].LibraryClass
            LibConstructorList = Lib.ConstructorList
            LibDesstructorList = Lib.DestructorList
            LibDepexList = Lib.DepexExpression[M.Arch, M.ModuleType]
            self.LibraryList.append((LibInfPath, LibClassList, LibConstructorList, LibDesstructorList, LibDepexList))

    ##
    # Generate report for module library information
    #
    # This function generates report for the module library.
    # If the module is EDKII style one, the additional library class, library
    # constructor/destructor and dependency expression may also be reported.
    #
    # @param self            The object pointer
    # @param File            The file object for report
    #
    def GenerateReport(self, File):
        FileWrite(File, gSubSectionStart)
        FileWrite(File, TAB_BRG_LIBRARY)
        if len(self.LibraryList) > 0:
            FileWrite(File, gSubSectionSep)
            for LibraryItem in self.LibraryList:
                LibInfPath = LibraryItem[0]
                FileWrite(File, LibInfPath)

                #
                # Report library class, library constructor and destructor for
                # EDKII style module.
                #
                if self._EdkIIModule:
                    LibClass = LibraryItem[1]
                    EdkIILibInfo = ""
                    LibConstructor = " ".join(LibraryItem[2])
                    if LibConstructor:
                        EdkIILibInfo += " C = " + LibConstructor
                    LibDestructor = " ".join(LibraryItem[3])
                    if LibDestructor:
                        EdkIILibInfo += " D = " + LibDestructor
                    LibDepex = " ".join(LibraryItem[4])
                    if LibDepex:
                        EdkIILibInfo += " Depex = " + LibDepex
                    if EdkIILibInfo:
                        FileWrite(File, "{%s: %s}" % (LibClass, EdkIILibInfo))
                    else:
                        FileWrite(File, "{%s}" % LibClass)

        FileWrite(File, gSubSectionEnd)

##
# Reports dependency expression information
#
# This class reports the module dependency expression subsection in the build report file.
#
class DepexReport(object):
    ##
    # Constructor function for class DepexReport
    #
    # This constructor function generates DepexReport object for
    # a module. If the module source contains the DXS file (usually EDK
    # style module), it uses the dependency in DXS file; otherwise,
    # it uses the dependency expression from its own INF [Depex] section
    # and then merges with the ones from its dependent library INF.
    #
    # @param self            The object pointer
    # @param M               Module context information
    #
    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, "")

        if ModuleType in ["SEC", "PEI_CORE", "DXE_CORE", "SMM_CORE", "UEFI_APPLICATION"]:
            return
      
        for Source in M.SourceFileList:
            if os.path.splitext(Source.Path)[1].lower() == ".dxs":
                Match = gDxsDependencyPattern.search(open(Source.Path).read())
                if Match:
                    self.Depex = Match.group(1).strip()
                    self.Source = "DXS"
                    break
        else:
            self.Depex = M.DepexExpressionList.get(M.ModuleType, "")
            self.ModuleDepex = " ".join(M.Module.DepexExpression[M.Arch, M.ModuleType])
            if not self.ModuleDepex:
                self.ModuleDepex = "(None)"

            LibDepexList = []
            for Lib in M.DependentLibraryList:
                LibDepex = " ".join(Lib.DepexExpression[M.Arch, M.ModuleType]).strip()
                if LibDepex != "":
                    LibDepexList.append("(" + LibDepex + ")")
            self.LibraryDepex = " AND ".join(LibDepexList)
            if not self.LibraryDepex:
                self.LibraryDepex = "(None)"
            self.Source = "INF"

    ##
    # Generate report for module dependency expression information
    #
    # This function generates report for the module dependency expression.
    #
    # @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, GlobalDepexParser):
        if not self.Depex:
            FileWrite(File, gSubSectionStart)
            FileWrite(File, TAB_DEPEX)
            FileWrite(File, gSubSectionEnd)
            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":
            FileWrite(File, "%s" % self.Depex, True)
            FileWrite(File, gSubSectionSep)
            FileWrite(File, "From Module INF:  %s" % self.ModuleDepex, True)
            FileWrite(File, "From Library INF: %s" % self.LibraryDepex, True)
        else:
            FileWrite(File, "%s" % self.Depex)
        FileWrite(File, gSubSectionEnd)

##
# Reports dependency expression information
#
# This class reports the module build flags subsection in the build report file.
#
class BuildFlagsReport(object):
    ##
    # Constructor function for class BuildFlagsReport
    #
    # This constructor function generates BuildFlagsReport object for
    # a module. It reports the build tool chain tag and all relevant
    # build flags to build the module.
    #
    # @param self            The object pointer
    # @param M               Module context information
    #
    def __init__(self, M):
        BuildOptions = {}
        #
        # Add build flags according to source file extension so that
        # irrelevant ones can be filtered out.
        #
        for Source in M.SourceFileList:
            Ext = os.path.splitext(Source.File)[1].lower()
            if Ext in [".c", ".cc", ".cpp"]:
                BuildOptions["CC"] = 1
            elif Ext in [".s", ".asm"]:
                BuildOptions["PP"] = 1
                BuildOptions["ASM"] = 1
            elif Ext in [".vfr"]:
                BuildOptions["VFRPP"] = 1
                BuildOptions["VFR"] = 1
            elif Ext in [".dxs"]:
                BuildOptions["APP"] = 1
                BuildOptions["CC"] = 1
            elif Ext in [".asl"]:
                BuildOptions["ASLPP"] = 1
                BuildOptions["ASL"] = 1
            elif Ext in [".aslc"]:
                BuildOptions["ASLCC"] = 1
                BuildOptions["ASLDLINK"] = 1
                BuildOptions["CC"] = 1
            elif Ext in [".asm16"]:
                BuildOptions["ASMLINK"] = 1
            BuildOptions["SLINK"] = 1
            BuildOptions["DLINK"] = 1

        #
        # Save module build flags.
        #
        self.ToolChainTag = M.ToolChain
        self.BuildFlags = {}
        for Tool in BuildOptions:
            self.BuildFlags[Tool + "_FLAGS"] = M.BuildOption.get(Tool, {}).get("FLAGS", "")

    ##
    # Generate report for module build flags information
    #
    # This function generates report for the module build flags expression.
    #
    # @param self            The object pointer
    # @param File            The file object for report
    #
    def GenerateReport(self, File):
        FileWrite(File, gSubSectionStart)
        FileWrite(File, "Build Flags")
        FileWrite(File, "Tool Chain Tag: %s" % self.ToolChainTag)
        for Tool in self.BuildFlags:
            FileWrite(File, gSubSectionSep)
            FileWrite(File, "%s = %s" % (Tool, self.BuildFlags[Tool]), True)

        FileWrite(File, gSubSectionEnd)


##
# Reports individual module information
#
# This class reports the module section in the build report file.
# It comprises of module summary, module PCD, library, dependency expression,
# build flags sections.
#
class ModuleReport(object):
    ##
    # Constructor function for class ModuleReport
    #
    # This constructor function generates ModuleReport object for
    # a separate module in a platform build.
    #
    # @param self            The object pointer
    # @param M               Module context information
    # @param ReportType      The kind of report items in the final report file
    #
    def __init__(self, M, ReportType):
        self.ModuleName = M.Module.BaseName
        self.ModuleInfPath = M.MetaFile.File
        self.FileGuid = M.Guid
        self.Size = 0
        self.BuildTimeStamp = None
        self.Hash = 0
        self.DriverType = ""
        if not M.IsLibrary:
            ModuleType = M.ModuleType
            if not ModuleType:
                ModuleType = gComponentType2ModuleType.get(M.ComponentType, "")
            #
            # If a module complies to PI 1.1, promote Module type to "SMM_DRIVER"
            #
            if ModuleType == "DXE_SMM_DRIVER":
                PiSpec = M.Module.Specification.get("PI_SPECIFICATION_VERSION", "0x00010000")
                if int(PiSpec, 0) >= 0x0001000A:
                    ModuleType = "SMM_DRIVER"
            self.DriverType = gDriverTypeMap.get(ModuleType, "0x2 (FREE_FORM)")
        self.UefiSpecVersion = M.Module.Specification.get("UEFI_SPECIFICATION_VERSION", "")
        self.PiSpecVersion = M.Module.Specification.get("PI_SPECIFICATION_VERSION", "")
        self.PciDeviceId = M.Module.Defines.get("PCI_DEVICE_ID", "")
        self.PciVendorId = M.Module.Defines.get("PCI_VENDOR_ID", "")
        self.PciClassCode = M.Module.Defines.get("PCI_CLASS_CODE", "")

        self._BuildDir = M.BuildDir
        self.ModulePcdSet = {}
        if "PCD" in ReportType:
            #
            # Collect all module used PCD set: module INF referenced directly or indirectly.
            # It also saves module INF default values of them in case they exist.
            #
            for Pcd in M.ModulePcdList + M.LibraryPcdList:
                self.ModulePcdSet.setdefault((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Type), (Pcd.InfDefaultValue, Pcd.DefaultValue))

        self.LibraryReport = None
        if "LIBRARY" in ReportType:
            self.LibraryReport = LibraryReport(M)

        self.DepexReport = None
        if "DEPEX" in ReportType:
            self.DepexReport = DepexReport(M)

        if "BUILD_FLAGS" in ReportType:
            self.BuildFlagsReport = BuildFlagsReport(M)


    ##
    # Generate report for module information
    #
    # 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 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, GlobalDepexParser, ReportType):
        FileWrite(File, gSectionStart)

        FwReportFileName = os.path.join(self._BuildDir, "DEBUG", self.ModuleName + ".txt")
        if os.path.isfile(FwReportFileName):
            try:
                FileContents = open(FwReportFileName).read()
                Match = gModuleSizePattern.search(FileContents)
                if Match:
                    self.Size = int(Match.group(1))

                Match = gTimeStampPattern.search(FileContents)
                if Match:
                    self.BuildTimeStamp = datetime.fromtimestamp(int(Match.group(1)))
            except IOError:
                EdkLogger.warn(None, "Fail to read report file", FwReportFileName)

        if "HASH" in ReportType:
            OutputDir = os.path.join(self._BuildDir, "OUTPUT")
            DefaultEFIfile = os.path.join(OutputDir, self.ModuleName + ".efi")
            if os.path.isfile(DefaultEFIfile):
                Tempfile = os.path.join(OutputDir, self.ModuleName + "_hash.tmp")
                # rebase the efi image since its base address may not zero
                cmd = ["GenFw", "--rebase", str(0), "-o", Tempfile, DefaultEFIfile]
                try:
                    PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
                except Exception, X:
                    EdkLogger.error("GenFw", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))
                EndOfProcedure = threading.Event()
                EndOfProcedure.clear()
                if PopenObject.stderr:
                    StdErrThread = threading.Thread(target=ReadMessage, args=(PopenObject.stderr, EdkLogger.quiet, EndOfProcedure))
                    StdErrThread.setName("STDERR-Redirector")
                    StdErrThread.setDaemon(False)
                    StdErrThread.start()
                # waiting for program exit
                PopenObject.wait()
                if PopenObject.stderr:
                    StdErrThread.join()
                if PopenObject.returncode != 0:
                    EdkLogger.error("GenFw", COMMAND_FAILURE, "Failed to generate firmware hash image for %s" % (DefaultEFIfile))
                if os.path.isfile(Tempfile):
                    self.Hash = hashlib.sha1()
                    buf = open(Tempfile, 'rb').read()
                    if self.Hash.update(buf):
                        self.Hash = self.Hash.update(buf)
                    self.Hash = self.Hash.hexdigest()
                    os.remove(Tempfile)

        FileWrite(File, "Module Summary")
        FileWrite(File, "Module Name:          %s" % self.ModuleName)
        FileWrite(File, "Module INF Path:      %s" % self.ModuleInfPath)
        FileWrite(File, "File GUID:            %s" % self.FileGuid)
        if self.Size:
            FileWrite(File, "Size:                 0x%X (%.2fK)" % (self.Size, self.Size / 1024.0))
        if self.Hash:
            FileWrite(File, "SHA1 HASH:            %s *%s" % (self.Hash, self.ModuleName + ".efi"))
        if self.BuildTimeStamp:
            FileWrite(File, "Build Time Stamp:     %s" % self.BuildTimeStamp)
        if self.DriverType:
            FileWrite(File, "Driver Type:          %s" % self.DriverType)
        if self.UefiSpecVersion:
            FileWrite(File, "UEFI Spec Version:    %s" % self.UefiSpecVersion)
        if self.PiSpecVersion:
            FileWrite(File, "PI Spec Version:      %s" % self.PiSpecVersion)
        if self.PciDeviceId:
            FileWrite(File, "PCI Device ID:        %s" % self.PciDeviceId)
        if self.PciVendorId:
            FileWrite(File, "PCI Vendor ID:        %s" % self.PciVendorId)
        if self.PciClassCode:
            FileWrite(File, "PCI Class Code:       %s" % self.PciClassCode)

        FileWrite(File, gSectionSep)

        if "PCD" in ReportType:
            GlobalPcdReport.GenerateReport(File, self.ModulePcdSet)

        if "LIBRARY" in ReportType:
            self.LibraryReport.GenerateReport(File)

        if "DEPEX" in ReportType:
            self.DepexReport.GenerateReport(File, GlobalDepexParser)

        if "BUILD_FLAGS" in ReportType:
            self.BuildFlagsReport.GenerateReport(File)

        if "FIXED_ADDRESS" in ReportType and self.FileGuid:
            GlobalPredictionReport.GenerateReport(File, self.FileGuid)

        FileWrite(File, gSectionEnd)

def ReadMessage(From, To, ExitFlag):
    while True:
        # read one line a time
        Line = From.readline()
        # empty string means "end"
        if Line != None and Line != "":
            To(Line.rstrip())
        else:
            break
        if ExitFlag.isSet():
            break

##
# Reports platform and module PCD information
#
# This class reports the platform PCD section and module PCD subsection
# in the build report file.
#
class PcdReport(object):
    ##
    # Constructor function for class PcdReport
    #
    # This constructor function generates PcdReport object a platform build.
    # It collects the whole PCD database from platform DSC files, platform
    # flash description file and package DEC files.
    #
    # @param self            The object pointer
    # @param Wa              Workspace context information
    #
    def __init__(self, Wa):
        self.AllPcds = {}
        self.UnusedPcds = {}
        self.ConditionalPcds = {}
        self.MaxLen = 0
        if Wa.FdfProfile:
            self.FdfPcdSet = Wa.FdfProfile.PcdDict
        else:
            self.FdfPcdSet = {}

        self.ModulePcdOverride = {}
        for Pa in Wa.AutoGenObjectList:
            #
            # Collect all platform referenced PCDs and grouped them by PCD token space
            # GUID C Names
            #
            for Pcd in Pa.AllPcdList:
                PcdList = self.AllPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, [])
                if Pcd not in PcdList:
                    PcdList.append(Pcd)
                if len(Pcd.TokenCName) > self.MaxLen:
                    self.MaxLen = len(Pcd.TokenCName)
            #
            # Collect the PCD defined in DSC/FDF file, but not used in module
            #
            UnusedPcdFullList = []
            for item in Pa.Platform.Pcds:
                Pcd = Pa.Platform.Pcds[item]
                if not Pcd.Type:
                    PcdTypeFlag = False
                    for package in Pa.PackageList:
                        for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
                            if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, T) in package.Pcds:
                                Pcd.Type = T
                                PcdTypeFlag = True
                                if not Pcd.DatumType:
                                    Pcd.DatumType = package.Pcds[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName, T)].DatumType
                                break
                        if PcdTypeFlag:
                            break
                if not Pcd.DatumType:
                    PcdType = Pcd.Type
                    # Try to remove Hii and Vpd suffix
                    if PcdType.startswith("DynamicEx"):
                        PcdType = "DynamicEx"
                    elif PcdType.startswith("Dynamic"):
                        PcdType = "Dynamic"
                    for package in Pa.PackageList:
                        if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, PcdType) in package.Pcds:
                            Pcd.DatumType = package.Pcds[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName, PcdType)].DatumType
                            break

                PcdList = self.AllPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, [])
                if Pcd not in PcdList and Pcd not in UnusedPcdFullList:
                    UnusedPcdFullList.append(Pcd)
                if len(Pcd.TokenCName) > self.MaxLen:
                    self.MaxLen = len(Pcd.TokenCName)

            if GlobalData.gConditionalPcds:
                for PcdItem in GlobalData.gConditionalPcds:
                    if '.' in PcdItem:
                        (TokenSpaceGuidCName, TokenCName) = PcdItem.split('.')
                        if (TokenCName, TokenSpaceGuidCName) in Pa.Platform.Pcds.keys():
                            Pcd = Pa.Platform.Pcds[(TokenCName, TokenSpaceGuidCName)]
                            PcdList = self.ConditionalPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, [])
                            if Pcd not in PcdList:
                                PcdList.append(Pcd)

            UnusedPcdList = []
            if UnusedPcdFullList:
                for Pcd in UnusedPcdFullList:
                    if Pcd.TokenSpaceGuidCName + '.' + Pcd.TokenCName in GlobalData.gConditionalPcds:
                        continue
                    UnusedPcdList.append(Pcd)

            for Pcd in UnusedPcdList:
                PcdList = self.UnusedPcds.setdefault(Pcd.TokenSpaceGuidCName, {}).setdefault(Pcd.Type, [])
                if Pcd not in PcdList:
                    PcdList.append(Pcd)

            for Module in Pa.Platform.Modules.values():
                #
                # Collect module override PCDs
                #
                for ModulePcd in Module.M.ModulePcdList + Module.M.LibraryPcdList:
                    TokenCName = ModulePcd.TokenCName
                    TokenSpaceGuid = ModulePcd.TokenSpaceGuidCName
                    ModuleDefault = ModulePcd.DefaultValue
                    ModulePath = os.path.basename(Module.M.MetaFile.File)
                    self.ModulePcdOverride.setdefault((TokenCName, TokenSpaceGuid), {})[ModulePath] = ModuleDefault


        #
        # Collect PCD DEC default value.
        #
        self.DecPcdDefault = {}
        for Pa in Wa.AutoGenObjectList:
            for Package in Pa.PackageList:
                for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:
                    DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue
                    self.DecPcdDefault.setdefault((TokenCName, TokenSpaceGuidCName, DecType), DecDefaultValue)
        #
        # Collect PCDs defined in DSC common section
        #
        self.DscPcdDefault = {}
        for Arch in Wa.ArchList:
            Platform = Wa.BuildDatabase[Wa.MetaFile, Arch, Wa.BuildTarget, Wa.ToolChain]
            for (TokenCName, TokenSpaceGuidCName) in Platform.Pcds:
                DscDefaultValue = Platform.Pcds[(TokenCName, TokenSpaceGuidCName)].DefaultValue
                if DscDefaultValue:
                    self.DscPcdDefault[(TokenCName, TokenSpaceGuidCName)] = DscDefaultValue

    def GenerateReport(self, File, ModulePcdSet):
        if self.ConditionalPcds:
            self.GenerateReportDetail(File, ModulePcdSet, 1)
        if self.UnusedPcds:
            self.GenerateReportDetail(File, ModulePcdSet, 2)
        self.GenerateReportDetail(File, ModulePcdSet)

    ##
    # Generate report for PCD information
    #
    # 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 ModulePcdSet    Set of all PCDs referenced by module or None for
    #                        platform PCD report
    # @param ReportySubType  0 means platform/module PCD report, 1 means Conditional
    #                        directives section report, 2 means Unused Pcds section report
    # @param DscOverridePcds Module DSC override PCDs set
    #
    def GenerateReportDetail(self, File, ModulePcdSet, ReportSubType = 0):
        PcdDict = self.AllPcds
        if ReportSubType == 1:
            PcdDict = self.ConditionalPcds
        elif ReportSubType == 2:
            PcdDict = self.UnusedPcds

        if ModulePcdSet == None:
            FileWrite(File, gSectionStart)
            if ReportSubType == 1:
                FileWrite(File, "Conditional Directives used by the build system")
            elif ReportSubType == 2:
                FileWrite(File, "PCDs not used by modules or in conditional directives")
            else:
                FileWrite(File, "Platform Configuration Database Report")

            FileWrite(File, "  *B  - PCD override in the build option")
            FileWrite(File, "  *P  - Platform scoped PCD override in DSC file")
            FileWrite(File, "  *F  - Platform scoped PCD override in FDF file")
            if not ReportSubType:
                FileWrite(File, "  *M  - Module scoped PCD override")
            FileWrite(File, gSectionSep)
        else:
            if not ReportSubType:
                #
                # For module PCD sub-section
                #
                FileWrite(File, gSubSectionStart)
                FileWrite(File, TAB_BRG_PCD)
                FileWrite(File, gSubSectionSep)

        for Key in PcdDict:
            #
            # Group PCD by their token space GUID C Name
            #
            First = True
            for Type in PcdDict[Key]:
                #
                # Group PCD by their usage type
                #
                TypeName, DecType = gPcdTypeMap.get(Type, ("", Type))
                for Pcd in PcdDict[Key][Type]:
                    #
                    # Get PCD default value and their override relationship
                    #
                    DecDefaultValue = self.DecPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, DecType))
                    DscDefaultValue = self.DscPcdDefault.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName))
                    DscDefaultValue = self.FdfPcdSet.get((Pcd.TokenCName, Key), DscDefaultValue)
                    InfDefaultValue = None
                    
                    PcdValue = DecDefaultValue
                    if DscDefaultValue:
                        PcdValue = DscDefaultValue
                    if ModulePcdSet != None:
                        if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type) not in ModulePcdSet:
                            continue
                        InfDefault, PcdValue = ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type]
                        if InfDefault == "":
                            InfDefault = None

                    BuildOptionMatch = False
                    if GlobalData.BuildOptionPcd:
                        for pcd in GlobalData.BuildOptionPcd:
                            if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (pcd[0], pcd[1]):
                                PcdValue = pcd[2]
                                BuildOptionMatch = True
                                break

                    if First:
                        if ModulePcdSet == None:
                            FileWrite(File, "")
                        FileWrite(File, Key)
                        First = False


                    if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):
                        PcdValueNumber = int(PcdValue.strip(), 0)
                        if DecDefaultValue == None:
                            DecMatch = True
                        else:
                            DecDefaultValueNumber = int(DecDefaultValue.strip(), 0)
                            DecMatch = (DecDefaultValueNumber == PcdValueNumber)

                        if InfDefaultValue == None:
                            InfMatch = True
                        else:
                            InfDefaultValueNumber = int(InfDefaultValue.strip(), 0)
                            InfMatch = (InfDefaultValueNumber == PcdValueNumber)

                        if DscDefaultValue == None:
                            DscMatch = True
                        else:
                            DscDefaultValueNumber = int(DscDefaultValue.strip(), 0)
                            DscMatch = (DscDefaultValueNumber == PcdValueNumber)
                    else:
                        if DecDefaultValue == None:
                            DecMatch = True
                        else:
                            DecMatch = (DecDefaultValue.strip() == PcdValue.strip())

                        if InfDefaultValue == None:
                            InfMatch = True
                        else:
                            InfMatch = (InfDefaultValue.strip() == PcdValue.strip())

                        if DscDefaultValue == None:
                            DscMatch = True
                        else:
                            DscMatch = (DscDefaultValue.strip() == PcdValue.strip())

                    #
                    # Report PCD item according to their override relationship
                    #
                    if BuildOptionMatch:
                        FileWrite(File, ' *B %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '(' + Pcd.DatumType + ')', PcdValue.strip()))
                    elif DecMatch and InfMatch:
                        FileWrite(File, '    %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '(' + Pcd.DatumType + ')', PcdValue.strip()))
                    else:
                        if DscMatch:
                            if (Pcd.TokenCName, Key) in self.FdfPcdSet:
                                FileWrite(File, ' *F %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '(' + Pcd.DatumType + ')', PcdValue.strip()))
                            else:
                                FileWrite(File, ' *P %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '(' + Pcd.DatumType + ')', PcdValue.strip()))
                        else:
                            FileWrite(File, ' *M %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '(' + Pcd.DatumType + ')', PcdValue.strip()))

                    if TypeName in ('DYNHII', 'DEXHII', 'DYNVPD', 'DEXVPD'):
                        for SkuInfo in Pcd.SkuInfoList.values():
                            if TypeName in ('DYNHII', 'DEXHII'):
                                FileWrite(File, '%*s: %s: %s' % (self.MaxLen + 4, SkuInfo.VariableGuid, SkuInfo.VariableName, SkuInfo.VariableOffset))
                            else:
                                FileWrite(File, '%*s' % (self.MaxLen + 4, SkuInfo.VpdOffset))
                               
                    if not DscMatch and DscDefaultValue != None:
                        FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'DSC DEFAULT', DscDefaultValue.strip()))

                    if not InfMatch and InfDefaultValue != None:
                        FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'INF DEFAULT', InfDefaultValue.strip()))

                    if not DecMatch and DecDefaultValue != None:
                        FileWrite(File, '    %*s = %s' % (self.MaxLen + 19, 'DEC DEFAULT', DecDefaultValue.strip()))

                    if ModulePcdSet == None:
                        if not BuildOptionMatch:
                            ModuleOverride = self.ModulePcdOverride.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), {})
                            for ModulePath in ModuleOverride:
                                ModuleDefault = ModuleOverride[ModulePath]
                                if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'):
                                    ModulePcdDefaultValueNumber = int(ModuleDefault.strip(), 0)
                                    Match = (ModulePcdDefaultValueNumber == PcdValueNumber)
                                else:
                                    Match = (ModuleDefault.strip() == PcdValue.strip())
                                if Match:
                                    continue
                                FileWrite(File, ' *M %-*s = %s' % (self.MaxLen + 19, ModulePath, ModuleDefault.strip()))

        if ModulePcdSet == None:
            FileWrite(File, gSectionEnd)
        else:
            if not ReportSubType:
                FileWrite(File, gSubSectionEnd)



##
# Reports platform and module Prediction information
#
# This class reports the platform execution order prediction section and
# module load fixed address prediction subsection in the build report file.
#
class PredictionReport(object):
    ##
    # Constructor function for class PredictionReport
    #
    # This constructor function generates PredictionReport object for the platform.
    #
    # @param self:           The object pointer
    # @param Wa              Workspace context information
    #
    def __init__(self, Wa):
        self._MapFileName = os.path.join(Wa.BuildDir, Wa.Name + ".map")
        self._MapFileParsed = False
        self._EotToolInvoked = False
        self._FvDir = Wa.FvDir
        self._EotDir = Wa.BuildDir
        self._FfsEntryPoint = {}
        self._GuidMap = {}
        self._SourceList = []
        self.FixedMapDict = {}
        self.ItemList = []
        self.MaxLen = 0

        #
        # Collect all platform reference source files and GUID C Name
        #
        for Pa in Wa.AutoGenObjectList:
            for Module in Pa.LibraryAutoGenList + Pa.ModuleAutoGenList:
                #
                # BASE typed modules are EFI agnostic, so we need not scan
                # their source code to find PPI/Protocol produce or consume
                # information.
                #
                if Module.ModuleType == "BASE":
                    continue
                #
                # Add module referenced source files
                #
                self._SourceList.append(str(Module))
                IncludeList = {}
                for Source in Module.SourceFileList:
                    if os.path.splitext(str(Source))[1].lower() == ".c":
                        self._SourceList.append("  " + str(Source))
                        FindIncludeFiles(Source.Path, Module.IncludePathList, IncludeList)
                for IncludeFile in IncludeList.values():
                    self._SourceList.append("  " + IncludeFile)

                for Guid in Module.PpiList:
                    self._GuidMap[Guid] = GuidStructureStringToGuidString(Module.PpiList[Guid])
                for Guid in Module.ProtocolList:
                    self._GuidMap[Guid] = GuidStructureStringToGuidString(Module.ProtocolList[Guid])
                for Guid in Module.GuidList:
                    self._GuidMap[Guid] = GuidStructureStringToGuidString(Module.GuidList[Guid])

                if Module.Guid and not Module.IsLibrary:
                    EntryPoint = " ".join(Module.Module.ModuleEntryPointList)
                    if int(str(Module.AutoGenVersion), 0) >= 0x00010005:
                        RealEntryPoint = "_ModuleEntryPoint"
                    else:
                        RealEntryPoint = EntryPoint
                        if EntryPoint == "_ModuleEntryPoint":
                            CCFlags = Module.BuildOption.get("CC", {}).get("FLAGS", "")
                            Match = gGlueLibEntryPoint.search(CCFlags)
                            if Match:
                                EntryPoint = Match.group(1)

                    self._FfsEntryPoint[Module.Guid.upper()] = (EntryPoint, RealEntryPoint)


        #
        # Collect platform firmware volume list as the input of EOT.
        #
        self._FvList = []
        if Wa.FdfProfile:
            for Fd in Wa.FdfProfile.FdDict:
                for FdRegion in Wa.FdfProfile.FdDict[Fd].RegionList:
                    if FdRegion.RegionType != "FV":
                        continue
                    for FvName in FdRegion.RegionDataList:
                        if FvName in self._FvList:
                            continue
                        self._FvList.append(FvName)
                        for Ffs in Wa.FdfProfile.FvDict[FvName.upper()].FfsList:
                            for Section in Ffs.SectionList:
                                try:
                                    for FvSection in Section.SectionList:
                                        if FvSection.FvName in self._FvList:
                                            continue
                                        self._FvList.append(FvSection.FvName)
                                except AttributeError:
                                    pass


    ##
    # Parse platform fixed address map files
    #
    # This function parses the platform final fixed address map file to get
    # the database of predicted fixed address for module image base, entry point
    # etc.
    #
    # @param self:           The object pointer
    #
    def _ParseMapFile(self):
        if self._MapFileParsed:
            return
        self._MapFileParsed = True
        if os.path.isfile(self._MapFileName):
            try:
                FileContents = open(self._MapFileName).read()
                for Match in gMapFileItemPattern.finditer(FileContents):
                    AddressType = Match.group(1)
                    BaseAddress = Match.group(2)
                    EntryPoint = Match.group(3)
                    Guid = Match.group(4).upper()
                    List = self.FixedMapDict.setdefault(Guid, [])
                    List.append((AddressType, BaseAddress, "*I"))
                    List.append((AddressType, EntryPoint, "*E"))
            except:
                EdkLogger.warn(None, "Cannot open file to read", self._MapFileName)

    ##
    # Invokes EOT tool to get the predicted the execution order.
    #
    # This function invokes EOT tool to calculate the predicted dispatch order
    #
    # @param self:           The object pointer
    #
    def _InvokeEotTool(self):
        if self._EotToolInvoked:
            return

        self._EotToolInvoked = True
        FvFileList = []
        for FvName in self._FvList:
            FvFile = os.path.join(self._FvDir, FvName + ".Fv")
            if os.path.isfile(FvFile):
                FvFileList.append(FvFile)

        if len(FvFileList) == 0:
            return
        #
        # Write source file list and GUID file list to an intermediate file
        # as the input for EOT tool and dispatch List as the output file
        # from EOT tool.
        #
        SourceList = os.path.join(self._EotDir, "SourceFile.txt")
        GuidList = os.path.join(self._EotDir, "GuidList.txt")
        DispatchList = os.path.join(self._EotDir, "Dispatch.txt")

        TempFile = open(SourceList, "w+")
        for Item in self._SourceList:
            FileWrite(TempFile, Item)
        TempFile.close()
        TempFile = open(GuidList, "w+")
        for Key in self._GuidMap:
            FileWrite(TempFile, "%s %s" % (Key, self._GuidMap[Key]))
        TempFile.close()

        try:
            from Eot.Eot import Eot

            #
            # Invoke EOT tool and echo its runtime performance
            #
            EotStartTime = time.time()
            Eot(CommandLineOption=False, SourceFileList=SourceList, GuidList=GuidList,
                FvFileList=' '.join(FvFileList), Dispatch=DispatchList, IsInit=True)
            EotEndTime = time.time()
            EotDuration = time.strftime("%H:%M:%S", time.gmtime(int(round(EotEndTime - EotStartTime))))
            EdkLogger.quiet("EOT run time: %s\n" % EotDuration)
            
            #
            # Parse the output of EOT tool
            #
            for Line in open(DispatchList):
                if len(Line.split()) < 4:
                    continue
                (Guid, Phase, FfsName, FilePath) = Line.split()
                Symbol = self._FfsEntryPoint.get(Guid, [FfsName, ""])[0]
                if len(Symbol) > self.MaxLen:
                    self.MaxLen = len(Symbol)
                self.ItemList.append((Phase, Symbol, FilePath))
        except:
            EdkLogger.quiet("(Python %s on %s\n%s)" % (platform.python_version(), sys.platform, traceback.format_exc()))
            EdkLogger.warn(None, "Failed to generate execution order prediction report, for some error occurred in executing EOT.")


    ##
    # Generate platform execution order report
    #
    # This function generates the predicted module execution order.
    #
    # @param self            The object pointer
    # @param File            The file object for report
    #
    def _GenerateExecutionOrderReport(self, File):
        self._InvokeEotTool()
        if len(self.ItemList) == 0:
            return
        FileWrite(File, gSectionStart)
        FileWrite(File, "Execution Order Prediction")
        FileWrite(File, "*P PEI phase")
        FileWrite(File, "*D DXE phase")
        FileWrite(File, "*E Module INF entry point name")
        FileWrite(File, "*N Module notification function name")

        FileWrite(File, "Type %-*s %s" % (self.MaxLen, "Symbol", "Module INF Path"))
        FileWrite(File, gSectionSep)
        for Item in self.ItemList:
            FileWrite(File, "*%sE  %-*s %s" % (Item[0], self.MaxLen, Item[1], Item[2]))

        FileWrite(File, gSectionStart)

    ##
    # Generate Fixed Address report.
    #
    # This function generate the predicted fixed address report for a module
    # specified by Guid.
    #
    # @param self            The object pointer
    # @param File            The file object for report
    # @param Guid            The module Guid value.
    # @param NotifyList      The list of all notify function in a module
    #
    def _GenerateFixedAddressReport(self, File, Guid, NotifyList):
        self._ParseMapFile()
        FixedAddressList = self.FixedMapDict.get(Guid)
        if not FixedAddressList:
            return

        FileWrite(File, gSubSectionStart)
        FileWrite(File, "Fixed Address Prediction")
        FileWrite(File, "*I  Image Loading Address")
        FileWrite(File, "*E  Entry Point Address")
        FileWrite(File, "*N  Notification Function Address")
        FileWrite(File, "*F  Flash Address")
        FileWrite(File, "*M  Memory Address")
        FileWrite(File, "*S  SMM RAM Offset")
        FileWrite(File, "TOM Top of Memory")

        FileWrite(File, "Type Address           Name")
        FileWrite(File, gSubSectionSep)
        for Item in FixedAddressList:
            Type = Item[0]
            Value = Item[1]
            Symbol = Item[2]
            if Symbol == "*I":
                Name = "(Image Base)"
            elif Symbol == "*E":
                Name = self._FfsEntryPoint.get(Guid, ["", "_ModuleEntryPoint"])[1]
            elif Symbol in NotifyList:
                Name = Symbol
                Symbol = "*N"
            else:
                continue

            if "Flash" in Type:
                Symbol += "F"
            elif "Memory" in Type:
                Symbol += "M"
            else:
                Symbol += "S"

            if Value[0] == "-":
                Value = "TOM" + Value

            FileWrite(File, "%s  %-16s  %s" % (Symbol, Value, Name))

    ##
    # Generate report for the prediction part
    #
    # This function generate the predicted fixed address report for a module or
    # predicted module execution order for a platform.
    # If the input Guid is None, then, it generates the predicted module execution order;
    # otherwise it generated the module fixed loading address for the module specified by
    # Guid.
    #
    # @param self            The object pointer
    # @param File            The file object for report
    # @param Guid            The module Guid value.
    #
    def GenerateReport(self, File, Guid):
        if Guid:
            self._GenerateFixedAddressReport(File, Guid.upper(), [])
        else:
            self._GenerateExecutionOrderReport(File)

##
# Reports FD region information
#
# This class reports the FD subsection in the build report file.
# It collects region information of platform flash device.
# If the region is a firmware volume, it lists the set of modules
# and its space information; otherwise, it only lists its region name,
# base address and size in its sub-section header.
# If there are nesting FVs, the nested FVs will list immediate after
# this FD region subsection
#
class FdRegionReport(object):
    ##
    # Discover all the nested FV name list.
    #
    # This is an internal worker function to discover the all the nested FV information
    # in the parent firmware volume. It uses deep first search algorithm recursively to
    # find all the FV list name and append them to the list.
    #
    # @param self            The object pointer
    # @param FvName          The name of current firmware file system
    # @param Wa              Workspace context information
    #
    def _DiscoverNestedFvList(self, FvName, Wa):
        FvDictKey=FvName.upper()
        if FvDictKey in Wa.FdfProfile.FvDict:
            for Ffs in Wa.FdfProfile.FvDict[FvName.upper()].FfsList:
                for Section in Ffs.SectionList:
                    try:
                        for FvSection in Section.SectionList:
                            if FvSection.FvName in self.FvList:
                                continue
                            self._GuidsDb[Ffs.NameGuid.upper()] = FvSection.FvName
                            self.FvList.append(FvSection.FvName)
                            self.FvInfo[FvSection.FvName] = ("Nested FV", 0, 0)
                            self._DiscoverNestedFvList(FvSection.FvName, Wa)
                    except AttributeError:
                        pass

    ##
    # Constructor function for class FdRegionReport
    #
    # This constructor function generates FdRegionReport object for a specified FdRegion.
    # If the FdRegion is a firmware volume, it will recursively find all its nested Firmware
    # volume list. This function also collects GUID map in order to dump module identification
    # in the final report.
    #
    # @param self:           The object pointer
    # @param FdRegion        The current FdRegion object
    # @param Wa              Workspace context information
    #
    def __init__(self, FdRegion, Wa):
        self.Type = FdRegion.RegionType
        self.BaseAddress = FdRegion.Offset
        self.Size = FdRegion.Size
        self.FvList = []
        self.FvInfo = {}
        self._GuidsDb = {}
        self._FvDir = Wa.FvDir

        #
        # If the input FdRegion is not a firmware volume,
        # we are done.
        #
        if self.Type != "FV":
            return

        #
        # Find all nested FVs in the FdRegion
        #
        for FvName in FdRegion.RegionDataList:
            if FvName in self.FvList:
                continue
            self.FvList.append(FvName)
            self.FvInfo[FvName] = ("Fd Region", self.BaseAddress, self.Size)
            self._DiscoverNestedFvList(FvName, Wa)

        PlatformPcds = {}
        #
        # Collect PCDs declared in DEC files.
        #        
        for Pa in Wa.AutoGenObjectList:
            for Package in Pa.PackageList:
                for (TokenCName, TokenSpaceGuidCName, DecType) in Package.Pcds:
                    DecDefaultValue = Package.Pcds[TokenCName, TokenSpaceGuidCName, DecType].DefaultValue
                    PlatformPcds[(TokenCName, TokenSpaceGuidCName)] = DecDefaultValue
        #
        # Collect PCDs defined in DSC file
        #
        for arch in Wa.ArchList:
            Platform = Wa.BuildDatabase[Wa.MetaFile, arch]
            for (TokenCName, TokenSpaceGuidCName) in Platform.Pcds:
                DscDefaultValue = Platform.Pcds[(TokenCName, TokenSpaceGuidCName)].DefaultValue
                PlatformPcds[(TokenCName, TokenSpaceGuidCName)] = DscDefaultValue

        #
        # Add PEI and DXE a priori files GUIDs defined in PI specification.
        #
        self._GuidsDb["1B45CC0A-156A-428A-AF62-49864DA0E6E6"] = "PEI Apriori"
        self._GuidsDb["FC510EE7-FFDC-11D4-BD41-0080C73C8881"] = "DXE Apriori"
        #
        # Add ACPI table storage file
        #
        self._GuidsDb["7E374E25-8E01-4FEE-87F2-390C23C606CD"] = "ACPI table storage"

        for Pa in Wa.AutoGenObjectList:
            for ModuleKey in Pa.Platform.Modules:
                M = Pa.Platform.Modules[ModuleKey].M
                InfPath = mws.join(Wa.WorkspaceDir, M.MetaFile.File)
                self._GuidsDb[M.Guid.upper()] = "%s (%s)" % (M.Module.BaseName, InfPath)

        #
        # Collect the GUID map in the FV firmware volume
        #
        for FvName in self.FvList:
            FvDictKey=FvName.upper()
            if FvDictKey in Wa.FdfProfile.FvDict:
                for Ffs in Wa.FdfProfile.FvDict[FvName.upper()].FfsList:
                    try:
                        #
                        # collect GUID map for binary EFI file in FDF file.
                        #
                        Guid = Ffs.NameGuid.upper()
                        Match = gPcdGuidPattern.match(Ffs.NameGuid)
                        if Match:
                            PcdTokenspace = Match.group(1)
                            PcdToken = Match.group(2)
                            if (PcdToken, PcdTokenspace) in PlatformPcds:
                                GuidValue = PlatformPcds[(PcdToken, PcdTokenspace)]
                                Guid = GuidStructureByteArrayToGuidString(GuidValue).upper()
                        for Section in Ffs.SectionList:
                            try:
                                ModuleSectFile = mws.join(Wa.WorkspaceDir, Section.SectFileName)
                                self._GuidsDb[Guid] = ModuleSectFile
                            except AttributeError:
                                pass
                    except AttributeError:
                        pass


    ##
    # Internal worker function to generate report for the FD region
    #
    # This internal worker function to generate report for the FD region.
    # It the type is firmware volume, it lists offset and module identification.
    #
    # @param self            The object pointer
    # @param File            The file object for report
    # @param Title           The title for the FD subsection
    # @param BaseAddress     The base address for the FD region
    # @param Size            The size of the FD region
    # @param FvName          The FV name if the FD region is a firmware volume
    #
    def _GenerateReport(self, File, Title, Type, BaseAddress, Size=0, FvName=None):
        FileWrite(File, gSubSectionStart)
        FileWrite(File, Title)
        FileWrite(File, "Type:               %s" % Type)
        FileWrite(File, "Base Address:       0x%X" % BaseAddress)

        if self.Type == "FV":
            FvTotalSize = 0
            FvTakenSize = 0
            FvFreeSize  = 0
            FvReportFileName = os.path.join(self._FvDir, FvName + ".Fv.txt")
            try:
                #
                # Collect size info in the firmware volume.
                #
                FvReport = open(FvReportFileName).read()
                Match = gFvTotalSizePattern.search(FvReport)
                if Match:
                    FvTotalSize = int(Match.group(1), 16)
                Match = gFvTakenSizePattern.search(FvReport)
                if Match:
                    FvTakenSize = int(Match.group(1), 16)
                FvFreeSize = FvTotalSize - FvTakenSize
                #
                # Write size information to the report file.
                #
                FileWrite(File, "Size:               0x%X (%.0fK)" % (FvTotalSize, FvTotalSize / 1024.0))
                FileWrite(File, "Fv Name:            %s (%.1f%% Full)" % (FvName, FvTakenSize * 100.0 / FvTotalSize))
                FileWrite(File, "Occupied Size:      0x%X (%.0fK)" % (FvTakenSize, FvTakenSize / 1024.0))
                FileWrite(File, "Free Size:          0x%X (%.0fK)" % (FvFreeSize, FvFreeSize / 1024.0))
                FileWrite(File, "Offset     Module")
                FileWrite(File, gSubSectionSep)
                #
                # Write module offset and module identification to the report file.
                #
                OffsetInfo = {}
                for Match in gOffsetGuidPattern.finditer(FvReport):
                    Guid = Match.group(2).upper()
                    OffsetInfo[Match.group(1)] = self._GuidsDb.get(Guid, Guid)
                OffsetList = OffsetInfo.keys()
                OffsetList.sort()
                for Offset in OffsetList:
                    FileWrite (File, "%s %s" % (Offset, OffsetInfo[Offset]))
            except IOError:
                EdkLogger.warn(None, "Fail to read report file", FvReportFileName)
        else:
            FileWrite(File, "Size:               0x%X (%.0fK)" % (Size, Size / 1024.0))
        FileWrite(File, gSubSectionEnd)

    ##
    # Generate report for the FD region
    #
    # This function generates report for the FD region.
    #
    # @param self            The object pointer
    # @param File            The file object for report
    #
    def GenerateReport(self, File):
        if (len(self.FvList) > 0):
            for FvItem in self.FvList:
                Info = self.FvInfo[FvItem]
                self._GenerateReport(File, Info[0], "FV", Info[1], Info[2], FvItem)
        else:
            self._GenerateReport(File, "FD Region", self.Type, self.BaseAddress, self.Size)

##
# Reports FD information
#
# This class reports the FD section in the build report file.
# It collects flash device information for a platform.
#
class FdReport(object):
    ##
    # Constructor function for class FdReport
    #
    # This constructor function generates FdReport object for a specified
    # firmware device.
    #
    # @param self            The object pointer
    # @param Fd              The current Firmware device object
    # @param Wa              Workspace context information
    #
    def __init__(self, Fd, Wa):
        self.FdName = Fd.FdUiName
        self.BaseAddress = Fd.BaseAddress
        self.Size = Fd.Size
        self.FdRegionList = [FdRegionReport(FdRegion, Wa) for FdRegion in Fd.RegionList]
        self.FvPath = os.path.join(Wa.BuildDir, "FV")
        self.VpdFilePath = os.path.join(self.FvPath, "%s.map" % Wa.Platform.VpdToolGuid)
        self.VPDBaseAddress = 0
        self.VPDSize = 0
        self.VPDInfoList = []
        for index, FdRegion in enumerate(Fd.RegionList):
            if str(FdRegion.RegionType) is 'FILE' and Wa.Platform.VpdToolGuid in str(FdRegion.RegionDataList):
                self.VPDBaseAddress = self.FdRegionList[index].BaseAddress
                self.VPDSize = self.FdRegionList[index].Size
                break

        if os.path.isfile(self.VpdFilePath):
            fd = open(self.VpdFilePath, "r")
            Lines = fd.readlines()
            for Line in Lines:
                Line = Line.strip()
                if len(Line) == 0 or Line.startswith("#"):
                    continue
                try:
                    PcdName, SkuId, Offset, Size, Value = Line.split("#")[0].split("|")
                    PcdName, SkuId, Offset, Size, Value = PcdName.strip(), SkuId.strip(), Offset.strip(), Size.strip(), Value.strip()
                    Offset = '0x%08X' % (int(Offset, 16) + self.VPDBaseAddress)
                    self.VPDInfoList.append("%s | %s | %s | %s | %s" % (PcdName, SkuId, Offset, Size, Value))
                except:
                    EdkLogger.error("BuildReport", CODE_ERROR, "Fail to parse VPD information file %s" % self.VpdFilePath)
            fd.close()

    ##
    # Generate report for the firmware device.
    #
    # This function generates report for the firmware device.
    #
    # @param self            The object pointer
    # @param File            The file object for report
    #
    def GenerateReport(self, File):
        FileWrite(File, gSectionStart)
        FileWrite(File, "Firmware Device (FD)")
        FileWrite(File, "FD Name:            %s" % self.FdName)
        FileWrite(File, "Base Address:       %s" % self.BaseAddress)
        FileWrite(File, "Size:               0x%X (%.0fK)" % (self.Size, self.Size / 1024.0))
        if len(self.FdRegionList) > 0:
            FileWrite(File, gSectionSep)
            for FdRegionItem in self.FdRegionList:
                FdRegionItem.GenerateReport(File)

        if len(self.VPDInfoList) > 0:
            FileWrite(File, gSubSectionStart)
            FileWrite(File, "FD VPD Region")
            FileWrite(File, "Base Address:       0x%X" % self.VPDBaseAddress)
            FileWrite(File, "Size:               0x%X (%.0fK)" % (self.VPDSize, self.VPDSize / 1024.0))
            FileWrite(File, gSubSectionSep)
            for item in self.VPDInfoList:
                FileWrite(File, item)
            FileWrite(File, gSubSectionEnd)
        FileWrite(File, gSectionEnd)



##
# Reports platform information
#
# This class reports the whole platform information
#
class PlatformReport(object):
    ##
    # Constructor function for class PlatformReport
    #
    # This constructor function generates PlatformReport object a platform build.
    # It generates report for platform summary, flash, global PCDs and detailed
    # module information for modules involved in platform build.
    #
    # @param self            The object pointer
    # @param Wa              Workspace context information
    # @param MaList          The list of modules in the platform build
    #
    def __init__(self, Wa, MaList, ReportType):
        self._WorkspaceDir = Wa.WorkspaceDir
        self.PlatformName = Wa.Name
        self.PlatformDscPath = Wa.Platform
        self.Architectures = " ".join(Wa.ArchList)
        self.ToolChain = Wa.ToolChain
        self.Target = Wa.BuildTarget
        self.OutputPath = os.path.join(Wa.WorkspaceDir, Wa.OutputDir)
        self.BuildEnvironment = platform.platform()

        self.PcdReport = None
        if "PCD" in ReportType:
            self.PcdReport = PcdReport(Wa)

        self.FdReportList = []
        if "FLASH" in ReportType and Wa.FdfProfile and MaList == None:
            for Fd in Wa.FdfProfile.FdDict:
                self.FdReportList.append(FdReport(Wa.FdfProfile.FdDict[Fd], Wa))

        self.PredictionReport = None
        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
            for Ma in MaList:
                self.ModuleReportList.append(ModuleReport(Ma, ReportType))
        else:
            self._IsModuleBuild = False
            for Pa in Wa.AutoGenObjectList:
                for ModuleKey in Pa.Platform.Modules:
                    self.ModuleReportList.append(ModuleReport(Pa.Platform.Modules[ModuleKey].M, ReportType))



    ##
    # Generate report for the whole platform.
    #
    # This function generates report for platform information.
    # It comprises of platform summary, global PCD, flash and
    # module list sections.
    #
    # @param self            The object pointer
    # @param File            The file object for report
    # @param BuildDuration   The total time to build the modules
    # @param ReportType      The kind of report items in the final report file
    #
    def GenerateReport(self, File, BuildDuration, ReportType):
        FileWrite(File, "Platform Summary")
        FileWrite(File, "Platform Name:        %s" % self.PlatformName)
        FileWrite(File, "Platform DSC Path:    %s" % self.PlatformDscPath)
        FileWrite(File, "Architectures:        %s" % self.Architectures)
        FileWrite(File, "Tool Chain:           %s" % self.ToolChain)
        FileWrite(File, "Target:               %s" % self.Target)
        FileWrite(File, "Output Path:          %s" % self.OutputPath)
        FileWrite(File, "Build Environment:    %s" % self.BuildEnvironment)
        FileWrite(File, "Build Duration:       %s" % BuildDuration)
        FileWrite(File, "Report Content:       %s" % ", ".join(ReportType))

        if GlobalData.MixedPcd:
            FileWrite(File, gSectionStart)
            FileWrite(File, "The following PCDs use different access methods:")
            FileWrite(File, gSectionSep)
            for PcdItem in GlobalData.MixedPcd:
                FileWrite(File, "%s.%s" % (str(PcdItem[1]), str(PcdItem[0])))
            FileWrite(File, gSectionEnd)

        if not self._IsModuleBuild:
            if "PCD" in ReportType:
                self.PcdReport.GenerateReport(File, None)
    
            if "FLASH" in ReportType:
                for FdReportListItem in self.FdReportList:
                    FdReportListItem.GenerateReport(File)

        for ModuleReportItem in self.ModuleReportList:
            ModuleReportItem.GenerateReport(File, self.PcdReport, self.PredictionReport, self.DepexParser, ReportType)

        if not self._IsModuleBuild:
            if "EXECUTION_ORDER" in ReportType:
                self.PredictionReport.GenerateReport(File, None)

## BuildReport class
#
#  This base class contain the routines to collect data and then
#  applies certain format to the output report
#
class BuildReport(object):
    ##
    # Constructor function for class BuildReport
    #
    # This constructor function generates BuildReport object a platform build.
    # It generates report for platform summary, flash, global PCDs and detailed
    # module information for modules involved in platform build.
    #
    # @param self            The object pointer
    # @param ReportFile      The file name to save report file
    # @param ReportType      The kind of report items in the final report file
    #
    def __init__(self, ReportFile, ReportType):
        self.ReportFile = ReportFile
        if ReportFile:
            self.ReportList = []
            self.ReportType = []
            if ReportType: 
                for ReportTypeItem in ReportType:
                    if ReportTypeItem not in self.ReportType:
                        self.ReportType.append(ReportTypeItem)
            else:
                self.ReportType = ["PCD", "LIBRARY", "BUILD_FLAGS", "DEPEX", "HASH", "FLASH", "FIXED_ADDRESS"]
    ##
    # Adds platform report to the list
    #
    # This function adds a platform report to the final report list.
    #
    # @param self            The object pointer
    # @param Wa              Workspace context information
    # @param MaList          The list of modules in the platform build
    #
    def AddPlatformReport(self, Wa, MaList=None):
        if self.ReportFile:
            self.ReportList.append((Wa, MaList))

    ##
    # Generates the final report.
    #
    # This function generates platform build report. It invokes GenerateReport()
    # method for every platform report in the list.
    #
    # @param self            The object pointer
    # @param BuildDuration   The total time to build the modules
    #
    def GenerateReport(self, BuildDuration):
        if self.ReportFile:
            try:
                File = StringIO('')
                for (Wa, MaList) in self.ReportList:
                    PlatformReport(Wa, MaList, self.ReportType).GenerateReport(File, BuildDuration, self.ReportType)
                Content = FileLinesSplit(File.getvalue(), gLineMaxLength)
                SaveFileOnChange(self.ReportFile, Content, True)
                EdkLogger.quiet("Build report can be found at %s" % os.path.abspath(self.ReportFile))
            except IOError:
                EdkLogger.error(None, FILE_WRITE_FAILURE, ExtraData=self.ReportFile)
            except:
                EdkLogger.error("BuildReport", CODE_ERROR, "Unknown fatal error when generating build report", ExtraData=self.ReportFile, RaiseError=False)
                EdkLogger.quiet("(Python %s on %s\n%s)" % (platform.python_version(), sys.platform, traceback.format_exc()))
            File.close()
            
# This acts like the main() function for the script, unless it is 'import'ed into another script.
if __name__ == '__main__':
    pass

