## @file
# Global variables for GenFds
#
#  Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>
#
#  SPDX-License-Identifier: BSD-2-Clause-Patent
#

##
# Import Modules
#
from __future__ import print_function
from __future__ import absolute_import

import Common.LongFilePathOs as os
import sys
from sys import stdout
from subprocess import PIPE,Popen
from struct import Struct
from array import array

from Common.BuildToolError import COMMAND_FAILURE,GENFDS_ERROR
from Common import EdkLogger
from Common.Misc import SaveFileOnChange

from Common.TargetTxtClassObject import TargetTxtDict
from Common.ToolDefClassObject import ToolDefDict,gDefaultToolsDefFile
from AutoGen.BuildEngine import ToolBuildRule
import Common.DataType as DataType
from Common.Misc import PathClass,CreateDirectory
from Common.LongFilePathSupport import OpenLongFilePath as open
from Common.MultipleWorkspace import MultipleWorkspace as mws
import Common.GlobalData as GlobalData
from Common.BuildToolError import *
from AutoGen.AutoGen import CalculatePriorityValue

## Global variables
#
#
class GenFdsGlobalVariable:
    FvDir = ''
    OutputDirDict = {}
    BinDir = ''
    # will be FvDir + os.sep + 'Ffs'
    FfsDir = ''
    FdfParser = None
    LibDir = ''
    WorkSpace = None
    WorkSpaceDir = ''
    ConfDir = ''
    OutputDirFromDscDict = {}
    TargetName = ''
    ToolChainTag = ''
    RuleDict = {}
    ArchList = None
    ActivePlatform = None
    FvAddressFileName = ''
    VerboseMode = False
    DebugLevel = -1
    SharpCounter = 0
    SharpNumberPerLine = 40
    FdfFile = ''
    FdfFileTimeStamp = 0
    FixedLoadAddress = False
    PlatformName = ''

    BuildRuleFamily = DataType.TAB_COMPILER_MSFT
    ToolChainFamily = DataType.TAB_COMPILER_MSFT
    __BuildRuleDatabase = None
    GuidToolDefinition = {}
    FfsCmdDict = {}
    SecCmdList = []
    CopyList   = []
    ModuleFile = ''
    EnableGenfdsMultiThread = True

    #
    # The list whose element are flags to indicate if large FFS or SECTION files exist in FV.
    # At the beginning of each generation of FV, false flag is appended to the list,
    # after the call to GenerateSection returns, check the size of the output file,
    # if it is greater than 0xFFFFFF, the tail flag in list is set to true,
    # and EFI_FIRMWARE_FILE_SYSTEM3_GUID is passed to C GenFv.
    # At the end of generation of FV, pop the flag.
    # List is used as a stack to handle nested FV generation.
    #
    LargeFileInFvFlags = []
    EFI_FIRMWARE_FILE_SYSTEM3_GUID = '5473C07A-3DCB-4dca-BD6F-1E9689E7349A'
    LARGE_FILE_SIZE = 0x1000000

    SectionHeader = Struct("3B 1B")

    # FvName, FdName, CapName in FDF, Image file name
    ImageBinDict = {}

    ## LoadBuildRule
    #
    @staticmethod
    def _LoadBuildRule():
        if GenFdsGlobalVariable.__BuildRuleDatabase:
            return GenFdsGlobalVariable.__BuildRuleDatabase
        BuildRule = ToolBuildRule()
        GenFdsGlobalVariable.__BuildRuleDatabase = BuildRule.ToolBuildRule
        TargetObj = TargetTxtDict()
        ToolDefinitionFile = TargetObj.Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
        if ToolDefinitionFile == '':
            ToolDefinitionFile =  os.path.join('Conf', gDefaultToolsDefFile)
        if os.path.isfile(ToolDefinitionFile):
            ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf")))
            ToolDefinition = ToolDefObj.ToolDef.ToolsDefTxtDatabase
            if DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDefinition \
               and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY] \
               and ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]:
                GenFdsGlobalVariable.BuildRuleFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_BUILDRULEFAMILY][GenFdsGlobalVariable.ToolChainTag]

            if DataType.TAB_TOD_DEFINES_FAMILY in ToolDefinition \
               and GenFdsGlobalVariable.ToolChainTag in ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY] \
               and ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]:
                GenFdsGlobalVariable.ToolChainFamily = ToolDefinition[DataType.TAB_TOD_DEFINES_FAMILY][GenFdsGlobalVariable.ToolChainTag]
        return GenFdsGlobalVariable.__BuildRuleDatabase

    ## GetBuildRules
    #    @param Inf: object of InfBuildData
    #    @param Arch: current arch
    #
    @staticmethod
    def GetBuildRules(Inf, Arch):
        if not Arch:
            Arch = DataType.TAB_COMMON

        if not Arch in GenFdsGlobalVariable.OutputDirDict:
            return {}

        BuildRuleDatabase = GenFdsGlobalVariable._LoadBuildRule()
        if not BuildRuleDatabase:
            return {}

        PathClassObj = PathClass(Inf.MetaFile.File,
                                 GenFdsGlobalVariable.WorkSpaceDir)
        BuildDir = os.path.join(
            GenFdsGlobalVariable.OutputDirDict[Arch],
            Arch,
            PathClassObj.SubDir,
            PathClassObj.BaseName
        )
        BinDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch], Arch)
        Macro = {
        "WORKSPACE":GenFdsGlobalVariable.WorkSpaceDir,
        "MODULE_NAME":Inf.BaseName,
        "MODULE_GUID":Inf.Guid,
        "MODULE_VERSION":Inf.Version,
        "MODULE_TYPE":Inf.ModuleType,
        "MODULE_FILE":str(PathClassObj),
        "MODULE_FILE_BASE_NAME":PathClassObj.BaseName,
        "MODULE_RELATIVE_DIR":PathClassObj.SubDir,
        "MODULE_DIR":PathClassObj.SubDir,
        "BASE_NAME":Inf.BaseName,
        "ARCH":Arch,
        "TOOLCHAIN":GenFdsGlobalVariable.ToolChainTag,
        "TOOLCHAIN_TAG":GenFdsGlobalVariable.ToolChainTag,
        "TOOL_CHAIN_TAG":GenFdsGlobalVariable.ToolChainTag,
        "TARGET":GenFdsGlobalVariable.TargetName,
        "BUILD_DIR":GenFdsGlobalVariable.OutputDirDict[Arch],
        "BIN_DIR":BinDir,
        "LIB_DIR":BinDir,
        "MODULE_BUILD_DIR":BuildDir,
        "OUTPUT_DIR":os.path.join(BuildDir, "OUTPUT"),
        "DEBUG_DIR":os.path.join(BuildDir, "DEBUG")
        }

        BuildRules = {}
        for Type in BuildRuleDatabase.FileTypeList:
            #first try getting build rule by BuildRuleFamily
            RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.BuildRuleFamily]
            if not RuleObject:
                # build type is always module type, but ...
                if Inf.ModuleType != Inf.BuildType:
                    RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.BuildRuleFamily]
            #second try getting build rule by ToolChainFamily
            if not RuleObject:
                RuleObject = BuildRuleDatabase[Type, Inf.BuildType, Arch, GenFdsGlobalVariable.ToolChainFamily]
                if not RuleObject:
                    # build type is always module type, but ...
                    if Inf.ModuleType != Inf.BuildType:
                        RuleObject = BuildRuleDatabase[Type, Inf.ModuleType, Arch, GenFdsGlobalVariable.ToolChainFamily]
            if not RuleObject:
                continue
            RuleObject = RuleObject.Instantiate(Macro)
            BuildRules[Type] = RuleObject
            for Ext in RuleObject.SourceFileExtList:
                BuildRules[Ext] = RuleObject
        return BuildRules

    ## GetModuleCodaTargetList
    #
    #    @param Inf: object of InfBuildData
    #    @param Arch: current arch
    #
    @staticmethod
    def GetModuleCodaTargetList(Inf, Arch):
        BuildRules = GenFdsGlobalVariable.GetBuildRules(Inf, Arch)
        if not BuildRules:
            return []

        TargetList = set()
        FileList = []

        if not Inf.IsBinaryModule:
            for File in Inf.Sources:
                if File.TagName in {"", DataType.TAB_STAR, GenFdsGlobalVariable.ToolChainTag} and \
                    File.ToolChainFamily in {"", DataType.TAB_STAR, GenFdsGlobalVariable.ToolChainFamily}:
                    FileList.append((File, DataType.TAB_UNKNOWN_FILE))

        for File in Inf.Binaries:
            if File.Target in {DataType.TAB_COMMON, DataType.TAB_STAR, GenFdsGlobalVariable.TargetName}:
                FileList.append((File, File.Type))

        for File, FileType in FileList:
            LastTarget = None
            RuleChain = []
            SourceList = [File]
            Index = 0
            while Index < len(SourceList):
                Source = SourceList[Index]
                Index = Index + 1

                if File.IsBinary and File == Source and Inf.Binaries and File in Inf.Binaries:
                    # Skip all files that are not binary libraries
                    if not Inf.LibraryClass:
                        continue
                    RuleObject = BuildRules[DataType.TAB_DEFAULT_BINARY_FILE]
                elif FileType in BuildRules:
                    RuleObject = BuildRules[FileType]
                elif Source.Ext in BuildRules:
                    RuleObject = BuildRules[Source.Ext]
                else:
                    # stop at no more rules
                    if LastTarget:
                        TargetList.add(str(LastTarget))
                    break

                FileType = RuleObject.SourceFileType

                # stop at STATIC_LIBRARY for library
                if Inf.LibraryClass and FileType == DataType.TAB_STATIC_LIBRARY:
                    if LastTarget:
                        TargetList.add(str(LastTarget))
                    break

                Target = RuleObject.Apply(Source)
                if not Target:
                    if LastTarget:
                        TargetList.add(str(LastTarget))
                    break
                elif not Target.Outputs:
                    # Only do build for target with outputs
                    TargetList.add(str(Target))

                # to avoid cyclic rule
                if FileType in RuleChain:
                    break

                RuleChain.append(FileType)
                SourceList.extend(Target.Outputs)
                LastTarget = Target
                FileType = DataType.TAB_UNKNOWN_FILE
                for Cmd in Target.Commands:
                    if "$(CP)" == Cmd.split()[0]:
                        CpTarget = Cmd.split()[2]
                        TargetList.add(CpTarget)

        return list(TargetList)

    ## SetDir()
    #
    #   @param  OutputDir           Output directory
    #   @param  FdfParser           FDF contents parser
    #   @param  Workspace           The directory of workspace
    #   @param  ArchList            The Arch list of platform
    #
    @staticmethod
    def SetDir (OutputDir, FdfParser, WorkSpace, ArchList):
        GenFdsGlobalVariable.VerboseLogger("GenFdsGlobalVariable.OutputDir:%s" % OutputDir)
        GenFdsGlobalVariable.FdfParser = FdfParser
        GenFdsGlobalVariable.WorkSpace = WorkSpace
        GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY)
        if not os.path.exists(GenFdsGlobalVariable.FvDir):
            os.makedirs(GenFdsGlobalVariable.FvDir)
        GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')
        if not os.path.exists(GenFdsGlobalVariable.FfsDir):
            os.makedirs(GenFdsGlobalVariable.FfsDir)

        #
        # Create FV Address inf file
        #
        GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')
        FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')
        #
        # Add [Options]
        #
        FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK)
        BsAddress = '0'
        for Arch in ArchList:
            if GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress:
                BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].BsBaseAddress
                break

        FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
                                       BsAddress + \
                                       DataType.TAB_LINE_BREAK)

        RtAddress = '0'
        for Arch in reversed(ArchList):
            temp = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag].RtBaseAddress
            if temp:
                RtAddress = temp
                break

        FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
                                       RtAddress + \
                                       DataType.TAB_LINE_BREAK)

        FvAddressFile.close()

    @staticmethod
    def SetEnv(FdfParser, WorkSpace, ArchList, GlobalData):
        GenFdsGlobalVariable.ModuleFile = WorkSpace.ModuleFile
        GenFdsGlobalVariable.FdfParser = FdfParser
        GenFdsGlobalVariable.WorkSpace = WorkSpace.Db
        GenFdsGlobalVariable.ArchList = ArchList
        GenFdsGlobalVariable.ToolChainTag = GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]
        GenFdsGlobalVariable.TargetName = GlobalData.gGlobalDefines["TARGET"]
        GenFdsGlobalVariable.ActivePlatform = GlobalData.gActivePlatform
        GenFdsGlobalVariable.ConfDir  = GlobalData.gConfDirectory
        GenFdsGlobalVariable.EnableGenfdsMultiThread = GlobalData.gEnableGenfdsMultiThread
        for Arch in ArchList:
            GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.normpath(
                os.path.join(GlobalData.gWorkspace,
                             WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],
                             GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory,
                             GlobalData.gGlobalDefines['TARGET'] +'_' + GlobalData.gGlobalDefines['TOOLCHAIN']))
            GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = os.path.normpath(
                             WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,
                             GlobalData.gGlobalDefines['TARGET'], GlobalData.gGlobalDefines['TOOLCHAIN']].OutputDirectory)
            GenFdsGlobalVariable.PlatformName = WorkSpace.Db.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,
                                                                      GlobalData.gGlobalDefines['TARGET'],
                                                                      GlobalData.gGlobalDefines['TOOLCHAIN']].PlatformName
        GenFdsGlobalVariable.FvDir = os.path.join(GenFdsGlobalVariable.OutputDirDict[ArchList[0]], DataType.TAB_FV_DIRECTORY)
        if not os.path.exists(GenFdsGlobalVariable.FvDir):
            os.makedirs(GenFdsGlobalVariable.FvDir)
        GenFdsGlobalVariable.FfsDir = os.path.join(GenFdsGlobalVariable.FvDir, 'Ffs')
        if not os.path.exists(GenFdsGlobalVariable.FfsDir):
            os.makedirs(GenFdsGlobalVariable.FfsDir)

        #
        # Create FV Address inf file
        #
        GenFdsGlobalVariable.FvAddressFileName = os.path.join(GenFdsGlobalVariable.FfsDir, 'FvAddress.inf')
        FvAddressFile = open(GenFdsGlobalVariable.FvAddressFileName, 'w')
        #
        # Add [Options]
        #
        FvAddressFile.writelines("[options]" + DataType.TAB_LINE_BREAK)
        BsAddress = '0'
        for Arch in ArchList:
            BsAddress = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch,
                                                                   GlobalData.gGlobalDefines['TARGET'],
                                                                   GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].BsBaseAddress
            if BsAddress:
                break

        FvAddressFile.writelines("EFI_BOOT_DRIVER_BASE_ADDRESS = " + \
                                 BsAddress + \
                                 DataType.TAB_LINE_BREAK)

        RtAddress = '0'
        for Arch in reversed(ArchList):
            temp = GenFdsGlobalVariable.WorkSpace.BuildObject[
                GenFdsGlobalVariable.ActivePlatform, Arch, GlobalData.gGlobalDefines['TARGET'],
                GlobalData.gGlobalDefines["TOOL_CHAIN_TAG"]].RtBaseAddress
            if temp:
                RtAddress = temp
                break

        FvAddressFile.writelines("EFI_RUNTIME_DRIVER_BASE_ADDRESS = " + \
                                 RtAddress + \
                                 DataType.TAB_LINE_BREAK)

        FvAddressFile.close()

    ## ReplaceWorkspaceMacro()
    #
    #   @param  String           String that may contain macro
    #
    @staticmethod
    def ReplaceWorkspaceMacro(String):
        String = mws.handleWsMacro(String)
        Str = String.replace('$(WORKSPACE)', GenFdsGlobalVariable.WorkSpaceDir)
        if os.path.exists(Str):
            if not os.path.isabs(Str):
                Str = os.path.abspath(Str)
        else:
            Str = mws.join(GenFdsGlobalVariable.WorkSpaceDir, String)
        return os.path.normpath(Str)

    ## Check if the input files are newer than output files
    #
    #   @param  Output          Path of output file
    #   @param  Input           Path list of input files
    #
    #   @retval True            if Output doesn't exist, or any Input is newer
    #   @retval False           if all Input is older than Output
    #
    @staticmethod
    def NeedsUpdate(Output, Input):
        if not os.path.exists(Output):
            return True
        # always update "Output" if no "Input" given
        if not Input:
            return True

        # if fdf file is changed after the 'Output" is generated, update the 'Output'
        OutputTime = os.path.getmtime(Output)
        if GenFdsGlobalVariable.FdfFileTimeStamp > OutputTime:
            return True

        for F in Input:
            # always update "Output" if any "Input" doesn't exist
            if not os.path.exists(F):
                return True
            # always update "Output" if any "Input" is newer than "Output"
            if os.path.getmtime(F) > OutputTime:
                return True
        return False

    @staticmethod
    def GenerateSection(Output, Input, Type=None, CompressionType=None, Guid=None,
                        GuidHdrLen=None, GuidAttr=[], Ui=None, Ver=None, InputAlign=[], BuildNumber=None, DummyFile=None, IsMakefile=False):
        Cmd = ["GenSec"]
        if Type:
            Cmd += ("-s", Type)
        if CompressionType:
            Cmd += ("-c", CompressionType)
        if Guid:
            Cmd += ("-g", Guid)
        if DummyFile:
            Cmd += ("--dummy", DummyFile)
        if GuidHdrLen:
            Cmd += ("-l", GuidHdrLen)
        #Add each guided attribute
        for Attr in GuidAttr:
            Cmd += ("-r", Attr)
        #Section Align is only for dummy section without section type
        for SecAlign in InputAlign:
            Cmd += ("--sectionalign", SecAlign)

        CommandFile = Output + '.txt'
        if Ui:
            if IsMakefile:
                if Ui == "$(MODULE_NAME)":
                    Cmd += ('-n', Ui)
                else:
                    Cmd += ("-n", '"' + Ui + '"')
                Cmd += ("-o", Output)
                if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
                    GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
            else:
                SectionData = array('B', [0, 0, 0, 0])
                SectionData.fromlist(array('B',Ui.encode('utf-16-le')).tolist())
                SectionData.append(0)
                SectionData.append(0)
                Len = len(SectionData)
                GenFdsGlobalVariable.SectionHeader.pack_into(SectionData, 0, Len & 0xff, (Len >> 8) & 0xff, (Len >> 16) & 0xff, 0x15)


                DirName = os.path.dirname(Output)
                if not CreateDirectory(DirName):
                    EdkLogger.error(None, FILE_CREATE_FAILURE, "Could not create directory %s" % DirName)
                else:
                    if DirName == '':
                        DirName = os.getcwd()
                    if not os.access(DirName, os.W_OK):
                        EdkLogger.error(None, PERMISSION_FAILURE, "Do not have write permission on directory %s" % DirName)

                try:
                    with open(Output, "wb") as Fd:
                        SectionData.tofile(Fd)
                        Fd.flush()
                except IOError as X:
                    EdkLogger.error(None, FILE_CREATE_FAILURE, ExtraData='IOError %s' % X)

        elif Ver:
            Cmd += ("-n", Ver)
            if BuildNumber:
                Cmd += ("-j", BuildNumber)
            Cmd += ("-o", Output)

            SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
            if IsMakefile:
                if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
                    GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
            else:
                if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
                    return
                GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
        else:
            Cmd += ("-o", Output)
            Cmd += Input

            SaveFileOnChange(CommandFile, ' '.join(Cmd), False)
            if IsMakefile:
                if sys.platform == "win32":
                    Cmd = ['if', 'exist', Input[0]] + Cmd
                else:
                    Cmd = ['-test', '-e', Input[0], "&&"] + Cmd
                if ' '.join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
                    GenFdsGlobalVariable.SecCmdList.append(' '.join(Cmd).strip())
            elif GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
                GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
                GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate section")
                if (os.path.getsize(Output) >= GenFdsGlobalVariable.LARGE_FILE_SIZE and
                    GenFdsGlobalVariable.LargeFileInFvFlags):
                    GenFdsGlobalVariable.LargeFileInFvFlags[-1] = True

    @staticmethod
    def GetAlignment (AlignString):
        if not AlignString:
            return 0
        if AlignString.endswith('K'):
            return int (AlignString.rstrip('K')) * 1024
        if AlignString.endswith('M'):
            return int (AlignString.rstrip('M')) * 1024 * 1024
        if AlignString.endswith('G'):
            return int (AlignString.rstrip('G')) * 1024 * 1024 * 1024
        return int (AlignString)

    @staticmethod
    def GenerateFfs(Output, Input, Type, Guid, Fixed=False, CheckSum=False, Align=None,
                    SectionAlign=None, MakefilePath=None):
        Cmd = ["GenFfs", "-t", Type, "-g", Guid]
        mFfsValidAlign = ["0", "8", "16", "128", "512", "1K", "4K", "32K", "64K", "128K", "256K", "512K", "1M", "2M", "4M", "8M", "16M"]
        if Fixed == True:
            Cmd.append("-x")
        if CheckSum:
            Cmd.append("-s")
        if Align:
            if Align not in mFfsValidAlign:
                Align = GenFdsGlobalVariable.GetAlignment (Align)
                for index in range(0, len(mFfsValidAlign) - 1):
                    if ((Align > GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index])) and (Align <= GenFdsGlobalVariable.GetAlignment(mFfsValidAlign[index + 1]))):
                        break
                Align = mFfsValidAlign[index + 1]
            Cmd += ("-a", Align)

        Cmd += ("-o", Output)
        for I in range(0, len(Input)):
            if MakefilePath:
                Cmd += ("-oi", Input[I])
            else:
                Cmd += ("-i", Input[I])
            if SectionAlign and SectionAlign[I]:
                Cmd += ("-n", SectionAlign[I])

        CommandFile = Output + '.txt'
        SaveFileOnChange(CommandFile, ' '.join(Cmd), False)

        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
        if MakefilePath:
            if (tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)) not in GenFdsGlobalVariable.FfsCmdDict:
                GenFdsGlobalVariable.FfsCmdDict[tuple(Cmd), tuple(GenFdsGlobalVariable.SecCmdList), tuple(GenFdsGlobalVariable.CopyList)] = MakefilePath
            GenFdsGlobalVariable.SecCmdList = []
            GenFdsGlobalVariable.CopyList = []
        else:
            if not GenFdsGlobalVariable.NeedsUpdate(Output, list(Input) + [CommandFile]):
                return
            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FFS")

    @staticmethod
    def GenerateFirmwareVolume(Output, Input, BaseAddress=None, ForceRebase=None, Capsule=False, Dump=False,
                               AddressFile=None, MapFile=None, FfsList=[], FileSystemGuid=None):
        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input+FfsList):
            return
        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))

        Cmd = ["GenFv"]
        if BaseAddress:
            Cmd += ("-r", BaseAddress)

        if ForceRebase == False:
            Cmd += ("-F", "FALSE")
        elif ForceRebase == True:
            Cmd += ("-F", "TRUE")

        if Capsule:
            Cmd.append("-c")
        if Dump:
            Cmd.append("-p")
        if AddressFile:
            Cmd += ("-a", AddressFile)
        if MapFile:
            Cmd += ("-m", MapFile)
        if FileSystemGuid:
            Cmd += ("-g", FileSystemGuid)
        Cmd += ("-o", Output)
        for I in Input:
            Cmd += ("-i", I)

        GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")

    @staticmethod
    def GenerateFirmwareImage(Output, Input, Type="efi", SubType=None, Zero=False,
                              Strip=False, Replace=False, TimeStamp=None, Join=False,
                              Align=None, Padding=None, Convert=False, IsMakefile=False):
        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:
            return
        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))

        Cmd = ["GenFw"]
        if Type.lower() == "te":
            Cmd.append("-t")
        if SubType:
            Cmd += ("-e", SubType)
        if TimeStamp:
            Cmd += ("-s", TimeStamp)
        if Align:
            Cmd += ("-a", Align)
        if Padding:
            Cmd += ("-p", Padding)
        if Zero:
            Cmd.append("-z")
        if Strip:
            Cmd.append("-l")
        if Replace:
            Cmd.append("-r")
        if Join:
            Cmd.append("-j")
        if Convert:
            Cmd.append("-m")
        Cmd += ("-o", Output)
        Cmd += Input
        if IsMakefile:
            if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
                GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())
        else:
            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate firmware image")

    @staticmethod
    def GenerateOptionRom(Output, EfiInput, BinaryInput, Compress=False, ClassCode=None,
                        Revision=None, DeviceId=None, VendorId=None, IsMakefile=False):
        InputList = []
        Cmd = ["EfiRom"]
        if EfiInput:

            if Compress:
                Cmd.append("-ec")
            else:
                Cmd.append("-e")

            for EfiFile in EfiInput:
                Cmd.append(EfiFile)
                InputList.append (EfiFile)

        if BinaryInput:
            Cmd.append("-b")
            for BinFile in BinaryInput:
                Cmd.append(BinFile)
                InputList.append (BinFile)

        # Check List
        if not GenFdsGlobalVariable.NeedsUpdate(Output, InputList) and not IsMakefile:
            return
        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, InputList))

        if ClassCode:
            Cmd += ("-l", ClassCode)
        if Revision:
            Cmd += ("-r", Revision)
        if DeviceId:
            Cmd += ("-i", DeviceId)
        if VendorId:
            Cmd += ("-f", VendorId)

        Cmd += ("-o", Output)
        if IsMakefile:
            if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
                GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())
        else:
            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate option rom")

    @staticmethod
    def GuidTool(Output, Input, ToolPath, Options='', returnValue=[], IsMakefile=False):
        if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:
            return
        GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))

        Cmd = [ToolPath, ]
        Cmd += Options.split(' ')
        Cmd += ("-o", Output)
        Cmd += Input
        if IsMakefile:
            if " ".join(Cmd).strip() not in GenFdsGlobalVariable.SecCmdList:
                GenFdsGlobalVariable.SecCmdList.append(" ".join(Cmd).strip())
        else:
            GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to call " + ToolPath, returnValue)

    @staticmethod
    def CallExternalTool (cmd, errorMess, returnValue=[]):

        if type(cmd) not in (tuple, list):
            GenFdsGlobalVariable.ErrorLogger("ToolError!  Invalid parameter type in call to CallExternalTool")

        if GenFdsGlobalVariable.DebugLevel != -1:
            cmd += ('--debug', str(GenFdsGlobalVariable.DebugLevel))
            GenFdsGlobalVariable.InfLogger (cmd)

        if GenFdsGlobalVariable.VerboseMode:
            cmd += ('-v',)
            GenFdsGlobalVariable.InfLogger (cmd)
        else:
            stdout.write ('#')
            stdout.flush()
            GenFdsGlobalVariable.SharpCounter = GenFdsGlobalVariable.SharpCounter + 1
            if GenFdsGlobalVariable.SharpCounter % GenFdsGlobalVariable.SharpNumberPerLine == 0:
                stdout.write('\n')

        try:
            PopenObject = Popen(' '.join(cmd), stdout=PIPE, stderr=PIPE, shell=True)
        except Exception as X:
            EdkLogger.error("GenFds", COMMAND_FAILURE, ExtraData="%s: %s" % (str(X), cmd[0]))
        (out, error) = PopenObject.communicate()

        while PopenObject.returncode is None:
            PopenObject.wait()
        if returnValue != [] and returnValue[0] != 0:
            #get command return value
            returnValue[0] = PopenObject.returncode
            return
        if PopenObject.returncode != 0 or GenFdsGlobalVariable.VerboseMode or GenFdsGlobalVariable.DebugLevel != -1:
            GenFdsGlobalVariable.InfLogger ("Return Value = %d" % PopenObject.returncode)
            GenFdsGlobalVariable.InfLogger(out.decode(encoding='utf-8', errors='ignore'))
            GenFdsGlobalVariable.InfLogger(error.decode(encoding='utf-8', errors='ignore'))
            if PopenObject.returncode != 0:
                print("###", cmd)
                EdkLogger.error("GenFds", COMMAND_FAILURE, errorMess)

    @staticmethod
    def VerboseLogger (msg):
        EdkLogger.verbose(msg)

    @staticmethod
    def InfLogger (msg):
        EdkLogger.info(msg)

    @staticmethod
    def ErrorLogger (msg, File=None, Line=None, ExtraData=None):
        EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)

    @staticmethod
    def DebugLogger (Level, msg):
        EdkLogger.debug(Level, msg)

    ## MacroExtend()
    #
    #   @param  Str           String that may contain macro
    #   @param  MacroDict     Dictionary that contains macro value pair
    #
    @staticmethod
    def MacroExtend (Str, MacroDict=None, Arch=DataType.TAB_COMMON):
        if Str is None:
            return None

        Dict = {'$(WORKSPACE)': GenFdsGlobalVariable.WorkSpaceDir,
#                '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
                '$(TARGET)': GenFdsGlobalVariable.TargetName,
                '$(TOOL_CHAIN_TAG)': GenFdsGlobalVariable.ToolChainTag,
                '$(SPACE)': ' '
               }

        if Arch != DataType.TAB_COMMON and Arch in GenFdsGlobalVariable.ArchList:
            OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch]
        else:
            OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]

        Dict['$(OUTPUT_DIRECTORY)'] = OutputDir

        if MacroDict:
            Dict.update(MacroDict)

        for key in Dict:
            if Str.find(key) >= 0:
                Str = Str.replace (key, Dict[key])

        if Str.find('$(ARCH)') >= 0:
            if len(GenFdsGlobalVariable.ArchList) == 1:
                Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0])
            else:
                EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str)

        return Str

    ## GetPcdValue()
    #
    #   @param  PcdPattern           pattern that labels a PCD.
    #
    @staticmethod
    def GetPcdValue (PcdPattern):
        if PcdPattern is None:
            return None
        if PcdPattern.startswith('PCD('):
            PcdPair = PcdPattern[4:].rstrip(')').strip().split('.')
        else:
            PcdPair = PcdPattern.strip().split('.')
        TokenSpace = PcdPair[0]
        TokenCName = PcdPair[1]

        for Arch in GenFdsGlobalVariable.ArchList:
            Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
            PcdDict = Platform.Pcds
            for Key in PcdDict:
                PcdObj = PcdDict[Key]
                if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
                    if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD:
                        EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
                    if PcdObj.DatumType != DataType.TAB_VOID:
                        EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)

                    return PcdObj.DefaultValue

            for Package in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,
                                                                         Arch,
                                                                         GenFdsGlobalVariable.TargetName,
                                                                         GenFdsGlobalVariable.ToolChainTag):
                PcdDict = Package.Pcds
                for Key in PcdDict:
                    PcdObj = PcdDict[Key]
                    if (PcdObj.TokenCName == TokenCName) and (PcdObj.TokenSpaceGuidCName == TokenSpace):
                        if PcdObj.Type != DataType.TAB_PCDS_FIXED_AT_BUILD:
                            EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not FixedAtBuild type." % PcdPattern)
                        if PcdObj.DatumType != DataType.TAB_VOID:
                            EdkLogger.error("GenFds", GENFDS_ERROR, "%s is not VOID* datum type." % PcdPattern)

                        return PcdObj.DefaultValue

        return ''

