]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/GenFds/FfsInfStatement.py
BaseTools:Make BaseTools support new rules to generate RAW FFS FILE
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FfsInfStatement.py
index a7a65919d7cd977d6f3c12f5769e01cb66f362e1..cd3b0f647793da01772e6fee4a98e3c576a6026d 100644 (file)
@@ -1,51 +1,54 @@
 ## @file\r
 # process FFS generation from INF statement\r
 #\r
 ## @file\r
 # process FFS generation from INF statement\r
 #\r
-#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2014-2016 Hewlett-Packard Development Company, L.P.<BR>\r
 #\r
 #\r
-#  This program and the accompanying materials\r
-#  are licensed and made available under the terms and conditions of the BSD License\r
-#  which accompanies this distribution.  The full text of the license may be found at\r
-#  http://opensource.org/licenses/bsd-license.php\r
-#\r
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
 \r
 ##\r
 # Import Modules\r
 #\r
 #\r
 \r
 ##\r
 # Import Modules\r
 #\r
-import Rule\r
+from __future__ import absolute_import\r
+from . import Rule\r
 import Common.LongFilePathOs as os\r
 import Common.LongFilePathOs as os\r
-import StringIO\r
+from io import BytesIO\r
 from struct import *\r
 from struct import *\r
-from GenFdsGlobalVariable import GenFdsGlobalVariable\r
-import Ffs\r
+from .GenFdsGlobalVariable import GenFdsGlobalVariable\r
+from .Ffs import SectionSuffix,FdfFvFileTypeToFileType\r
 import subprocess\r
 import sys\r
 import subprocess\r
 import sys\r
-import Section\r
-import RuleSimpleFile\r
-import RuleComplexFile\r
+from . import Section\r
+from . import RuleSimpleFile\r
+from . import RuleComplexFile\r
 from CommonDataClass.FdfClass import FfsInfStatementClassObject\r
 from CommonDataClass.FdfClass import FfsInfStatementClassObject\r
-from Common.String import *\r
+from Common.MultipleWorkspace import MultipleWorkspace as mws\r
+from Common.DataType import SUP_MODULE_USER_DEFINED\r
+from Common.StringUtils import *\r
 from Common.Misc import PathClass\r
 from Common.Misc import GuidStructureByteArrayToGuidString\r
 from Common.Misc import PathClass\r
 from Common.Misc import GuidStructureByteArrayToGuidString\r
+from Common.Misc import ProcessDuplicatedInf\r
+from Common.Misc import GetVariableOffset\r
 from Common import EdkLogger\r
 from Common.BuildToolError import *\r
 from Common import EdkLogger\r
 from Common.BuildToolError import *\r
-from GuidSection import GuidSection\r
-from FvImageSection import FvImageSection\r
+from .GuidSection import GuidSection\r
+from .FvImageSection import FvImageSection\r
 from Common.Misc import PeImageClass\r
 from AutoGen.GenDepex import DependencyExpression\r
 from PatchPcdValue.PatchPcdValue import PatchBinaryFile\r
 from Common.LongFilePathSupport import CopyLongFilePath\r
 from Common.LongFilePathSupport import OpenLongFilePath as open\r
 from Common.Misc import PeImageClass\r
 from AutoGen.GenDepex import DependencyExpression\r
 from PatchPcdValue.PatchPcdValue import PatchBinaryFile\r
 from Common.LongFilePathSupport import CopyLongFilePath\r
 from Common.LongFilePathSupport import OpenLongFilePath as open\r
+import Common.GlobalData as GlobalData\r
+from .DepexSection import DepexSection\r
+from Common.Misc import SaveFileOnChange\r
+from Common.Expression import *\r
+from Common.DataType import *\r
 \r
 ## generate FFS from INF\r
 #\r
 #\r
 class FfsInfStatement(FfsInfStatementClassObject):\r
 \r
 ## generate FFS from INF\r
 #\r
 #\r
 class FfsInfStatement(FfsInfStatementClassObject):\r
-    ## The mapping dictionary from datum type to its maximum number.\r
-    _MAX_SIZE_TYPE = {"BOOLEAN":0x01, "UINT8":0xFF, "UINT16":0xFFFF, "UINT32":0xFFFFFFFF, "UINT64":0xFFFFFFFFFFFFFFFF}\r
     ## The constructor\r
     #\r
     #   @param  self        The object pointer\r
     ## The constructor\r
     #\r
     #   @param  self        The object pointer\r
@@ -64,6 +67,10 @@ class FfsInfStatement(FfsInfStatementClassObject):
         self.CurrentLineContent = None\r
         self.FileName = None\r
         self.InfFileName = None\r
         self.CurrentLineContent = None\r
         self.FileName = None\r
         self.InfFileName = None\r
+        self.OverrideGuid = None\r
+        self.PatchedBinFile = ''\r
+        self.MacroDict = {}\r
+        self.Depex = False\r
 \r
     ## GetFinalTargetSuffixMap() method\r
     #\r
 \r
     ## GetFinalTargetSuffixMap() method\r
     #\r
@@ -77,12 +84,12 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 self.FinalTargetSuffixMap.setdefault(os.path.splitext(File)[1], []).append(File)\r
 \r
             # Check if current INF module has DEPEX\r
                 self.FinalTargetSuffixMap.setdefault(os.path.splitext(File)[1], []).append(File)\r
 \r
             # Check if current INF module has DEPEX\r
-            if '.depex' not in self.FinalTargetSuffixMap and self.InfModule.ModuleType != "USER_DEFINED" \\r
+            if '.depex' not in self.FinalTargetSuffixMap and self.InfModule.ModuleType != SUP_MODULE_USER_DEFINED \\r
                 and not self.InfModule.DxsFile and not self.InfModule.LibraryClass:\r
                 ModuleType = self.InfModule.ModuleType\r
                 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
 \r
                 and not self.InfModule.DxsFile and not self.InfModule.LibraryClass:\r
                 ModuleType = self.InfModule.ModuleType\r
                 PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
 \r
-                if ModuleType != DataType.SUP_MODULE_USER_DEFINED:\r
+                if ModuleType != SUP_MODULE_USER_DEFINED:\r
                     for LibraryClass in PlatformDataBase.LibraryClasses.GetKeys():\r
                         if LibraryClass.startswith("NULL") and PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]:\r
                             self.InfModule.LibraryClasses[LibraryClass] = PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]\r
                     for LibraryClass in PlatformDataBase.LibraryClasses.GetKeys():\r
                         if LibraryClass.startswith("NULL") and PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]:\r
                             self.InfModule.LibraryClasses[LibraryClass] = PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]\r
@@ -140,12 +147,14 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  self        The object pointer\r
     #   @param  Dict        dictionary contains macro and value pair\r
     #\r
     #   @param  self        The object pointer\r
     #   @param  Dict        dictionary contains macro and value pair\r
     #\r
-    def __InfParse__(self, Dict = {}):\r
+    def __InfParse__(self, Dict = None, IsGenFfs=False):\r
 \r
         GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName)\r
 \r
         self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '')\r
 \r
         GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName)\r
 \r
         self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '')\r
-        if self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' :\r
+        if len(self.InfFileName) > 1 and self.InfFileName[0] == '\\' and self.InfFileName[1] == '\\':\r
+            pass\r
+        elif self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' :\r
             self.InfFileName = self.InfFileName[1:]\r
 \r
         if self.InfFileName.find('$') == -1:\r
             self.InfFileName = self.InfFileName[1:]\r
 \r
         if self.InfFileName.find('$') == -1:\r
@@ -164,32 +173,38 @@ class FfsInfStatement(FfsInfStatementClassObject):
         ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")\r
         if ErrorCode != 0:\r
             EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
         ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")\r
         if ErrorCode != 0:\r
             EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\r
-        \r
-        if self.CurrentArch != None:\r
+\r
+        #\r
+        # Cache lower case version of INF path before processing FILE_GUID override\r
+        #\r
+        InfLowerPath = str(PathClassObj).lower()\r
+        if self.OverrideGuid:\r
+            PathClassObj = ProcessDuplicatedInf(PathClassObj, self.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir)\r
+        if self.CurrentArch is not None:\r
 \r
             Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
             #\r
 \r
             Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
             #\r
-            # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath\r
+            # Set Ffs BaseName, ModuleGuid, ModuleType, Version, OutputPath\r
             #\r
             self.BaseName = Inf.BaseName\r
             self.ModuleGuid = Inf.Guid\r
             self.ModuleType = Inf.ModuleType\r
             #\r
             self.BaseName = Inf.BaseName\r
             self.ModuleGuid = Inf.Guid\r
             self.ModuleType = Inf.ModuleType\r
