## @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
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
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
- 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
- "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
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
- 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
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 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
## @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
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
- 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