]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/GenFds/FfsInfStatement.py
BaseTools: merge towards minimum PCD MAX <something> methods
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / FfsInfStatement.py
index 040d2ebcd4c8ff861976f459a9b72cfc6818a22f..37624f3fa9d4e0b9b357b65627d89bbb99aabef7 100644 (file)
@@ -1,8 +1,8 @@
 ## @file\r
 # process FFS generation from INF statement\r
 #\r
-#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
-#  Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<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
 #  This program and the accompanying materials\r
 #  are licensed and made available under the terms and conditions of the BSD License\r
@@ -28,10 +28,12 @@ import Section
 import RuleSimpleFile\r
 import RuleComplexFile\r
 from CommonDataClass.FdfClass import FfsInfStatementClassObject\r
+from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 from Common.String import *\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 GuidSection import GuidSection\r
@@ -41,13 +43,16 @@ from AutoGen.GenDepex import DependencyExpression
 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
-    ## 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
@@ -69,6 +74,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
         self.OverrideGuid = None\r
         self.PatchedBinFile = ''\r
         self.MacroDict = {}\r
+        self.Depex = False\r
 \r
     ## GetFinalTargetSuffixMap() method\r
     #\r
@@ -172,9 +178,13 @@ class FfsInfStatement(FfsInfStatementClassObject):
         if ErrorCode != 0:\r
             EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)\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 != None:\r
+        if self.CurrentArch is not None:\r
 \r
             Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]\r
             #\r
@@ -183,22 +193,22 @@ class FfsInfStatement(FfsInfStatementClassObject):
             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
-            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
-            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
-            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
@@ -217,13 +227,17 @@ class FfsInfStatement(FfsInfStatementClassObject):
         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
 \r
-        if Inf._Defs != None and len(Inf._Defs) > 0:\r
+        if self.ModuleType == '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
+        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
+        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
@@ -239,7 +253,6 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 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
@@ -255,11 +268,36 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 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
+\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
             if Pcd.DatumType == "VOID*":\r
-                if Pcd.DefaultValue == DefaultValue or DefaultValue in [None, '']:\r
+                if Pcd.InfDefaultValue == DefaultValue or DefaultValue in [None, '']:\r
                     continue\r
                 # Get the string size from FDF or DSC\r
                 if DefaultValue[0] == 'L':\r
@@ -273,15 +311,15 @@ class FfsInfStatement(FfsInfStatementClassObject):
                     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
+                    Pcd.MaxDatumSize = str(len(Pcd.InfDefaultValue.split(',')))\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
-                    PcdValueInImg = int(Pcd.DefaultValue, Base1)\r
+                    PcdValueInImg = int(Pcd.InfDefaultValue, Base1)\r
                     PcdValueInDscOrFdf = int(DefaultValue, Base2)\r
                     if PcdValueInImg == PcdValueInDscOrFdf:\r
                         continue\r
@@ -293,8 +331,8 @@ class FfsInfStatement(FfsInfStatementClassObject):
                     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
             self.PatchPcds.append((Pcd, DefaultValue))\r
@@ -302,6 +340,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
         self.InfModule = Inf\r
         self.PcdIsDriver = Inf.PcdIsDriver\r
         self.IsBinaryModule = Inf.IsBinaryModule\r
+        Inf._GetDepex()\r
+        Inf._GetDepexExpression()\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
@@ -317,7 +360,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
         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
     ## PatchEfiFile\r
@@ -329,25 +372,63 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #           If passed in file does not end with efi, return as is\r
     #\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
+\r
+        #\r
+        # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED\r
+        #  \r
         if FileType != 'PE32' and self.ModuleType != "USER_DEFINED":\r
             return EfiFile\r
+\r
+        #\r
+        # Generate path to patched output file\r
+        #\r
+        Basename = os.path.basename(EfiFile)\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
-        Basename = os.path.basename(EfiFile)\r
-        Output = os.path.join(self.OutputPath, Basename)\r
+\r
+        #\r
+        # Copy unpatched file contents to output file location to perform patching\r
+        #  \r
         CopyLongFilePath(EfiFile, Output)\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
-        self.PatchedBinFile = os.path.normpath(EfiFile)\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
+\r
     ## GenFfs() method\r
     #\r
     #   Generate FFS\r
@@ -358,13 +439,14 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @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
         self.__InfParse__(Dict)\r
-        SrcFile = os.path.join( GenFdsGlobalVariable.WorkSpaceDir , self.InfFileName);\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
@@ -393,9 +475,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
         # Allow binary type module not specify override rule in FDF file.\r
         # \r
         if len(self.BinFileList) > 0:\r
-            if self.Rule == None or self.Rule == "":\r
+            if self.Rule is None or self.Rule == "":\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
@@ -416,17 +500,21 @@ class FfsInfStatement(FfsInfStatementClassObject):
         #\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
-            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
@@ -458,7 +546,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #\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
@@ -469,23 +557,23 @@ class FfsInfStatement(FfsInfStatementClassObject):
                        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