-            if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:\r
+            if Inf.Specification is not None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:\r
                 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']\r
             if Inf.AutoGenVersion < 0x00010005:\r
                 self.ModuleType = Inf.ComponentType\r
             self.VersionString = Inf.Version\r
             self.BinFileList = Inf.Binaries\r
             self.SourceFileList = Inf.Sources\r
                 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']\r
             if Inf.AutoGenVersion < 0x00010005:\r
                 self.ModuleType = Inf.ComponentType\r
             self.VersionString = Inf.Version\r
             self.BinFileList = Inf.Binaries\r
             self.SourceFileList = Inf.Sources\r
-            if self.KeepReloc == None and Inf.Shadow:\r
+            if self.KeepReloc is None and Inf.Shadow:\r
                 self.ShadowFromInfFile = Inf.Shadow\r
 \r
         else:\r
                 self.ShadowFromInfFile = Inf.Shadow\r
 \r
         else:\r
-            Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
+            Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, TAB_COMMON, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
             self.BaseName = Inf.BaseName\r
             self.ModuleGuid = Inf.Guid\r
             self.ModuleType = Inf.ModuleType\r
             self.BaseName = Inf.BaseName\r
             self.ModuleGuid = Inf.Guid\r
             self.ModuleType = Inf.ModuleType\r
-            if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:\r
+            if Inf.Specification is not None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:\r
                 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']\r
             self.VersionString = Inf.Version\r
             self.BinFileList = Inf.Binaries\r
                 self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']\r
             self.VersionString = Inf.Version\r
             self.BinFileList = Inf.Binaries\r
@@ -199,19 +214,26 @@ class FfsInfStatement(FfsInfStatementClassObject):
                                 "INF %s specified in FDF could not be found in build ARCH %s!" \\r
                                 % (self.InfFileName, GenFdsGlobalVariable.ArchList))\r
 \r
                                 "INF %s specified in FDF could not be found in build ARCH %s!" \\r
                                 % (self.InfFileName, GenFdsGlobalVariable.ArchList))\r
 \r
+        if self.OverrideGuid:\r
+            self.ModuleGuid = self.OverrideGuid\r
+\r
         if len(self.SourceFileList) != 0 and not self.InDsc:\r
             EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName))\r
 \r
         if len(self.SourceFileList) != 0 and not self.InDsc:\r
             EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName))\r
 \r
-        if self.ModuleType == 'SMM_CORE' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
-            EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.InfFileName)      \r
+        if self.ModuleType == SUP_MODULE_SMM_CORE and int(self.PiSpecVersion, 16) < 0x0001000A:\r
+            EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.InfFileName)\r
+\r
+        if self.ModuleType == SUP_MODULE_MM_CORE_STANDALONE and int(self.PiSpecVersion, 16) < 0x00010032:\r
+            EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "MM_CORE_STANDALONE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x00010032", File=self.InfFileName)\r
 \r
 \r
-        if Inf._Defs != None and len(Inf._Defs) > 0:\r
+        if Inf._Defs is not None and len(Inf._Defs) > 0:\r
             self.OptRomDefs.update(Inf._Defs)\r
 \r
         self.PatchPcds = []\r
         InfPcds = Inf.Pcds\r
         Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
         FdfPcdDict = GenFdsGlobalVariable.FdfParser.Profile.PcdDict\r
             self.OptRomDefs.update(Inf._Defs)\r
 \r
         self.PatchPcds = []\r
         InfPcds = Inf.Pcds\r
         Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
         FdfPcdDict = GenFdsGlobalVariable.FdfParser.Profile.PcdDict\r
+        PlatformPcds = Platform.Pcds\r
 \r
         # Workaround here: both build and GenFds tool convert the workspace path to lower case\r
         # But INF file path in FDF and DSC file may have real case characters.\r
 \r
         # Workaround here: both build and GenFds tool convert the workspace path to lower case\r
         # But INF file path in FDF and DSC file may have real case characters.\r
@@ -223,11 +245,10 @@ class FfsInfStatement(FfsInfStatementClassObject):
             Pcd = InfPcds[PcdKey]\r
             if not hasattr(Pcd, 'Offset'):\r
                 continue\r
             Pcd = InfPcds[PcdKey]\r
             if not hasattr(Pcd, 'Offset'):\r
                 continue\r
-            if Pcd.Type != 'PatchableInModule':\r
+            if Pcd.Type != TAB_PCDS_PATCHABLE_IN_MODULE:\r
                 continue\r
             # Override Patchable PCD value by the value from DSC\r
             PatchPcd = None\r
                 continue\r
             # Override Patchable PCD value by the value from DSC\r
             PatchPcd = None\r
-            InfLowerPath = str(PathClassObj).lower()\r
             if InfLowerPath in DscModules and PcdKey in DscModules[InfLowerPath].Pcds:\r
                 PatchPcd = DscModules[InfLowerPath].Pcds[PcdKey]\r
             elif PcdKey in Platform.Pcds:\r
             if InfLowerPath in DscModules and PcdKey in DscModules[InfLowerPath].Pcds:\r
                 PatchPcd = DscModules[InfLowerPath].Pcds[PcdKey]\r
             elif PcdKey in Platform.Pcds:\r
@@ -243,11 +264,36 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 DefaultValue = FdfPcdDict[PcdKey]\r
                 FdfOverride = True\r
 \r
                 DefaultValue = FdfPcdDict[PcdKey]\r
                 FdfOverride = True\r
 \r
-            if not DscOverride and not FdfOverride:\r
+            # Override Patchable PCD value by the value from Build Option\r
+            BuildOptionOverride = False\r
+            if GlobalData.BuildOptionPcd:\r
+                for pcd in GlobalData.BuildOptionPcd:\r
+                    if PcdKey == (pcd[1], pcd[0]):\r
+                        if pcd[2]:\r
+                            continue\r
+                        DefaultValue = pcd[3]\r
+                        BuildOptionOverride = True\r
+                        break\r
+\r
+            if not DscOverride and not FdfOverride and not BuildOptionOverride:\r
                 continue\r
                 continue\r
+\r
+            # Support Flexible PCD format\r
+            if DefaultValue:\r
+                try:\r
+                    DefaultValue = ValueExpressionEx(DefaultValue, Pcd.DatumType, Platform._GuidDict)(True)\r
+                except BadExpression:\r
+                    EdkLogger.error("GenFds", GENFDS_ERROR, 'PCD [%s.%s] Value "%s"' %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValue), File=self.InfFileName)\r
+\r
+            if Pcd.InfDefaultValue:\r
+                try:\r
+                    Pcd.InfDefaultValue = ValueExpressionEx(Pcd.InfDefaultValue, Pcd.DatumType, Platform._GuidDict)(True)\r
+                except BadExpression:\r
+                    EdkLogger.error("GenFds", GENFDS_ERROR, 'PCD [%s.%s] Value "%s"' %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DefaultValue), File=self.InfFileName)\r
+\r
             # Check value, if value are equal, no need to patch\r
             # Check value, if value are equal, no need to patch\r
-            if Pcd.DatumType == "VOID*":\r
-                if Pcd.DefaultValue == DefaultValue or DefaultValue in [None, '']:\r
+            if Pcd.DatumType == TAB_VOID:\r
+                if Pcd.InfDefaultValue == DefaultValue or not DefaultValue:\r
                     continue\r
                 # Get the string size from FDF or DSC\r
                 if DefaultValue[0] == 'L':\r
                     continue\r
                 # Get the string size from FDF or DSC\r
                 if DefaultValue[0] == 'L':\r
@@ -260,36 +306,39 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 if DscOverride:\r
                     Pcd.MaxDatumSize = PatchPcd.MaxDatumSize\r
                 # If no defined the maximum size in DSC, try to get current size from INF\r
                 if DscOverride:\r
                     Pcd.MaxDatumSize = PatchPcd.MaxDatumSize\r
                 # If no defined the maximum size in DSC, try to get current size from INF\r
-                if Pcd.MaxDatumSize in ['', None]:\r
-                    Pcd.MaxDatumSize = str(len(Pcd.DefaultValue.split(',')))\r
+                if not Pcd.MaxDatumSize:\r
+                    Pcd.MaxDatumSize = str(len(Pcd.InfDefaultValue.split(',')))\r
             else:\r
                 Base1 = Base2 = 10\r
             else:\r
                 Base1 = Base2 = 10\r
