mirror of https://github.com/acidanthera/audk.git
BaseTools: Add support for INF statement in FD region
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
This commit is contained in:
parent
84c7452165
commit
b21a13fbb6
|
@ -1,7 +1,7 @@
|
||||||
## @file
|
## @file
|
||||||
# parse FDF 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>
|
# Copyright (c) 2015, Hewlett Packard Enterprise Development, L.P.<BR>
|
||||||
#
|
#
|
||||||
# This program and the accompanying materials
|
# This program and the accompanying materials
|
||||||
|
@ -1846,7 +1846,7 @@ class FdfParser:
|
||||||
if not self.__GetNextWord():
|
if not self.__GetNextWord():
|
||||||
return True
|
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]]
|
# 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.
|
# Or it might be next region's offset described by an expression which starts with a PCD.
|
||||||
|
@ -1887,17 +1887,27 @@ class FdfParser:
|
||||||
|
|
||||||
elif self.__Token == "FILE":
|
elif self.__Token == "FILE":
|
||||||
self.__UndoToken()
|
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":
|
elif self.__Token == "DATA":
|
||||||
self.__UndoToken()
|
self.__UndoToken()
|
||||||
self.__GetRegionDataType( RegionObj)
|
self.__GetRegionDataType(RegionObj)
|
||||||
else:
|
else:
|
||||||
self.__UndoToken()
|
self.__UndoToken()
|
||||||
if self.__GetRegionLayout(Fd):
|
if self.__GetRegionLayout(Fd):
|
||||||
return True
|
return True
|
||||||
raise Warning("A valid region type was not found. "
|
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)
|
self.FileName, self.CurrentLineNumber)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
@ -2426,23 +2436,12 @@ class FdfParser:
|
||||||
FvObj.AprioriSectionList.append(AprSectionObj)
|
FvObj.AprioriSectionList.append(AprSectionObj)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
## __GetInfStatement() method
|
def __ParseInfStatement(self):
|
||||||
#
|
if not self.__IsKeyword("INF"):
|
||||||
# Get INF statements
|
return None
|
||||||
#
|
|
||||||
# @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
|
|
||||||
|
|
||||||
ffsInf = FfsInfStatement.FfsInfStatement()
|
ffsInf = FfsInfStatement.FfsInfStatement()
|
||||||
self.__GetInfOptions( ffsInf)
|
self.__GetInfOptions(ffsInf)
|
||||||
|
|
||||||
if not self.__GetNextToken():
|
if not self.__GetNextToken():
|
||||||
raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)
|
raise Warning("expected INF file path", self.FileName, self.CurrentLineNumber)
|
||||||
|
@ -2472,7 +2471,23 @@ class FdfParser:
|
||||||
ffsInf.KeepReloc = True
|
ffsInf.KeepReloc = True
|
||||||
else:
|
else:
|
||||||
raise Warning("Unknown reloc strip flag '%s'" % self.__Token, self.FileName, self.CurrentLineNumber)
|
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:
|
if ForCapsule:
|
||||||
capsuleFfs = CapsuleData.CapsuleFfs()
|
capsuleFfs = CapsuleData.CapsuleFfs()
|
||||||
capsuleFfs.Ffs = ffsInf
|
capsuleFfs.Ffs = ffsInf
|
||||||
|
|
|
@ -331,25 +331,63 @@ class FfsInfStatement(FfsInfStatementClassObject):
|
||||||
# If passed in file does not end with efi, return as is
|
# If passed in file does not end with efi, return as is
|
||||||
#
|
#
|
||||||
def PatchEfiFile(self, EfiFile, FileType):
|
def PatchEfiFile(self, EfiFile, FileType):
|
||||||
|
#
|
||||||
|
# If the module does not have any patches, then return path to input file
|
||||||
|
#
|
||||||
if not self.PatchPcds:
|
if not self.PatchPcds:
|
||||||
return EfiFile
|
return EfiFile
|
||||||
|
|
||||||
|
#
|
||||||
|
# Only patch file if FileType is PE32 or ModuleType is USER_DEFINED
|
||||||
|
#
|
||||||
if FileType != 'PE32' and self.ModuleType != "USER_DEFINED":
|
if FileType != 'PE32' and self.ModuleType != "USER_DEFINED":
|
||||||
return EfiFile
|
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:
|
if self.PatchedBinFile:
|
||||||
EdkLogger.error("GenFds", GENFDS_ERROR,
|
EdkLogger.error("GenFds", GENFDS_ERROR,
|
||||||
'Only one binary file can be patched:\n'
|
'Only one binary file can be patched:\n'
|
||||||
' a binary file has been patched: %s\n'
|
' a binary file has been patched: %s\n'
|
||||||
' current file: %s' % (self.PatchedBinFile, EfiFile),
|
' current file: %s' % (self.PatchedBinFile, EfiFile),
|
||||||
File=self.InfFileName)
|
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)
|
CopyLongFilePath(EfiFile, Output)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Apply patches to patched output file
|
||||||
|
#
|
||||||
for Pcd, Value in self.PatchPcds:
|
for Pcd, Value in self.PatchPcds:
|
||||||
RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Value, Pcd.MaxDatumSize)
|
RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Value, Pcd.MaxDatumSize)
|
||||||
if RetVal:
|
if RetVal:
|
||||||
EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName)
|
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
|
return Output
|
||||||
|
|
||||||
## GenFfs() method
|
## GenFfs() method
|
||||||
#
|
#
|
||||||
# Generate FFS
|
# Generate FFS
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
## @file
|
## @file
|
||||||
# process FD Region generation
|
# 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
|
# This program and the accompanying materials
|
||||||
# are licensed and made available under the terms and conditions of the BSD License
|
# are licensed and made available under the terms and conditions of the BSD License
|
||||||
|
@ -202,13 +202,20 @@ class Region(RegionClassObject):
|
||||||
for i in range(0, Size):
|
for i in range(0, Size):
|
||||||
Buffer.write(pack('B', PadData))
|
Buffer.write(pack('B', PadData))
|
||||||
|
|
||||||
if self.RegionType == 'FILE':
|
if self.RegionType in ('FILE', 'INF'):
|
||||||
for RegionData in self.RegionDataList:
|
for RegionData in self.RegionDataList:
|
||||||
RegionData = GenFdsGlobalVariable.MacroExtend(RegionData, MacroDict)
|
if self.RegionType == 'INF':
|
||||||
if RegionData[1] != ':' :
|
RegionData.__InfParse__(None)
|
||||||
RegionData = mws.join (GenFdsGlobalVariable.WorkSpaceDir, RegionData)
|
if len(RegionData.BinFileList) != 1:
|
||||||
if not os.path.exists(RegionData):
|
EdkLogger.error('GenFds', GENFDS_ERROR, 'INF in FD region can only contain one binary: %s' % RegionData)
|
||||||
EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=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
|
# Add the file image into FD buffer
|
||||||
#
|
#
|
||||||
|
|
Loading…
Reference in New Issue