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....@intel.com>
---
 Source/Python/GenFds/FdfParser.py       | 57 +++++++++++++++++++++------------
 Source/Python/GenFds/FfsInfStatement.py | 44 +++++++++++++++++++++++--
 Source/Python/GenFds/Region.py          | 21 ++++++++----
 3 files changed, 91 insertions(+), 31 deletions(-)

diff --git a/Source/Python/GenFds/FdfParser.py 
b/Source/Python/GenFds/FdfParser.py
index 664bf8e..01c035c 100644
--- a/Source/Python/GenFds/FdfParser.py
+++ b/Source/Python/GenFds/FdfParser.py
@@ -1,9 +1,9 @@
 ## @file
 # parse FDF file
 #
-#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
 #  Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD 
License
 #  which accompanies this distribution.  The full text of the license may be 
found at
@@ -1844,11 +1844,11 @@ class FdfParser:
         RegionObj.Size = Size
 
         if not self.__GetNextWord():
             return True
 
-        if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE"):
+        if not self.__Token in ("SET", "FV", "FILE", "DATA", "CAPSULE", "INF"):
             #
             # If next token is a word which is not a valid FV type, it might 
be part of [PcdOffset[|PcdSize]]
             # Or it might be next region's offset described by an expression 
which starts with a PCD.
             #    PcdOffset[|PcdSize] or OffsetPcdExpression|Size
             #
@@ -1885,21 +1885,31 @@ class FdfParser:
             self.__UndoToken()
             self.__GetRegionCapType( RegionObj)
 
         elif self.__Token == "FILE":
             self.__UndoToken()
-            self.__GetRegionFileType( RegionObj)
+            self.__GetRegionFileType(RegionObj)
+
+        elif self.__Token == "INF":
+            self.__UndoToken()
+            RegionObj.RegionType = "INF"
+            while self.__IsKeyword("INF"):
+                self.__UndoToken()
+                ffsInf = self.__ParseInfStatement()
+                if not ffsInf:
+                    break
+                RegionObj.RegionDataList.append(ffsInf)
 
         elif self.__Token == "DATA":
             self.__UndoToken()
-            self.__GetRegionDataType( RegionObj)
+            self.__GetRegionDataType(RegionObj)
         else:
             self.__UndoToken()
             if self.__GetRegionLayout(Fd):
                 return True
             raise Warning("A valid region type was not found. "
-                          "Valid types are [SET, FV, CAPSULE, FILE, DATA]. 
This error occurred",
+                          "Valid types are [SET, FV, CAPSULE, FILE, DATA, 
INF]. This error occurred",
                           self.FileName, self.CurrentLineNumber)
 
         return True
 
     ## __GetRegionFvType() method
@@ -2424,27 +2434,16 @@ class FdfParser:
             raise Warning("expected '}'", self.FileName, 
self.CurrentLineNumber)
 
         FvObj.AprioriSectionList.append(AprSectionObj)
         return True
 
-    ## __GetInfStatement() method
-    #
-    #   Get INF statements
-    #
-    #   @param  self        The object pointer
-    #   @param  Obj         for whom inf statement is got
-    #   @param  MacroDict   dictionary used to replace macro
-    #   @retval True        Successfully find inf statement
-    #   @retval False       Not able to find inf statement
-    #
-    def __GetInfStatement(self, Obj, ForCapsule = False, MacroDict = {}):
-
-        if not self.__IsKeyword( "INF"):
-            return False
+    def __ParseInfStatement(self):
+        if not self.__IsKeyword("INF"):
+            return None
 
         ffsInf = FfsInfStatement.FfsInfStatement()
-        self.__GetInfOptions( ffsInf)
+        self.__GetInfOptions(ffsInf)
 
         if not self.__GetNextToken():
             raise Warning("expected INF file path", self.FileName, 
self.CurrentLineNumber)
         ffsInf.InfFileName = self.__Token
 
@@ -2470,11 +2469,27 @@ class FdfParser:
                 ffsInf.KeepReloc = False
             elif self.__IsKeyword('RELOCS_RETAINED'):
                 ffsInf.KeepReloc = True
             else:
                 raise Warning("Unknown reloc strip flag '%s'" % self.__Token, 
self.FileName, self.CurrentLineNumber)
-        
+        return ffsInf
+
+    ## __GetInfStatement() method
+    #
+    #   Get INF statements
+    #
+    #   @param  self        The object pointer
+    #   @param  Obj         for whom inf statement is got
+    #   @param  MacroDict   dictionary used to replace macro
+    #   @retval True        Successfully find inf statement
+    #   @retval False       Not able to find inf statement
+    #
+    def __GetInfStatement(self, Obj, ForCapsule=False, MacroDict={}):
+        ffsInf = self.__ParseInfStatement()
+        if not ffsInf:
+            return False
+
         if ForCapsule:
             capsuleFfs = CapsuleData.CapsuleFfs()
             capsuleFfs.Ffs = ffsInf
             Obj.CapsuleDataList.append(capsuleFfs)
         else:
diff --git a/Source/Python/GenFds/FfsInfStatement.py 
b/Source/Python/GenFds/FfsInfStatement.py
index ed767d3..b9cb4f2 100644
--- a/Source/Python/GenFds/FfsInfStatement.py
+++ b/Source/Python/GenFds/FfsInfStatement.py
@@ -329,29 +329,67 @@ class FfsInfStatement(FfsInfStatementClassObject):
     #  @param EfiFile: EFI file needs to be patched.
     #  @retval: Full path of patched EFI file: self.OutputPath + EfiFile base 
name
     #           If passed in file does not end with efi, return as is
     #
     def PatchEfiFile(self, EfiFile, FileType):
+        #
+        # If the module does not have any patches, then return path to input 
file
+        #  
         if not self.PatchPcds:
             return EfiFile
+
+        #
+        # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED
+        #  
         if FileType != 'PE32' and self.ModuleType != "USER_DEFINED":
             return EfiFile
+
+        #
+        # Generate path to patched output file
+        #
+        Basename = os.path.basename(EfiFile)
+        Output = os.path.normpath (os.path.join(self.OutputPath, Basename))
+
+        #
+        # If this file has already been patched, then return the path to the 
patched file
+        #
+        if self.PatchedBinFile == Output:
+          return Output
+
+        #
+        # If a different file from the same module has already been patched, 
then generate an error
+        #  
         if self.PatchedBinFile:
             EdkLogger.error("GenFds", GENFDS_ERROR,
                             'Only one binary file can be patched:\n'
                             '  a binary file has been patched: %s\n'
                             '  current file: %s' % (self.PatchedBinFile, 
EfiFile),
                             File=self.InfFileName)
-        Basename = os.path.basename(EfiFile)
-        Output = os.path.join(self.OutputPath, Basename)
+
+        #
+        # Copy unpatched file contents to output file location to perform 
patching
+        #  
         CopyLongFilePath(EfiFile, Output)
+
+        #
+        # Apply patches to patched output file
+        #  
         for Pcd, Value in self.PatchPcds:
             RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), 
Pcd.DatumType, Value, Pcd.MaxDatumSize)
             if RetVal:
                 EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, 
File=self.InfFileName)
-        self.PatchedBinFile = os.path.normpath(EfiFile)
+
+        #
+        # Save the path of the patched output file
+        #  
+        self.PatchedBinFile = Output
+
+        #
+        # Return path to patched output file
+        #  
         return Output
+
     ## GenFfs() method
     #
     #   Generate FFS
     #
     #   @param  self         The object pointer
diff --git a/Source/Python/GenFds/Region.py b/Source/Python/GenFds/Region.py
index feb56cb..f259124 100644
--- a/Source/Python/GenFds/Region.py
+++ b/Source/Python/GenFds/Region.py
@@ -1,9 +1,9 @@
 ## @file
 # process FD Region generation
 #
-#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
+#  Copyright (c) 2007 - 2015, Intel Corporation. All rights reserved.<BR>
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD 
License
 #  which accompanies this distribution.  The full text of the license may be 
found at
 #  http://opensource.org/licenses/bsd-license.php
@@ -200,17 +200,24 @@ class Region(RegionClassObject):
                 else :
                     PadData = 0
                 for i in range(0, Size):
                     Buffer.write(pack('B', PadData))
 
-        if self.RegionType == 'FILE':
+        if self.RegionType in ('FILE', 'INF'):
             for RegionData in self.RegionDataList:
-                RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, 
MacroDict)
-                if RegionData[1] != ':' :
-                    RegionData = mws.join (GenFdsGlobalVariable.WorkSpaceDir, 
RegionData)
-                if not os.path.exists(RegionData):
-                    EdkLogger.error("GenFds", FILE_NOT_FOUND, 
ExtraData=RegionData)
+                if self.RegionType == 'INF':
+                    RegionData.__InfParse__(None)
+                    if len(RegionData.BinFileList) != 1:
+                        EdkLogger.error('GenFds', GENFDS_ERROR, 'INF in FD 
region can only contain one binary: %s' % RegionData)
+                    File = RegionData.BinFileList[0]
+                    RegionData = RegionData.PatchEfiFile(File.Path, File.Type)
+                else:
+                    RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, 
MacroDict)
+                    if RegionData[1] != ':' :
+                        RegionData = os.path.join 
(GenFdsGlobalVariable.WorkSpaceDir, RegionData)
+                    if not os.path.exists(RegionData):
+                        EdkLogger.error("GenFds", FILE_NOT_FOUND, 
ExtraData=RegionData)
                 #
                 # Add the file image into FD buffer
                 #
                 FileLength = os.stat(RegionData)[ST_SIZE]
                 if FileLength > Size:
-- 
2.6.1.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to