-                if Pcd.DefaultValue.upper().startswith('0X'):\r
+                if Pcd.InfDefaultValue.upper().startswith('0X'):\r
                     Base1 = 16\r
                 if DefaultValue.upper().startswith('0X'):\r
                     Base2 = 16\r
                 try:\r
                     Base1 = 16\r
                 if DefaultValue.upper().startswith('0X'):\r
                     Base2 = 16\r
                 try:\r
-                    PcdValueInImg = int(Pcd.DefaultValue, Base1)\r
+                    PcdValueInImg = int(Pcd.InfDefaultValue, Base1)\r
                     PcdValueInDscOrFdf = int(DefaultValue, Base2)\r
                     if PcdValueInImg == PcdValueInDscOrFdf:\r
                         continue\r
                 except:\r
                     continue\r
             # Check the Pcd size and data type\r
                     PcdValueInDscOrFdf = int(DefaultValue, Base2)\r
                     if PcdValueInImg == PcdValueInDscOrFdf:\r
                         continue\r
                 except:\r
                     continue\r
             # Check the Pcd size and data type\r
-            if Pcd.DatumType == "VOID*":\r
+            if Pcd.DatumType == TAB_VOID:\r
                 if int(MaxDatumSize) > int(Pcd.MaxDatumSize):\r
                     EdkLogger.error("GenFds", GENFDS_ERROR, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \\r
                                     % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, int(MaxDatumSize) - int(Pcd.MaxDatumSize)))\r
             else:\r
                 if int(MaxDatumSize) > int(Pcd.MaxDatumSize):\r
                     EdkLogger.error("GenFds", GENFDS_ERROR, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \\r
                                     % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, int(MaxDatumSize) - int(Pcd.MaxDatumSize)))\r
             else:\r
-                if PcdValueInDscOrFdf > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType] \\r
-                    or PcdValueInImg > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType]:\r
+                if PcdValueInDscOrFdf > MAX_VAL_TYPE[Pcd.DatumType] \\r
+                    or PcdValueInImg > MAX_VAL_TYPE[Pcd.DatumType]:\r
                     EdkLogger.error("GenFds", GENFDS_ERROR, "The size of %s type PCD '%s.%s' doesn't match its data type." \\r
                                     % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
                     EdkLogger.error("GenFds", GENFDS_ERROR, "The size of %s type PCD '%s.%s' doesn't match its data type." \\r
                                     % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
-            Pcd.DefaultValue = DefaultValue\r
-            self.PatchPcds.append(Pcd)\r
+            self.PatchPcds.append((Pcd, DefaultValue))\r
+\r
         self.InfModule = Inf\r
         self.PcdIsDriver = Inf.PcdIsDriver\r
         self.IsBinaryModule = Inf.IsBinaryModule\r
         self.InfModule = Inf\r
         self.PcdIsDriver = Inf.PcdIsDriver\r
         self.IsBinaryModule = Inf.IsBinaryModule\r
+        if len(Inf.Depex.data) > 0 and len(Inf.DepexExpression.data) > 0:\r
+            self.Depex = True\r
+\r
         GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName)\r
         GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid)\r
         GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType)\r
         GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName)\r
         GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid)\r
         GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType)\r
@@ -297,18 +346,21 @@ class FfsInfStatement(FfsInfStatementClassObject):
         GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" % self.InfFileName)\r
 \r
         #\r
         GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" % self.InfFileName)\r
 \r
         #\r
-        # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\\r
+        # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${ModuleName}\\r
         #\r
         #\r
-\r
+        if IsGenFfs:\r
+            Rule = self.__GetRule__()\r
+            if GlobalData.gGuidPatternEnd.match(Rule.NameGuid):\r
+                self.ModuleGuid = Rule.NameGuid\r
         self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \\r
                                        self.ModuleGuid + self.BaseName)\r
         if not os.path.exists(self.OutputPath) :\r
             os.makedirs(self.OutputPath)\r
 \r
         self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \\r
                                        self.ModuleGuid + self.BaseName)\r
         if not os.path.exists(self.OutputPath) :\r
             os.makedirs(self.OutputPath)\r
 \r
-        self.EfiOutputPath = self.__GetEFIOutPutPath__()\r
+        self.EfiOutputPath, self.EfiDebugPath = self.__GetEFIOutPutPath__()\r
         GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)\r
 \r
         GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)\r
 \r
-## PatchEfiFile\r
+    ## PatchEfiFile\r
     #\r
     #  Patch EFI file with patch PCD\r
     #\r
     #\r
     #  Patch EFI file with patch PCD\r
     #\r
@@ -316,19 +368,64 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #  @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name\r
     #           If passed in file does not end with efi, return as is\r
     #\r
     #  @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name\r
     #           If passed in file does not end with efi, return as is\r
     #\r
-    def PatchEfiFile(self, EfiFile):\r
-        if os.path.splitext(EfiFile)[1].lower() != '.efi':\r
-            return EfiFile\r
+    def PatchEfiFile(self, EfiFile, FileType):\r
+        #\r
+        # If the module does not have any patches, then return path to input file\r
+        #\r
         if not self.PatchPcds:\r
             return EfiFile\r
         if not self.PatchPcds:\r
             return EfiFile\r
+\r
+        #\r
+        # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED\r
+        #\r
+        if FileType != BINARY_FILE_TYPE_PE32 and self.ModuleType != SUP_MODULE_USER_DEFINED:\r
+            return EfiFile\r
+\r
+        #\r
+        # Generate path to patched output file\r
+        #\r
         Basename = os.path.basename(EfiFile)\r
         Basename = os.path.basename(EfiFile)\r
-        Output = os.path.join(self.OutputPath, Basename)\r
+        Output = os.path.normpath (os.path.join(self.OutputPath, Basename))\r
+\r
+        #\r
+        # If this file has already been patched, then return the path to the patched file\r
+        #\r
+        if self.PatchedBinFile == Output:\r
+          return Output\r
+\r
+        #\r
+        # If a different file from the same module has already been patched, then generate an error\r
+        #\r
+        if self.PatchedBinFile:\r
+            EdkLogger.error("GenFds", GENFDS_ERROR,\r
+                            'Only one binary file can be patched:\n'\r
+                            '  a binary file has been patched: %s\n'\r
+                            '  current file: %s' % (self.PatchedBinFile, EfiFile),\r
+                            File=self.InfFileName)\r
+\r
+        #\r
+        # Copy unpatched file contents to output file location to perform patching\r
+        #\r
         CopyLongFilePath(EfiFile, Output)\r
         CopyLongFilePath(EfiFile, Output)\r
-        for Pcd in self.PatchPcds:\r
-            RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Pcd.DefaultValue, Pcd.MaxDatumSize)\r
+\r
+        #\r
+        # Apply patches to patched output file\r
+        #\r
+        for Pcd, Value in self.PatchPcds:\r
+            RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Value, Pcd.MaxDatumSize)\r
             if RetVal:\r
                 EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName)\r
             if RetVal:\r
                 EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName)\r
+\r
+        #\r
+        # Save the path of the patched output file\r
+        #\r
+        self.PatchedBinFile = Output\r
+\r
+        #\r
+        # Return path to patched output file\r
+        #\r
         return Output\r
         return Output\r
+\r
     ## GenFfs() method\r
     #\r
     #   Generate FFS\r
     ## GenFfs() method\r
     #\r
     #   Generate FFS\r
@@ -339,20 +436,47 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  FvParentAddr Parent Fv base address\r
     #   @retval string       Generated FFS file name\r
     #\r
     #   @param  FvParentAddr Parent Fv base address\r
     #   @retval string       Generated FFS file name\r
     #\r
-    def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None):\r
+    def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None, IsMakefile=False, FvName=None):\r
         #\r
         # Parse Inf file get Module related information\r
         #\r
 \r
         #\r
         # Parse Inf file get Module related information\r
         #\r
 \r
