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