## FindExtendTool()
#
#  Find location of tools to process data
#
#  @param  KeyStringList    Filter for inputs of section generation
#  @param  CurrentArchList  Arch list
#  @param  NameGuid         The Guid name
#
def FindExtendTool(KeyStringList, CurrentArchList, NameGuid):
    if GenFdsGlobalVariable.GuidToolDefinition:
        if NameGuid in GenFdsGlobalVariable.GuidToolDefinition:
            return GenFdsGlobalVariable.GuidToolDefinition[NameGuid]

    ToolDefObj = ToolDefDict((os.path.join(os.getenv("WORKSPACE"), "Conf")))
    ToolDef = ToolDefObj.ToolDef
    ToolDb = ToolDef.ToolsDefTxtDatabase
    # if user not specify filter, try to deduce it from global data.
    if KeyStringList is None or KeyStringList == []:
        Target = GenFdsGlobalVariable.TargetName
        ToolChain = GenFdsGlobalVariable.ToolChainTag
        if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:
            EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain)
        KeyStringList = [Target + '_' + ToolChain + '_' + CurrentArchList[0]]
        for Arch in CurrentArchList:
            if Target + '_' + ToolChain + '_' + Arch not in KeyStringList:
                KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)

    ToolPathTmp = None
    ToolOption = None
    for Arch in CurrentArchList:
        MatchItem = None
        MatchPathItem = None
        MatchOptionsItem = None
        for KeyString in KeyStringList:
            KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_')
            if KeyStringArch != Arch:
                continue
            for Item in ToolDef.ToolsDefTxtDictionary:
                if len(Item.split('_')) < 5:
                    continue
                ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item.split('_')
                if ItemTarget == DataType.TAB_STAR:
                    ItemTarget = KeyStringBuildTarget
                if ItemToolChain == DataType.TAB_STAR:
                    ItemToolChain = KeyStringToolChain
                if ItemArch == DataType.TAB_STAR:
                    ItemArch = KeyStringArch
                if ItemTarget != KeyStringBuildTarget:
                    continue
                if ItemToolChain != KeyStringToolChain:
                    continue
                if ItemArch != KeyStringArch:
                    continue
                if ItemAttr != DataType.TAB_GUID:
                    # Not GUID attribute
                    continue
                if ToolDef.ToolsDefTxtDictionary[Item].lower() != NameGuid.lower():
                    # No GUID value match
                    continue
                if MatchItem:
                    if MatchItem.split('_')[3] == ItemTool:
                        # Tool name is the same
                        continue
                    if CalculatePriorityValue(MatchItem) > CalculatePriorityValue(Item):
                        # Current MatchItem is higher priority than new match item
                        continue
                MatchItem = Item
            if not MatchItem:
                continue
            ToolName = MatchItem.split('_')[3]
            for Item in ToolDef.ToolsDefTxtDictionary:
                if len(Item.split('_')) < 5:
                    continue
                ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item.split('_')
                if ItemTarget == DataType.TAB_STAR:
                    ItemTarget = KeyStringBuildTarget
                if ItemToolChain == DataType.TAB_STAR:
                    ItemToolChain = KeyStringToolChain
                if ItemArch == DataType.TAB_STAR:
                    ItemArch = KeyStringArch
                if ItemTarget != KeyStringBuildTarget:
                    continue
                if ItemToolChain != KeyStringToolChain:
                    continue
                if ItemArch != KeyStringArch:
                    continue
                if ItemTool != ToolName:
                    continue
                if ItemAttr == 'PATH':
                    if MatchPathItem:
                        if CalculatePriorityValue(MatchPathItem) <= CalculatePriorityValue(Item):
                            MatchPathItem = Item
                    else:
                        MatchPathItem = Item
                if ItemAttr == 'FLAGS':
                    if MatchOptionsItem:
                        if CalculatePriorityValue(MatchOptionsItem) <= CalculatePriorityValue(Item):
                            MatchOptionsItem = Item
                    else:
                        MatchOptionsItem = Item
        if MatchPathItem:
            ToolPathTmp = ToolDef.ToolsDefTxtDictionary[MatchPathItem]
        if MatchOptionsItem:
            ToolOption = ToolDef.ToolsDefTxtDictionary[MatchOptionsItem]

    for Arch in CurrentArchList:
        MatchItem = None
        MatchPathItem = None
        MatchOptionsItem = None
        for KeyString in KeyStringList:
            KeyStringBuildTarget, KeyStringToolChain, KeyStringArch = KeyString.split('_')
            if KeyStringArch != Arch:
                continue
            Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, KeyStringBuildTarget, KeyStringToolChain]
            for Item in Platform.BuildOptions:
                if len(Item[1].split('_')) < 5:
                    continue
                ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item[1].split('_')
                if ItemTarget == DataType.TAB_STAR:
                    ItemTarget = KeyStringBuildTarget
                if ItemToolChain == DataType.TAB_STAR:
                    ItemToolChain = KeyStringToolChain
                if ItemArch == DataType.TAB_STAR:
                    ItemArch = KeyStringArch
                if ItemTarget != KeyStringBuildTarget:
                    continue
                if ItemToolChain != KeyStringToolChain:
                    continue
                if ItemArch != KeyStringArch:
                    continue
                if ItemAttr != DataType.TAB_GUID:
                    # Not GUID attribute match
                    continue
                if Platform.BuildOptions[Item].lower() != NameGuid.lower():
                    # No GUID value match
                    continue
                if MatchItem:
                    if MatchItem[1].split('_')[3] == ItemTool:
                        # Tool name is the same
                        continue
                    if CalculatePriorityValue(MatchItem[1]) > CalculatePriorityValue(Item[1]):
                        # Current MatchItem is higher priority than new match item
                        continue
                MatchItem = Item
            if not MatchItem:
                continue
            ToolName = MatchItem[1].split('_')[3]
            for Item in Platform.BuildOptions:
                if len(Item[1].split('_')) < 5:
                    continue
                ItemTarget, ItemToolChain, ItemArch, ItemTool, ItemAttr = Item[1].split('_')
                if ItemTarget == DataType.TAB_STAR:
                    ItemTarget = KeyStringBuildTarget
                if ItemToolChain == DataType.TAB_STAR:
                    ItemToolChain = KeyStringToolChain
                if ItemArch == DataType.TAB_STAR:
                    ItemArch = KeyStringArch
                if ItemTarget != KeyStringBuildTarget:
                    continue
                if ItemToolChain != KeyStringToolChain:
                    continue
                if ItemArch != KeyStringArch:
                    continue
                if ItemTool != ToolName:
                    continue
                if ItemAttr == 'PATH':
                    if MatchPathItem:
                        if CalculatePriorityValue(MatchPathItem[1]) <= CalculatePriorityValue(Item[1]):
                            MatchPathItem = Item
                    else:
                        MatchPathItem = Item
                if ItemAttr == 'FLAGS':
                    if MatchOptionsItem:
                        if CalculatePriorityValue(MatchOptionsItem[1]) <= CalculatePriorityValue(Item[1]):
                            MatchOptionsItem = Item
                    else:
                        MatchOptionsItem = Item
    if MatchPathItem:
        ToolPathTmp = Platform.BuildOptions[MatchPathItem]
    if MatchOptionsItem:
        ToolOption = Platform.BuildOptions[MatchOptionsItem]
    GenFdsGlobalVariable.GuidToolDefinition[NameGuid] = (ToolPathTmp, ToolOption)
    return ToolPathTmp, ToolOption