-        self.__InfParse__(Dict)\r
-        \r
+        self.__InfParse__(Dict, IsGenFfs=True)\r
+        Arch = self.GetCurrentArch()\r
+        SrcFile = mws.join( GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName);\r
+        DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')\r
+\r
+        SrcFileDir = "."\r
+        SrcPath = os.path.dirname(SrcFile)\r
+        SrcFileName = os.path.basename(SrcFile)\r
+        SrcFileBase, SrcFileExt = os.path.splitext(SrcFileName)\r
+        DestPath = os.path.dirname(DestFile)\r
+        DestFileName = os.path.basename(DestFile)\r
+        DestFileBase, DestFileExt = os.path.splitext(DestFileName)\r
+        self.MacroDict = {\r
+            # source file\r
+            "${src}"      :   SrcFile,\r
+            "${s_path}"   :   SrcPath,\r
+            "${s_dir}"    :   SrcFileDir,\r
+            "${s_name}"   :   SrcFileName,\r
+            "${s_base}"   :   SrcFileBase,\r
+            "${s_ext}"    :   SrcFileExt,\r
+            # destination file\r
+            "${dst}"      :   DestFile,\r
+            "${d_path}"   :   DestPath,\r
+            "${d_name}"   :   DestFileName,\r
+            "${d_base}"   :   DestFileBase,\r
+            "${d_ext}"    :   DestFileExt\r
+        }\r
         #\r
         # Allow binary type module not specify override rule in FDF file.\r
         #\r
         # Allow binary type module not specify override rule in FDF file.\r
-        # \r
-        if len(self.BinFileList) >0 and not self.InDsc:\r
-            if self.Rule == None or self.Rule == "":\r
+        #\r
+        if len(self.BinFileList) > 0:\r
+            if self.Rule is None or self.Rule == "":\r
                 self.Rule = "BINARY"\r
                 self.Rule = "BINARY"\r
-                \r
+\r
+        if not IsMakefile and GenFdsGlobalVariable.EnableGenfdsMultiThread and self.Rule != 'BINARY':\r
+            IsMakefile = True\r
         #\r
         # Get the rule of how to generate Ffs file\r
         #\r
         #\r
         # Get the rule of how to generate Ffs file\r
         #\r
@@ -361,29 +485,33 @@ class FfsInfStatement(FfsInfStatementClassObject):
         #\r
         # Convert Fv File Type for PI1.1 SMM driver.\r
         #\r
         #\r
         # Convert Fv File Type for PI1.1 SMM driver.\r
         #\r
-        if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:\r
+        if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) >= 0x0001000A:\r
             if Rule.FvFileType == 'DRIVER':\r
                 Rule.FvFileType = 'SMM'\r
         #\r
         # Framework SMM Driver has no SMM FV file type\r
         #\r
             if Rule.FvFileType == 'DRIVER':\r
                 Rule.FvFileType = 'SMM'\r
         #\r
         # Framework SMM Driver has no SMM FV file type\r
         #\r
-        if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
-            if Rule.FvFileType == 'SMM' or Rule.FvFileType == 'SMM_CORE':\r
+        if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) < 0x0001000A:\r
+            if Rule.FvFileType == 'SMM' or Rule.FvFileType == SUP_MODULE_SMM_CORE:\r
                 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File=self.InfFileName)\r
         #\r
         # For the rule only has simpleFile\r
         #\r
                 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File=self.InfFileName)\r
         #\r
         # For the rule only has simpleFile\r
         #\r
-        if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) :\r
-            SectionOutputList = self.__GenSimpleFileSection__(Rule)\r
-            FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList)\r
+        MakefilePath = None\r
+        if self.IsBinaryModule:\r
+            IsMakefile = False\r
+        if IsMakefile:\r
+            MakefilePath = self.InfFileName, Arch\r
+        if isinstance (Rule, RuleSimpleFile.RuleSimpleFile):\r
+            SectionOutputList = self.__GenSimpleFileSection__(Rule, IsMakefile=IsMakefile)\r
+            FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList, MakefilePath=MakefilePath)\r
             return FfsOutput\r
         #\r
         # For Rule has ComplexFile\r
         #\r
         elif isinstance(Rule, RuleComplexFile.RuleComplexFile):\r
             return FfsOutput\r
         #\r
         # For Rule has ComplexFile\r
         #\r
         elif isinstance(Rule, RuleComplexFile.RuleComplexFile):\r
-            InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr)\r
-            FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments)\r
-\r
+            InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr, IsMakefile=IsMakefile)\r
+            FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments, MakefilePath=MakefilePath)\r
             return FfsOutput\r
 \r
     ## __ExtendMacro__() method\r
             return FfsOutput\r
 \r
     ## __ExtendMacro__() method\r
@@ -403,6 +531,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
             '$(NAMED_GUID)'  : self.ModuleGuid\r
         }\r
         String = GenFdsGlobalVariable.MacroExtend(String, MacroDict)\r
             '$(NAMED_GUID)'  : self.ModuleGuid\r
         }\r
         String = GenFdsGlobalVariable.MacroExtend(String, MacroDict)\r
+        String = GenFdsGlobalVariable.MacroExtend(String, self.MacroDict)\r
         return String\r
 \r
     ## __GetRule__() method\r
         return String\r
 \r
     ## __GetRule__() method\r
@@ -414,7 +543,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #\r
     def __GetRule__ (self) :\r
         CurrentArchList = []\r
     #\r
     def __GetRule__ (self) :\r
         CurrentArchList = []\r
-        if self.CurrentArch == None:\r
+        if self.CurrentArch is None:\r
             CurrentArchList = ['common']\r
         else:\r
             CurrentArchList.append(self.CurrentArch)\r
             CurrentArchList = ['common']\r
         else:\r
             CurrentArchList.append(self.CurrentArch)\r
@@ -425,23 +554,23 @@ class FfsInfStatement(FfsInfStatementClassObject):
                        CurrentArch.upper() + \\r
                        '.'                 + \\r
                        self.ModuleType.upper()\r
                        CurrentArch.upper() + \\r
                        '.'                 + \\r
                        self.ModuleType.upper()\r
-            if self.Rule != None:\r
+            if self.Rule is not None:\r
                 RuleName = RuleName + \\r
                            '.'      + \\r
                            self.Rule.upper()\r
 \r
             Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)\r
                 RuleName = RuleName + \\r
                            '.'      + \\r
                            self.Rule.upper()\r
 \r
             Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)\r
-            if Rule != None:\r
+            if Rule is not None:\r
                 GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)\r
                 return Rule\r
 \r
         RuleName = 'RULE'      + \\r
                    '.'         + \\r
                 GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)\r
                 return Rule\r
 \r
         RuleName = 'RULE'      + \\r
                    '.'         + \\r
-                   'COMMON'    + \\r
+                   TAB_COMMON    + \\r
                    '.'         + \\r
                    self.ModuleType.upper()\r
 \r
                    '.'         + \\r
                    self.ModuleType.upper()\r
 \r
-        if self.Rule != None:\r
+        if self.Rule is not None:\r
             RuleName = RuleName + \\r
                        '.'      + \\r
                        self.Rule.upper()\r
             RuleName = RuleName + \\r
                        '.'      + \\r
                        self.Rule.upper()\r
@@ -449,11 +578,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
         GenFdsGlobalVariable.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName, self.InfFileName))\r
 \r
         Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)\r
         GenFdsGlobalVariable.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName, self.InfFileName))\r
 \r
         Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)\r
-        if Rule != None:\r
+        if Rule is not None:\r
             GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)\r
             return Rule\r
 \r
             GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)\r
             return Rule\r
 \r
-        if Rule == None :\r
+        if Rule is None :\r
             EdkLogger.error("GenFds", GENFDS_ERROR, 'Don\'t Find common rule %s for INF %s' \\r
                             % (RuleName, self.InfFileName))\r
 \r
             EdkLogger.error("GenFds", GENFDS_ERROR, 'Don\'t Find common rule %s for INF %s' \\r
                             % (RuleName, self.InfFileName))\r
 \r
@@ -466,37 +595,23 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #\r
     def __GetPlatformArchList__(self):\r
 \r
     #\r
     def __GetPlatformArchList__(self):\r
 \r
-        InfFileKey = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))\r
+        InfFileKey = os.path.normpath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))\r
         DscArchList = []\r
         DscArchList = []\r