-            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
-                   'COMMON'    + \\r
+                   TAB_COMMON    + \\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
@@ -493,11 +581,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
-        if Rule != None:\r
+        if Rule is not None:\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
@@ -510,37 +598,23 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #\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
-        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
@@ -575,7 +649,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
             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
@@ -609,13 +683,14 @@ class FfsInfStatement(FfsInfStatementClassObject):
     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
         if self.OverrideGuid:\r
             FileName = self.OverrideGuid\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
@@ -624,8 +699,15 @@ class FfsInfStatement(FfsInfStatementClassObject):
                                   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
-        return OutputPath\r
+        DebugPath = os.path.realpath(DebugPath)\r
+        return OutputPath, DebugPath\r
 \r
     ## __GenSimpleFileSection__() method\r
     #\r
@@ -635,14 +717,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
-    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
-        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
@@ -667,11 +749,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 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.KeepReloc is not None:\r
                 NoStrip = self.KeepReloc\r
-            elif Rule.KeepReloc != None:\r
+            elif Rule.KeepReloc is not None:\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
@@ -689,8 +771,10 @@ class FfsInfStatement(FfsInfStatementClassObject):
                     ImageObj = PeImageClass (File)\r
                     if ImageObj.SectionAlignment < 0x400:\r
                         self.Alignment = str (ImageObj.SectionAlignment)\r
-                    else:\r
+                    elif ImageObj.SectionAlignment < 0x100000:\r
                         self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'\r
+                    else:\r
+                        self.Alignment = str (ImageObj.SectionAlignment / 0x100000) + 'M'\r
 \r
                 if not NoStrip:\r
                     FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')\r
@@ -699,22 +783,23 @@ class FfsInfStatement(FfsInfStatementClassObject):
                         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
                 if SectionType == 'TE':\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
-\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
@@ -728,8 +813,10 @@ class FfsInfStatement(FfsInfStatementClassObject):
                 ImageObj = PeImageClass (GenSecInputFile)\r
                 if ImageObj.SectionAlignment < 0x400:\r
                     self.Alignment = str (ImageObj.SectionAlignment)\r
-                else:\r
+                elif ImageObj.SectionAlignment < 0x100000:\r
                     self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'\r
+                else:\r
+                    self.Alignment = str (ImageObj.SectionAlignment / 0x100000) + 'M'\r
 \r
             if not NoStrip:\r
                 FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')\r
@@ -739,22 +826,23 @@ class FfsInfStatement(FfsInfStatementClassObject):
 \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
             if SectionType == 'TE':\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
-\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
@@ -768,7 +856,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @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
@@ -781,7 +869,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
             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
@@ -794,12 +882,13 @@ class FfsInfStatement(FfsInfStatementClassObject):
                             % (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
+                                             Ffs.Ffs.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
@@ -812,14 +901,14 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @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
+    def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr, IsMakefile = False):\r
         if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):\r
-            if Rule.KeepReloc != None:\r
+            if Rule.KeepReloc is not None:\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
@@ -829,6 +918,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
             GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,\r
                                                  [PcdExDbFileName],\r
                                                  "EFI_SECTION_RAW",\r
+                                                 IsMakefile = IsMakefile\r
                                                  )\r
             SectFiles.append(PcdExDbSecName)\r
             SectAlignments.append(None)\r
@@ -839,9 +929,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],\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
@@ -867,17 +958,17 @@ class FfsInfStatement(FfsInfStatementClassObject):
                     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
             \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
-                SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self)\r
+                SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self, IsMakefile = IsMakefile)\r
             \r
-            if not HasGneratedFlag:\r
+            if not HasGeneratedFlag:\r
                 UniVfrOffsetFileSection = ""    \r
-                ModuleFileName = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)\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
@@ -898,26 +989,40 @@ class FfsInfStatement(FfsInfStatementClassObject):
                     \r
                 \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
+                    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
@@ -934,9 +1039,9 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @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
-        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
@@ -951,34 +1056,14 @@ class FfsInfStatement(FfsInfStatementClassObject):
 \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
+                                             Ffs.Ffs.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
-    ## __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
@@ -988,63 +1073,20 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #   @retval RetValue              A list contain offset of UNI/INF object.\r
     #    \r
     def __GetBuildOutputMapFileVfrUniInfo(self, VfrUniBaseName):\r
-        \r
-        RetValue = []\r
-        \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
+        EfiFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".efi")\r
+        return GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values())\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
-    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
         fStringIO = StringIO.StringIO('')  \r
         \r
@@ -1076,18 +1118,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
         #\r
         # write data into file.\r
         #\r
-        try :  \r
-            fInputfile.write (fStringIO.getvalue())\r
+        try :\r
+            SaveFileOnChange(UniVfrOffsetFileName, fStringIO.getvalue())\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
         fStringIO.close ()\r
-        fInputfile.close ()\r
-        \r
-                \r
-                    \r
-            \r
-            \r
-        \r
-                                \r
+\r
         \r