]> git.proxmox.com Git - mirror_edk2.git/commitdiff
BaseTools: Add support for INF statement in FD region
authorYonghong Zhu <yonghong.zhu@intel.com>
Mon, 7 Dec 2015 08:27:53 +0000 (08:27 +0000)
committeryzhu52 <yzhu52@Edk2>
Mon, 7 Dec 2015 08:27:53 +0000 (08:27 +0000)
FD region today can be file or data, but not a patched image.Add support
for an INF statement in an FD region, so the binary from the INF can be
patched prior to being added to the FD region.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19136 6f19259b-4bc3-4df7-8a09-765794883524

BaseTools/Source/Python/GenFds/FdfParser.py
BaseTools/Source/Python/GenFds/FfsInfStatement.py
BaseTools/Source/Python/GenFds/Region.py

index 664bf8e87d264fdc0e92b56648d16a8244dd44c0..788190567eef4366310fe8d502eb3cf0853db8f3 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # parse FDF file\r
 #\r
 ## @file\r
 # parse FDF file\r
 #\r
-#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>\r
 #  Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>\r
 #\r
 #  This program and the accompanying materials\r
 #  Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>\r
 #\r
 #  This program and the accompanying materials\r
@@ -1846,7 +1846,7 @@ class FdfParser:
         if not self.__GetNextWord():\r
             return True\r
 \r
         if not self.__GetNextWord():\r
             return True\r
 \r
-        if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE"):\r
+        if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE", "INF"):\r
             #\r
             # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]\r
             # Or it might be next region's offset described by an expression which starts with a PCD.\r
             #\r
             # If next token is a word which is not a valid FV type, it might be part of [PcdOffset[|PcdSize]]\r
             # Or it might be next region's offset described by an expression which starts with a PCD.\r
@@ -1887,17 +1887,27 @@ class FdfParser:
 \r
         elif self.__Token == "FILE":\r
             self.__UndoToken()\r
 \r
         elif self.__Token == "FILE":\r
             self.__UndoToken()\r
-            self.__GetRegionFileType( RegionObj)\r
+            self.__GetRegionFileType(RegionObj)\r
+\r
+        elif self.__Token == "INF":\r
+            self.__UndoToken()\r
+            RegionObj.RegionType = "INF"\r
+            while self.__IsKeyword("INF"):\r
+                self.__UndoToken()\r
+                ffsInf = self.__ParseInfStatement()\r
+                if not ffsInf:\r
+                    break\r
+                RegionObj.RegionDataList.append(ffsInf)\r
 \r
         elif self.__Token == "DATA":\r
             self.__UndoToken()\r
 \r
         elif self.__Token == "DATA":\r
             self.__UndoToken()\r
-            self.__GetRegionDataType( RegionObj)\r
+            self.__GetRegionDataType(RegionObj)\r
         else:\r
             self.__UndoToken()\r
             if self.__GetRegionLayout(Fd):\r
                 return True\r
             raise Warning("A valid region type was not found. "\r
         else:\r
             self.__UndoToken()\r
             if self.__GetRegionLayout(Fd):\r
                 return True\r
             raise Warning("A valid region type was not found. "\r
-                          "Valid types are [SET, FV, CAPSULE, FILE, DATA]. This error occurred",\r
+                          "Valid types are [SET, FV, CAPSULE, FILE, DATA, INF]. This error occurred",\r
                           self.FileName, self.CurrentLineNumber)\r
 \r
         return True\r
                           self.FileName, self.CurrentLineNumber)\r
 \r
         return True\r
@@ -2426,23 +2436,12 @@ class FdfParser:
         FvObj.AprioriSectionList.append(AprSectionObj)\r
         return True\r
 \r
         FvObj.AprioriSectionList.append(AprSectionObj)\r
         return True\r
 \r
-    ## __GetInfStatement() method\r
-    #\r
-    #   Get INF statements\r
-    #\r
-    #   @param  self        The object pointer\r
-    #   @param  Obj         for whom inf statement is got\r
-    #   @param  MacroDict   dictionary used to replace macro\r
-    #   @retval True        Successfully find inf statement\r
-    #   @retval False       Not able to find inf statement\r
-    #\r
-    def __GetInfStatement(self, Obj, ForCapsule = False, MacroDict = {}):\r
-\r
-        if not self.__IsKeyword( "INF"):\r
-            return False\r
+    def __ParseInfStatement(self):\r
+        if not self.__IsKeyword("INF"):\r
+            return None\r
 \r
         ffsInf = FfsInfStatement.FfsInfStatement()\r
 \r
         ffsInf = FfsInfStatement.FfsInfStatement()\r