-        PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IA32', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
-        if  PlatformDataBase != None:\r
-            if InfFileKey in PlatformDataBase.Modules:\r
-                DscArchList.append ('IA32')\r
-\r
-        PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'X64', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
-        if  PlatformDataBase != None:\r
-            if InfFileKey in PlatformDataBase.Modules:\r
-                DscArchList.append ('X64')\r
-\r
-        PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'IPF', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
-        if PlatformDataBase != None:\r
-            if InfFileKey in (PlatformDataBase.Modules):\r
-                DscArchList.append ('IPF')\r
-\r
-        PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'ARM', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
-        if PlatformDataBase != None:\r
-            if InfFileKey in (PlatformDataBase.Modules):\r
-                DscArchList.append ('ARM')\r
-\r
-        PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'EBC', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
-        if PlatformDataBase != None:\r
-            if InfFileKey in (PlatformDataBase.Modules):\r
-                DscArchList.append ('EBC')\r
-\r
-        PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'AARCH64', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
-        if PlatformDataBase != None:\r
-            if InfFileKey in (PlatformDataBase.Modules):\r
-                DscArchList.append ('AARCH64')\r
+        for Arch in GenFdsGlobalVariable.ArchList :\r
+            PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
+            if  PlatformDataBase is not None:\r
+                if InfFileKey in PlatformDataBase.Modules:\r
+                    DscArchList.append (Arch)\r
+                else:\r
+                    #\r
+                    # BaseTools support build same module more than once, the module path with FILE_GUID overridden has\r
+                    # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key,\r
+                    # but the path (self.MetaFile.Path) is the real path\r
+                    #\r
+                    for key in PlatformDataBase.Modules:\r
+                        if InfFileKey == str((PlatformDataBase.Modules[key]).MetaFile.Path):\r
+                            DscArchList.append (Arch)\r
+                            break\r
 \r
         return DscArchList\r
 \r
 \r
         return DscArchList\r
 \r
@@ -531,7 +646,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
             ArchList = CurArchList\r
 \r
         UseArchList = TargetArchList\r
             ArchList = CurArchList\r
 \r
         UseArchList = TargetArchList\r
-        if self.UseArch != None:\r
+        if self.UseArch is not None:\r
             UseArchList = []\r
             UseArchList.append(self.UseArch)\r
             ArchList = list(set (UseArchList) & set (ArchList))\r
             UseArchList = []\r
             UseArchList.append(self.UseArch)\r
             ArchList = list(set (UseArchList) & set (ArchList))\r
@@ -565,21 +680,31 @@ class FfsInfStatement(FfsInfStatementClassObject):
     def __GetEFIOutPutPath__(self):\r
         Arch = ''\r
         OutputPath = ''\r
     def __GetEFIOutPutPath__(self):\r
         Arch = ''\r
         OutputPath = ''\r
+        DebugPath = ''\r
         (ModulePath, FileName) = os.path.split(self.InfFileName)\r
         Index = FileName.rfind('.')\r
         FileName = FileName[0:Index]\r
         (ModulePath, FileName) = os.path.split(self.InfFileName)\r
         Index = FileName.rfind('.')\r
         FileName = FileName[0:Index]\r
+        if self.OverrideGuid:\r
+            FileName = self.OverrideGuid\r
         Arch = "NoneArch"\r
         Arch = "NoneArch"\r
-        if self.CurrentArch != None:\r
+        if self.CurrentArch is not None:\r
             Arch = self.CurrentArch\r
 \r
         OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],\r
             Arch = self.CurrentArch\r
 \r
         OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],\r
-                                  Arch ,\r
+                                  Arch,\r
                                   ModulePath,\r
                                   FileName,\r
                                   'OUTPUT'\r
                                   )\r
                                   ModulePath,\r
                                   FileName,\r
                                   'OUTPUT'\r
                                   )\r
+        DebugPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],\r
+                                  Arch,\r
+                                  ModulePath,\r
+                                  FileName,\r
+                                  'DEBUG'\r
+                                  )\r
         OutputPath = os.path.realpath(OutputPath)\r
         OutputPath = os.path.realpath(OutputPath)\r
-        return OutputPath\r
+        DebugPath = os.path.realpath(DebugPath)\r
+        return OutputPath, DebugPath\r
 \r
     ## __GenSimpleFileSection__() method\r
     #\r
 \r
     ## __GenSimpleFileSection__() method\r
     #\r
@@ -589,14 +714,14 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  Rule        The rule object used to generate section\r
     #   @retval string      File name of the generated section file\r
     #\r
     #   @param  Rule        The rule object used to generate section\r
     #   @retval string      File name of the generated section file\r
     #\r
-    def __GenSimpleFileSection__(self, Rule):\r
+    def __GenSimpleFileSection__(self, Rule, IsMakefile = False):\r
         #\r
         # Prepare the parameter of GenSection\r
         #\r
         FileList = []\r
         OutputFileList = []\r
         GenSecInputFile = None\r
         #\r
         # Prepare the parameter of GenSection\r
         #\r
         FileList = []\r
         OutputFileList = []\r
         GenSecInputFile = None\r
-        if Rule.FileName != None:\r
+        if Rule.FileName is not None:\r
             GenSecInputFile = self.__ExtendMacro__(Rule.FileName)\r
             if os.path.isabs(GenSecInputFile):\r
                 GenSecInputFile = os.path.normpath(GenSecInputFile)\r
             GenSecInputFile = self.__ExtendMacro__(Rule.FileName)\r
             if os.path.isabs(GenSecInputFile):\r
                 GenSecInputFile = os.path.normpath(GenSecInputFile)\r
@@ -610,22 +735,22 @@ class FfsInfStatement(FfsInfStatementClassObject):
         #\r
         # Convert Fv Section Type for PI1.1 SMM driver.\r
         #\r
         #\r
         # Convert Fv Section Type for PI1.1 SMM driver.\r
         #\r
-        if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:\r
-            if SectionType == 'DXE_DEPEX':\r
-                SectionType = 'SMM_DEPEX'\r
+        if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) >= 0x0001000A:\r
+            if SectionType == BINARY_FILE_TYPE_DXE_DEPEX:\r
+                SectionType = BINARY_FILE_TYPE_SMM_DEPEX\r
         #\r
         # Framework SMM Driver has no SMM_DEPEX section type\r
         #\r
         #\r
         # Framework SMM Driver has no SMM_DEPEX section type\r
         #\r
-        if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
-            if SectionType == 'SMM_DEPEX':\r
+        if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) < 0x0001000A:\r
+            if SectionType == BINARY_FILE_TYPE_SMM_DEPEX:\r
                 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)\r
         NoStrip = True\r
                 EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)\r
         NoStrip = True\r
-        if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):\r
-            if self.KeepReloc != None:\r
+        if self.ModuleType in (SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM):\r
+            if self.KeepReloc is not None:\r
                 NoStrip = self.KeepReloc\r
                 NoStrip = self.KeepReloc\r
-            elif Rule.KeepReloc != None:\r
+            elif Rule.KeepReloc is not None:\r
                 NoStrip = Rule.KeepReloc\r
                 NoStrip = Rule.KeepReloc\r
-            elif self.ShadowFromInfFile != None:\r
+            elif self.ShadowFromInfFile is not None:\r
                 NoStrip = self.ShadowFromInfFile\r
 \r
         if FileList != [] :\r
                 NoStrip = self.ShadowFromInfFile\r
 \r
         if FileList != [] :\r
@@ -633,18 +758,20 @@ class FfsInfStatement(FfsInfStatementClassObject):
 \r
                 SecNum = '%d' %Index\r
                 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \\r
 \r
                 SecNum = '%d' %Index\r
                 GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \\r
-                              Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum\r
+                              SectionSuffix[SectionType] + SUP_MODULE_SEC + SecNum\r
                 Index = Index + 1\r
                 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)\r
                 File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)\r
 \r
                 #Get PE Section alignment when align is set to AUTO\r
                 Index = Index + 1\r
                 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)\r
                 File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)\r
 \r
                 #Get PE Section alignment when align is set to AUTO\r
-                if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):\r
+                if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_TE):\r
                     ImageObj = PeImageClass (File)\r
                     if ImageObj.SectionAlignment < 0x400:\r
                         self.Alignment = str (ImageObj.SectionAlignment)\r
                     ImageObj = PeImageClass (File)\r
                     if ImageObj.SectionAlignment < 0x400:\r
                         self.Alignment = str (ImageObj.SectionAlignment)\r
+                    elif ImageObj.SectionAlignment < 0x100000:\r
+                        self.Alignment = str (ImageObj.SectionAlignment // 0x400) + 'K'\r
                     else:\r
                     else:\r
-                        self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'\r
+                        self.Alignment = str (ImageObj.SectionAlignment // 0x100000) + 'M'\r
 \r
                 if not NoStrip:\r
                     FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')\r
 \r
                 if not NoStrip:\r
                     FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')\r
@@ -653,37 +780,40 @@ class FfsInfStatement(FfsInfStatementClassObject):
                         CopyLongFilePath(File, FileBeforeStrip)\r
                     StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')\r
                     GenFdsGlobalVariable.GenerateFirmwareImage(\r
                         CopyLongFilePath(File, FileBeforeStrip)\r
                     StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')\r
                     GenFdsGlobalVariable.GenerateFirmwareImage(\r
-                                            StrippedFile,\r
-                                            [File],\r
-                                            Strip=True\r
-                                            )\r
+                            StrippedFile,\r
+                            [File],\r
+                            Strip=True,\r
+                            IsMakefile=IsMakefile\r
+                        )\r
                     File = StrippedFile\r
 \r
                     File = StrippedFile\r
 \r
-                if SectionType == 'TE':\r
+                if SectionType == BINARY_FILE_TYPE_TE:\r
                     TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')\r
                     GenFdsGlobalVariable.GenerateFirmwareImage(\r
                     TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')\r
                     GenFdsGlobalVariable.GenerateFirmwareImage(\r
-                                            TeFile,\r
-                                            [File],\r
-                                            Type='te'\r
-                                            )\r
+                            TeFile,\r
+                            [File],\r
+                            Type='te',\r
+                            IsMakefile=IsMakefile\r
+                        )\r
                     File = TeFile\r
                     File = TeFile\r
-\r
-                GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType])\r
+                GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile)\r
                 OutputFileList.append(OutputFile)\r
         else:\r
             SecNum = '%d' %Index\r
             GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \\r
                 OutputFileList.append(OutputFile)\r
         else:\r
             SecNum = '%d' %Index\r
             GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \\r
-                              Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum\r
+                              SectionSuffix[SectionType] + SUP_MODULE_SEC + SecNum\r
             OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)\r
             GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch)\r
 \r
             #Get PE Section alignment when align is set to AUTO\r
             OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)\r
             GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch)\r
 \r
             #Get PE Section alignment when align is set to AUTO\r
-            if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):\r
+            if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_TE):\r
                 ImageObj = PeImageClass (GenSecInputFile)\r
                 if ImageObj.SectionAlignment < 0x400:\r
                     self.Alignment = str (ImageObj.SectionAlignment)\r
                 ImageObj = PeImageClass (GenSecInputFile)\r
                 if ImageObj.SectionAlignment < 0x400:\r
                     self.Alignment = str (ImageObj.SectionAlignment)\r
+                elif ImageObj.SectionAlignment < 0x100000:\r
+                    self.Alignment = str (ImageObj.SectionAlignment // 0x400) + 'K'\r
                 else:\r
                 else:\r
-                    self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'\r
+                    self.Alignment = str (ImageObj.SectionAlignment // 0x100000) + 'M'\r
 \r
             if not NoStrip:\r
                 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')\r
 \r
             if not NoStrip:\r
                 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')\r
@@ -693,22 +823,23 @@ class FfsInfStatement(FfsInfStatementClassObject):
 \r
                 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')\r
                 GenFdsGlobalVariable.GenerateFirmwareImage(\r
 \r
                 StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')\r
                 GenFdsGlobalVariable.GenerateFirmwareImage(\r
-                                        StrippedFile,\r
-                                        [GenSecInputFile],\r
-                                        Strip=True\r
-                                        )\r
+                        StrippedFile,\r
+                        [GenSecInputFile],\r
+                        Strip=True,\r
+                        IsMakefile=IsMakefile\r
+                    )\r
                 GenSecInputFile = StrippedFile\r
 \r
                 GenSecInputFile = StrippedFile\r
 \r
-            if SectionType == 'TE':\r
+            if SectionType == BINARY_FILE_TYPE_TE:\r
                 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')\r
                 GenFdsGlobalVariable.GenerateFirmwareImage(\r
                 TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')\r
                 GenFdsGlobalVariable.GenerateFirmwareImage(\r
-                                        TeFile,\r
-                                        [GenSecInputFile],\r
-                                        Type='te'\r
-                                        )\r
+                        TeFile,\r
+                        [GenSecInputFile],\r
+                        Type='te',\r
+                        IsMakefile=IsMakefile\r
+                    )\r
                 GenSecInputFile = TeFile\r
                 GenSecInputFile = TeFile\r
-\r
-            GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType])\r
+            GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType], IsMakefile=IsMakefile)\r
             OutputFileList.append(OutputFile)\r
 \r
         return OutputFileList\r
             OutputFileList.append(OutputFile)\r
 \r
         return OutputFileList\r
@@ -722,7 +853,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  InputFileList        The output file list from GenSection\r
     #   @retval string      Generated FFS file name\r
     #\r
     #   @param  InputFileList        The output file list from GenSection\r
     #   @retval string      Generated FFS file name\r
     #\r
-    def __GenSimpleFileFfs__(self, Rule, InputFileList):\r
+    def __GenSimpleFileFfs__(self, Rule, InputFileList, MakefilePath = None):\r
         FfsOutput = self.OutputPath                     + \\r
                     os.sep                              + \\r
                     self.__ExtendMacro__(Rule.NameGuid) + \\r
         FfsOutput = self.OutputPath                     + \\r
                     os.sep                              + \\r
                     self.__ExtendMacro__(Rule.NameGuid) + \\r
@@ -735,7 +866,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
             InputSection.append(InputFile)\r
             SectionAlignments.append(Rule.SectAlignment)\r
 \r
             InputSection.append(InputFile)\r
             SectionAlignments.append(Rule.SectAlignment)\r
 \r
-        if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):\r
+        if Rule.NameGuid is not None and Rule.NameGuid.startswith('PCD('):\r
             PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)\r
             if len(PcdValue) == 0:\r
                 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \\r
             PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)\r
             if len(PcdValue) == 0:\r
                 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \\r
@@ -748,12 +879,13 @@ class FfsInfStatement(FfsInfStatementClassObject):
                             % (Rule.NameGuid))\r
             self.ModuleGuid = RegistryGuidStr\r
 \r
                             % (Rule.NameGuid))\r
             self.ModuleGuid = RegistryGuidStr\r
 \r
-        GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,\r
-                                         Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],\r
-                                         self.ModuleGuid, Fixed=Rule.Fixed,\r
-                                         CheckSum=Rule.CheckSum, Align=Rule.Alignment,\r
-                                         SectionAlign=SectionAlignments\r
-                                        )\r
+            GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,\r
+                                             FdfFvFileTypeToFileType[Rule.FvFileType],\r
+                                             self.ModuleGuid, Fixed=Rule.Fixed,\r
+                                             CheckSum=Rule.CheckSum, Align=Rule.Alignment,\r
+                                             SectionAlign=SectionAlignments,\r
+                                             MakefilePath=MakefilePath\r
+                                             )\r
         return FfsOutput\r
 \r
     ## __GenComplexFileSection__() method\r
         return FfsOutput\r
 \r
     ## __GenComplexFileSection__() method\r
@@ -766,14 +898,14 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  FvParentAddr Parent Fv base address\r
     #   @retval string       File name of the generated section file\r
     #\r
     #   @param  FvParentAddr Parent Fv base address\r
     #   @retval string       File name of the generated section file\r
     #\r
-    def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr):\r
-        if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):\r
-            if Rule.KeepReloc != None:\r
+    def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr, IsMakefile = False):\r
+        if self.ModuleType in (SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE):\r
+            if Rule.KeepReloc is not None:\r
                 self.KeepRelocFromRule = Rule.KeepReloc\r
         SectFiles = []\r
         SectAlignments = []\r
         Index = 1\r
                 self.KeepRelocFromRule = Rule.KeepReloc\r
         SectFiles = []\r
         SectAlignments = []\r
         Index = 1\r
-        HasGneratedFlag = False\r
+        HasGeneratedFlag = False\r
         if self.PcdIsDriver == 'PEI_PCD_DRIVER':\r
             if self.IsBinaryModule:\r
                 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "PEIPcdDataBase.raw")\r
         if self.PcdIsDriver == 'PEI_PCD_DRIVER':\r
             if self.IsBinaryModule:\r
                 PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "PEIPcdDataBase.raw")\r
@@ -783,6 +915,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
             GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,\r
                                                  [PcdExDbFileName],\r
                                                  "EFI_SECTION_RAW",\r
             GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,\r
                                                  [PcdExDbFileName],\r
                                                  "EFI_SECTION_RAW",\r
+                                                 IsMakefile = IsMakefile\r
                                                  )\r
             SectFiles.append(PcdExDbSecName)\r
             SectAlignments.append(None)\r
                                                  )\r
             SectFiles.append(PcdExDbSecName)\r
             SectAlignments.append(None)\r
@@ -793,9 +926,10 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 PcdExDbFileName = os.path.join(self.EfiOutputPath, "DXEPcdDataBase.raw")\r
             PcdExDbSecName = os.path.join(self.OutputPath, "DXEPcdDataBaseSec.raw")\r
             GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,\r
                 PcdExDbFileName = os.path.join(self.EfiOutputPath, "DXEPcdDataBase.raw")\r
             PcdExDbSecName = os.path.join(self.OutputPath, "DXEPcdDataBaseSec.raw")\r
             GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,\r