-        self.__GetInfOptions( ffsInf)\r
+        self.__GetInfOptions(ffsInf)\r
 \r
         if not self.__GetNextToken():\r
             raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)\r
 \r
         if not self.__GetNextToken():\r
             raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)\r
@@ -2472,7 +2471,23 @@ class FdfParser:
                 ffsInf.KeepReloc = True\r
             else:\r
                 raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
                 ffsInf.KeepReloc = True\r
             else:\r
                 raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)\r
-        \r
+        return ffsInf\r
+\r
+    ## __GetInfStatement() method\r
+    #\r
+    #   Get INF statements\r
+    #\r
+    #   @param  self        The object pointer\r
+    #   @param  Obj         for whom inf statement is got\r
+    #   @param  MacroDict   dictionary used to replace macro\r
+    #   @retval True        Successfully find inf statement\r
+    #   @retval False       Not able to find inf statement\r
+    #\r
+    def __GetInfStatement(self, Obj, ForCapsule=False, MacroDict={}):\r
+        ffsInf = self.__ParseInfStatement()\r
+        if not ffsInf:\r
+            return False\r
+\r
         if ForCapsule:\r
             capsuleFfs = CapsuleData.CapsuleFfs()\r
             capsuleFfs.Ffs = ffsInf\r
         if ForCapsule:\r
             capsuleFfs = CapsuleData.CapsuleFfs()\r
             capsuleFfs.Ffs = ffsInf\r
index ed767d3fa698f33f607e0d906a183f5d091a6197..7b221399b4017a92e6e88a0c996cb41bb58176ed 100644 (file)
@@ -331,25 +331,63 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #           If passed in file does not end with efi, return as is\r
     #\r
     def PatchEfiFile(self, EfiFile, FileType):\r
     #           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
         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
         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
         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
         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
         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
         return Output\r
+\r
     ## GenFfs() method\r
     #\r
     #   Generate FFS\r
     ## GenFfs() method\r
     #\r
     #   Generate FFS\r
index 01e998e54c6fb6c5fa2ec1aa5c4d0f8e47622c54..8734635fda29d0b4993a4d1655bb6d854d63ba29 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # process FD Region generation\r
 #\r
 ## @file\r
 # process FD Region generation\r
 #\r
-#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<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
 #\r
 #  This program and the accompanying materials\r
 #  are licensed and made available under the terms and conditions of the BSD License\r
@@ -202,13 +202,20 @@ class Region(RegionClassObject):
                 for i in range(0, Size):\r
                     Buffer.write(pack('B', PadData))\r
 \r
                 for i in range(0, Size):\r
                     Buffer.write(pack('B', PadData))\r
 \r
-        if self.RegionType == 'FILE':\r
+        if self.RegionType in ('FILE', 'INF'):\r
             for RegionData in self.RegionDataList:\r
             for RegionData in self.RegionDataList:\r
-                RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)\r
-                if RegionData[1] != ':' :\r
-                    RegionData = mws.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)\r
-                if not os.path.exists(RegionData):\r
-                    EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)\r
+                if self.RegionType == 'INF':\r
+                    RegionData.__InfParse__(None)\r
+                    if len(RegionData.BinFileList) != 1:\r
+                        EdkLogger.error('GenFds', GENFDS_ERROR, 'INF in FD region can only contain one binary: %s' % RegionData)\r
+                    File = RegionData.BinFileList[0]\r
+                    RegionData = RegionData.PatchEfiFile(File.Path, File.Type)\r
+                else:\r
+                    RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)\r
+                    if RegionData[1] != ':' :\r
+                        RegionData = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)\r
+                    if not os.path.exists(RegionData):\r
+                        EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData)\r
                 #\r
                 # Add the file image into FD buffer\r
                 #\r
                 #\r
                 # Add the file image into FD buffer\r
                 #\r