-                                                 [PcdExDbFileName],\r
-                                                 "EFI_SECTION_RAW",\r
-                                                 )\r
+                                                [PcdExDbFileName],\r
+                                                "EFI_SECTION_RAW",\r
+                                                IsMakefile = IsMakefile\r
+                                                )\r
             SectFiles.append(PcdExDbSecName)\r
             SectAlignments.append(None)\r
         for Sect in Rule.SectionList:\r
             SectFiles.append(PcdExDbSecName)\r
             SectAlignments.append(None)\r
         for Sect in Rule.SectionList:\r
@@ -804,14 +938,14 @@ class FfsInfStatement(FfsInfStatementClassObject):
             #\r
             # Convert Fv Section Type for PI1.1 SMM driver.\r
             #\r
             #\r
             # Convert Fv Section Type for PI1.1 SMM driver.\r
             #\r
-            if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:\r
-                if Sect.SectionType == 'DXE_DEPEX':\r
-                    Sect.SectionType = 'SMM_DEPEX'\r
+            if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) >= 0x0001000A:\r
+                if Sect.SectionType == BINARY_FILE_TYPE_DXE_DEPEX:\r
+                    Sect.SectionType = BINARY_FILE_TYPE_SMM_DEPEX\r
             #\r
             # Framework SMM Driver has no SMM_DEPEX section type\r
             #\r
             #\r
             # Framework SMM Driver has no SMM_DEPEX section type\r
             #\r
-            if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:\r
-                if Sect.SectionType == 'SMM_DEPEX':\r
+            if self.ModuleType == SUP_MODULE_DXE_SMM_DRIVER and int(self.PiSpecVersion, 16) < 0x0001000A:\r
+                if Sect.SectionType == BINARY_FILE_TYPE_SMM_DEPEX:\r
                     EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)\r
             #\r
             # process the inside FvImage from FvSection or GuidSection\r
                     EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)\r
             #\r
             # process the inside FvImage from FvSection or GuidSection\r
@@ -821,17 +955,17 @@ class FfsInfStatement(FfsInfStatementClassObject):
                     Sect.FvAddr = FvChildAddr.pop(0)\r
                 elif isinstance(Sect, GuidSection):\r
                     Sect.FvAddr = FvChildAddr\r
                     Sect.FvAddr = FvChildAddr.pop(0)\r
                 elif isinstance(Sect, GuidSection):\r
                     Sect.FvAddr = FvChildAddr\r
-            if FvParentAddr != None and isinstance(Sect, GuidSection):\r
+            if FvParentAddr is not None and isinstance(Sect, GuidSection):\r
                 Sect.FvParentAddr = FvParentAddr\r
                 Sect.FvParentAddr = FvParentAddr\r
-            \r
+\r
             if Rule.KeyStringList != []:\r
             if Rule.KeyStringList != []:\r
-                SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self)\r
+                SectList, Align = Sect.GenSection(self.OutputPath, self.ModuleGuid, SecIndex, Rule.KeyStringList, self, IsMakefile = IsMakefile)\r
             else :\r
             else :\r
-                SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self)\r
-            \r
-            if not HasGneratedFlag:\r
-                UniVfrOffsetFileSection = ""    \r
-                ModuleFileName = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)\r
+                SectList, Align = Sect.GenSection(self.OutputPath, self.ModuleGuid, SecIndex, self.KeyStringList, self, IsMakefile = IsMakefile)\r
+\r
+            if not HasGeneratedFlag:\r
+                UniVfrOffsetFileSection = ""\r
+                ModuleFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)\r
                 InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch]\r
                 #\r
                 # Search the source list in InfData to find if there are .vfr file exist.\r
                 InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch]\r
                 #\r
                 # Search the source list in InfData to find if there are .vfr file exist.\r
@@ -841,38 +975,52 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 for SourceFile in InfData.Sources:\r
                     if SourceFile.Type.upper() == ".VFR" :\r
                         #\r
                 for SourceFile in InfData.Sources:\r
                     if SourceFile.Type.upper() == ".VFR" :\r
                         #\r
-                        # search the .map file to find the offset of vfr binary in the PE32+/TE file. \r
+                        # search the .map file to find the offset of vfr binary in the PE32+/TE file.\r
                         #\r
                         VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin")\r
                     if SourceFile.Type.upper() == ".UNI" :\r
                         #\r
                         #\r
                         VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin")\r
                     if SourceFile.Type.upper() == ".UNI" :\r
                         #\r
-                        # search the .map file to find the offset of Uni strings binary in the PE32+/TE file. \r
+                        # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.\r
                         #\r
                         VfrUniBaseName["UniOffsetName"] = (self.BaseName + "Strings")\r
                         #\r
                         VfrUniBaseName["UniOffsetName"] = (self.BaseName + "Strings")\r
-                    \r
-                \r
+\r
+\r
                 if len(VfrUniBaseName) > 0:\r
                 if len(VfrUniBaseName) > 0:\r
-                    VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName)\r
-                    #\r
-                    # Generate the Raw data of raw section\r
-                    #\r
-                    os.path.join( self.OutputPath, self.BaseName + '.offset')\r
-                    UniVfrOffsetFileName    =  os.path.join( self.OutputPath, self.BaseName + '.offset')\r
-                    UniVfrOffsetFileSection =  os.path.join( self.OutputPath, self.BaseName + 'Offset' + '.raw')\r
-                    \r
-                    self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName)\r
-                    \r
-                    UniVfrOffsetFileNameList = []\r
-                    UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)\r
-                    """Call GenSection"""\r
-                    GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,\r
-                                                         UniVfrOffsetFileNameList,\r
-                                                         "EFI_SECTION_RAW"\r
-                                                         )\r
-                    os.remove(UniVfrOffsetFileName)         \r
-                    SectList.append(UniVfrOffsetFileSection)\r
-                    HasGneratedFlag = True\r
-                \r
+                    if IsMakefile:\r
+                        if InfData.BuildType != 'UEFI_HII':\r
+                            UniVfrOffsetFileName = os.path.join(self.OutputPath, self.BaseName + '.offset')\r
+                            UniVfrOffsetFileSection = os.path.join(self.OutputPath, self.BaseName + 'Offset' + '.raw')\r
+                            UniVfrOffsetFileNameList = []\r
+                            UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)\r
+                            TrimCmd = "Trim --Vfr-Uni-Offset -o %s --ModuleName=%s --DebugDir=%s " % (UniVfrOffsetFileName, self.BaseName, self.EfiDebugPath)\r
+                            GenFdsGlobalVariable.SecCmdList.append(TrimCmd)\r
+                            GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,\r
+                                                                [UniVfrOffsetFileName],\r
+                                                                "EFI_SECTION_RAW",\r
+                                                                IsMakefile = True\r
+                                                                )\r
+                    else:\r
+                        VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName)\r
+                        #\r
+                        # Generate the Raw data of raw section\r
+                        #\r
+                        if VfrUniOffsetList:\r
+                            UniVfrOffsetFileName = os.path.join(self.OutputPath, self.BaseName + '.offset')\r
+                            UniVfrOffsetFileSection = os.path.join(self.OutputPath, self.BaseName + 'Offset' + '.raw')\r
+                            FfsInfStatement.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName)\r
+                            UniVfrOffsetFileNameList = []\r
+                            UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)\r
+                            """Call GenSection"""\r
+\r
+                            GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,\r
+                                                                 UniVfrOffsetFileNameList,\r
+                                                                 "EFI_SECTION_RAW"\r
+                                                                 )\r
+                            #os.remove(UniVfrOffsetFileName)\r
+                    if UniVfrOffsetFileSection:\r
+                        SectList.append(UniVfrOffsetFileSection)\r
+                        HasGeneratedFlag = True\r
+\r
             for SecName in  SectList :\r
                 SectFiles.append(SecName)\r
                 SectAlignments.append(Align)\r
             for SecName in  SectList :\r
                 SectFiles.append(SecName)\r
                 SectAlignments.append(Align)\r
@@ -888,9 +1036,9 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  InputFileList        The output file list from GenSection\r
     #   @retval string      Generated FFS file name\r
     #\r
     #   @param  InputFileList        The output file list from GenSection\r
     #   @retval string      Generated FFS file name\r
     #\r
-    def __GenComplexFileFfs__(self, Rule, InputFile, Alignments):\r
+    def __GenComplexFileFfs__(self, Rule, InputFile, Alignments, MakefilePath = None):\r
 \r
 \r
-        if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):\r
+        if Rule.NameGuid is not None and Rule.NameGuid.startswith('PCD('):\r
             PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)\r
             if len(PcdValue) == 0:\r
                 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \\r
             PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)\r
             if len(PcdValue) == 0:\r
                 EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \\r
@@ -905,34 +1053,14 @@ class FfsInfStatement(FfsInfStatementClassObject):
 \r
         FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')\r
         GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile,\r
 \r
         FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')\r
         GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile,\r
-                                         Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],\r
-                                         self.ModuleGuid, Fixed=Rule.Fixed,\r
-                                         CheckSum=Rule.CheckSum, Align=Rule.Alignment,\r
-                                         SectionAlign=Alignments\r
-                                        )\r
+                                             FdfFvFileTypeToFileType[Rule.FvFileType],\r
+                                             self.ModuleGuid, Fixed=Rule.Fixed,\r
+                                             CheckSum=Rule.CheckSum, Align=Rule.Alignment,\r
+                                             SectionAlign=Alignments,\r
+                                             MakefilePath=MakefilePath\r
+                                             )\r
         return FfsOutput\r
 \r
         return FfsOutput\r
 \r
-    ## __GetGenFfsCmdParameter__() method\r
-    #\r
-    #   Create parameter string for GenFfs\r
-    #\r
-    #   @param  self        The object pointer\r
-    #   @param  Rule        The rule object used to generate section\r
-    #   @retval tuple       (FileType, Fixed, CheckSum, Alignment)\r
-    #\r
-    def __GetGenFfsCmdParameter__(self, Rule):\r
-        result = tuple()\r
-        result += ('-t', Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType])\r
-        if Rule.Fixed != False:\r
-            result += ('-x',)\r
-        if Rule.CheckSum != False:\r
-            result += ('-s',)\r
-\r
-        if Rule.Alignment != None and Rule.Alignment != '':\r
-            result += ('-a', Rule.Alignment)\r
-\r
-        return result\r
\r
     ## __GetBuildOutputMapFileVfrUniInfo() method\r
     #\r
     #   Find the offset of UNI/INF object offset in the EFI image file.\r
     ## __GetBuildOutputMapFileVfrUniInfo() method\r
     #\r
     #   Find the offset of UNI/INF object offset in the EFI image file.\r
@@ -940,68 +1068,25 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @param  self                  The object pointer\r
     #   @param  VfrUniBaseName        A name list contain the UNI/INF object name.\r
     #   @retval RetValue              A list contain offset of UNI/INF object.\r
     #   @param  self                  The object pointer\r
     #   @param  VfrUniBaseName        A name list contain the UNI/INF object name.\r
     #   @retval RetValue              A list contain offset of UNI/INF object.\r
-    #    \r
+    #\r
     def __GetBuildOutputMapFileVfrUniInfo(self, VfrUniBaseName):\r
     def __GetBuildOutputMapFileVfrUniInfo(self, VfrUniBaseName):\r
-        \r
-        RetValue = []\r
-        \r
         MapFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".map")\r
         MapFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".map")\r
-        try:\r
-            fInputfile = open(MapFileName, "r", 0)\r
-            try:\r
-                FileLinesList = fInputfile.readlines()\r
-            except:\r
-                EdkLogger.error("GenFds", FILE_READ_FAILURE, "File read failed for %s" %MapFileName,None)\r
-            finally:\r
-                fInputfile.close()\r
-        except:\r
-            EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %MapFileName,None)\r
-        \r
-        IsHex = False\r
-        for eachLine in FileLinesList:\r
-            for eachName in VfrUniBaseName.values():\r
-                if eachLine.find(eachName) != -1:\r
-                    eachLine = eachLine.strip()\r
-                    Element  = eachLine.split()\r
-                    #\r
-                    # MSFT/ICC/EBC map file\r
-                    #\r
-                    if (len(Element) == 4):\r
-                        try:\r
-                            int (Element[2], 16)\r
-                            IsHex = True\r
-                        except:\r
-                            IsHex = False\r
-                    \r
-                        if IsHex:\r
-                            RetValue.append((eachName, Element[2]))\r
-                            IsHex = False\r
-                    #\r
-                    # GCC map file\r
-                    #\r
-                    elif (len(Element) == 2) and Element[0].startswith("0x"):\r
-                        RetValue.append((eachName, Element[0]))\r
-        \r
-        return RetValue\r
-    \r
+        EfiFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".efi")\r
+        return GetVariableOffset(MapFileName, EfiFileName, list(VfrUniBaseName.values()))\r
+\r
     ## __GenUniVfrOffsetFile() method\r
     #\r
     #   Generate the offset file for the module which contain VFR or UNI file.\r
     #\r
     ## __GenUniVfrOffsetFile() method\r
     #\r
     #   Generate the offset file for the module which contain VFR or UNI file.\r
     #\r
-    #   @param  self                    The object pointer\r
     #   @param  VfrUniOffsetList        A list contain the VFR/UNI offsets in the EFI image file.\r
     #   @param  UniVfrOffsetFileName    The output offset file name.\r
     #\r
     #   @param  VfrUniOffsetList        A list contain the VFR/UNI offsets in the EFI image file.\r
     #   @param  UniVfrOffsetFileName    The output offset file name.\r
     #\r
-    def __GenUniVfrOffsetFile(self, VfrUniOffsetList, UniVfrOffsetFileName):\r
-        \r
-        try:\r
-            fInputfile = open(UniVfrOffsetFileName, "wb+", 0)\r
-        except:\r
-            EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %UniVfrOffsetFileName,None)\r
-            \r
+    @staticmethod\r
+    def __GenUniVfrOffsetFile(VfrUniOffsetList, UniVfrOffsetFileName):\r
+\r
         # Use a instance of StringIO to cache data\r
         # Use a instance of StringIO to cache data\r
-        fStringIO = StringIO.StringIO('')  \r
-        \r
+        fStringIO = BytesIO()\r
+\r
         for Item in VfrUniOffsetList:\r
             if (Item[0].find("Strings") != -1):\r
                 #\r
         for Item in VfrUniOffsetList:\r
             if (Item[0].find("Strings") != -1):\r
                 #\r
@@ -1009,9 +1094,8 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 # GUID + Offset\r
                 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }\r
                 #\r
                 # GUID + Offset\r
                 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }\r
                 #\r
-                UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]\r
-                UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]\r
-                fStringIO.write(''.join(UniGuid))            \r
+                UniGuid = b'\xe0\xc5\x13\x89\xf63\x86M\x9b\xf1C\xef\x89\xfc\x06f'\r
+                fStringIO.write(UniGuid)\r
                 UniValue = pack ('Q', int (Item[1], 16))\r
                 fStringIO.write (UniValue)\r
             else:\r
                 UniValue = pack ('Q', int (Item[1], 16))\r
                 fStringIO.write (UniValue)\r
             else:\r
@@ -1020,28 +1104,20 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 # GUID + Offset\r
                 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };\r
                 #\r
                 # GUID + Offset\r
                 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };\r
                 #\r
-                VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]\r
-                VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]\r
-                fStringIO.write(''.join(VfrGuid))                   \r
-                type (Item[1]) \r
+                VfrGuid = b'\xb4|\xbc\xd0Gj_I\xaa\x11q\x07F\xda\x06\xa2'\r
+                fStringIO.write(VfrGuid)\r
+                type (Item[1])\r
                 VfrValue = pack ('Q', int (Item[1], 16))\r
                 fStringIO.write (VfrValue)\r
                 VfrValue = pack ('Q', int (Item[1], 16))\r
                 fStringIO.write (VfrValue)\r
-            \r
+\r
         #\r
         # write data into file.\r
         #\r
         #\r
         # write data into file.\r
         #\r
-        try :  \r
-            fInputfile.write (fStringIO.getvalue())\r
+        try :\r
+            SaveFileOnChange(UniVfrOffsetFileName, fStringIO.getvalue())\r
         except:\r
         except:\r
-            EdkLogger.error("GenFds", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %UniVfrOffsetFileName,None)\r
-        \r
+            EdkLogger.error("GenFds", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %UniVfrOffsetFileName, None)\r
+\r
         fStringIO.close ()\r
         fStringIO.close ()\r
-        fInputfile.close ()\r
-        \r
-                \r
-                    \r
-            \r
-            \r
-        \r
-                                \r
-        \r
+\r
+\r