BaseTools/EOT: Change to call a program instead of calling Python API.

Update the EOT tool to call the program itself instead of calling the Python API when parsing FV images.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Hess Chen <hesheng.chen@intel.com>
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
Acked-by: Jaben Carsey <jaben.carsey@intel.com>
This commit is contained in:
Hess Chen 2018-10-15 16:29:09 +08:00 committed by Yonghong Zhu
parent ff4d0f851d
commit 47f15da160
5 changed files with 83 additions and 442 deletions

View File

@ -17,18 +17,20 @@
from __future__ import absolute_import from __future__ import absolute_import
import Common.LongFilePathOs as os, time, glob import Common.LongFilePathOs as os, time, glob
import Common.EdkLogger as EdkLogger import Common.EdkLogger as EdkLogger
from . import EotGlobalData import Eot.EotGlobalData as EotGlobalData
from optparse import OptionParser from optparse import OptionParser
from Common.StringUtils import NormPath from Common.StringUtils import NormPath
from Common import BuildToolError from Common import BuildToolError
from Common.Misc import GuidStructureStringToGuidString, sdict from Common.Misc import GuidStructureStringToGuidString, sdict
from .InfParserLite import * from Eot.Parser import *
from . import c from Eot.InfParserLite import EdkInfParser
from . import Database from Common.StringUtils import GetSplitValueList
from Eot import c
from Eot import Database
from array import array from array import array
from .Report import Report from Eot.Report import Report
from Common.BuildVersion import gBUILD_VERSION from Common.BuildVersion import gBUILD_VERSION
from .Parser import ConvertGuid from Eot.Parser import ConvertGuid
from Common.LongFilePathSupport import OpenLongFilePath as open from Common.LongFilePathSupport import OpenLongFilePath as open
import struct import struct
import uuid import uuid
@ -58,14 +60,14 @@ class Image(array):
self._SubImages = sdict() # {offset: Image()} self._SubImages = sdict() # {offset: Image()}
array.__init__(self, 'B') array.__init__(self)
def __repr__(self): def __repr__(self):
return self._ID_ return self._ID_
def __len__(self): def __len__(self):
Len = array.__len__(self) Len = array.__len__(self)
for Offset in self._SubImages: for Offset in self._SubImages.keys():
Len += len(self._SubImages[Offset]) Len += len(self._SubImages[Offset])
return Len return Len
@ -154,19 +156,11 @@ class CompressedImage(Image):
def _GetSections(self): def _GetSections(self):
try: try:
from . import EfiCompressor TmpData = DeCompress('Efi', self[self._HEADER_SIZE_:])
TmpData = EfiCompressor.FrameworkDecompress(
self[self._HEADER_SIZE_:],
len(self) - self._HEADER_SIZE_
)
DecData = array('B') DecData = array('B')
DecData.fromstring(TmpData) DecData.fromstring(TmpData)
except: except:
from . import EfiCompressor TmpData = DeCompress('Framework', self[self._HEADER_SIZE_:])
TmpData = EfiCompressor.UefiDecompress(
self[self._HEADER_SIZE_:],
len(self) - self._HEADER_SIZE_
)
DecData = array('B') DecData = array('B')
DecData.fromstring(TmpData) DecData.fromstring(TmpData)
@ -297,7 +291,7 @@ class Depex(Image):
Expression = property(_GetExpression) Expression = property(_GetExpression)
## FirmwareVolume() class # # FirmwareVolume() class
# #
# A class for Firmware Volume # A class for Firmware Volume
# #
@ -308,12 +302,12 @@ class FirmwareVolume(Image):
_FfsGuid = "8C8CE578-8A3D-4F1C-9935-896185C32DD3" _FfsGuid = "8C8CE578-8A3D-4F1C-9935-896185C32DD3"
_GUID_ = struct.Struct("16x 1I2H8B") _GUID_ = struct.Struct("16x 1I2H8B")
_LENGTH_ = struct.Struct("16x 16x 1Q") _LENGTH_ = struct.Struct("16x 16x 1Q")
_SIG_ = struct.Struct("16x 16x 8x 1I") _SIG_ = struct.Struct("16x 16x 8x 1I")
_ATTR_ = struct.Struct("16x 16x 8x 4x 1I") _ATTR_ = struct.Struct("16x 16x 8x 4x 1I")
_HLEN_ = struct.Struct("16x 16x 8x 4x 4x 1H") _HLEN_ = struct.Struct("16x 16x 8x 4x 4x 1H")
_CHECKSUM_ = struct.Struct("16x 16x 8x 4x 4x 2x 1H") _CHECKSUM_ = struct.Struct("16x 16x 8x 4x 4x 2x 1H")
def __init__(self, Name=''): def __init__(self, Name=''):
Image.__init__(self) Image.__init__(self)
@ -387,7 +381,7 @@ class FirmwareVolume(Image):
DepexString = DepexList[0].strip() DepexString = DepexList[0].strip()
return (CouldBeLoaded, DepexString, FileDepex) return (CouldBeLoaded, DepexString, FileDepex)
def Dispatch(self, Db = None): def Dispatch(self, Db=None):
if Db is None: if Db is None:
return False return False
self.UnDispatchedFfsDict = copy.copy(self.FfsDict) self.UnDispatchedFfsDict = copy.copy(self.FfsDict)
@ -397,7 +391,7 @@ class FirmwareVolume(Image):
FfsDxeCoreGuid = None FfsDxeCoreGuid = None
FfsPeiPrioriGuid = None FfsPeiPrioriGuid = None
FfsDxePrioriGuid = None FfsDxePrioriGuid = None
for FfsID in self.UnDispatchedFfsDict: for FfsID in self.UnDispatchedFfsDict.keys():
Ffs = self.UnDispatchedFfsDict[FfsID] Ffs = self.UnDispatchedFfsDict[FfsID]
if Ffs.Type == 0x03: if Ffs.Type == 0x03:
FfsSecCoreGuid = FfsID FfsSecCoreGuid = FfsID
@ -439,6 +433,7 @@ class FirmwareVolume(Image):
if GuidString in self.UnDispatchedFfsDict: if GuidString in self.UnDispatchedFfsDict:
self.OrderedFfsDict[GuidString] = self.UnDispatchedFfsDict.pop(GuidString) self.OrderedFfsDict[GuidString] = self.UnDispatchedFfsDict.pop(GuidString)
self.LoadPpi(Db, GuidString) self.LoadPpi(Db, GuidString)
self.DisPatchPei(Db) self.DisPatchPei(Db)
# Parse DXE then # Parse DXE then
@ -460,6 +455,7 @@ class FirmwareVolume(Image):
if GuidString in self.UnDispatchedFfsDict: if GuidString in self.UnDispatchedFfsDict:
self.OrderedFfsDict[GuidString] = self.UnDispatchedFfsDict.pop(GuidString) self.OrderedFfsDict[GuidString] = self.UnDispatchedFfsDict.pop(GuidString)
self.LoadProtocol(Db, GuidString) self.LoadProtocol(Db, GuidString)
self.DisPatchDxe(Db) self.DisPatchDxe(Db)
def LoadProtocol(self, Db, ModuleGuid): def LoadProtocol(self, Db, ModuleGuid):
@ -501,7 +497,7 @@ class FirmwareVolume(Image):
def DisPatchDxe(self, Db): def DisPatchDxe(self, Db):
IsInstalled = False IsInstalled = False
ScheduleList = sdict() ScheduleList = sdict()
for FfsID in self.UnDispatchedFfsDict: for FfsID in self.UnDispatchedFfsDict.keys():
CouldBeLoaded = False CouldBeLoaded = False
DepexString = '' DepexString = ''
FileDepex = None FileDepex = None
@ -548,7 +544,7 @@ class FirmwareVolume(Image):
else: else:
self.UnDispatchedFfsDict[FfsID].Depex = DepexString self.UnDispatchedFfsDict[FfsID].Depex = DepexString
for FfsID in ScheduleList: for FfsID in ScheduleList.keys():
NewFfs = ScheduleList.pop(FfsID) NewFfs = ScheduleList.pop(FfsID)
FfsName = 'UnKnown' FfsName = 'UnKnown'
self.OrderedFfsDict[FfsID] = NewFfs self.OrderedFfsDict[FfsID] = NewFfs
@ -560,12 +556,13 @@ class FirmwareVolume(Image):
RecordSet = Db.TblReport.Exec(SqlCommand) RecordSet = Db.TblReport.Exec(SqlCommand)
if RecordSet != []: if RecordSet != []:
FfsName = RecordSet[0][0] FfsName = RecordSet[0][0]
if IsInstalled: if IsInstalled:
self.DisPatchDxe(Db) self.DisPatchDxe(Db)
def DisPatchPei(self, Db): def DisPatchPei(self, Db):
IsInstalled = False IsInstalled = False
for FfsID in self.UnDispatchedFfsDict: for FfsID in self.UnDispatchedFfsDict.keys():
CouldBeLoaded = True CouldBeLoaded = True
DepexString = '' DepexString = ''
FileDepex = None FileDepex = None
@ -576,7 +573,6 @@ class FirmwareVolume(Image):
if Section.Type == 0x1B: if Section.Type == 0x1B:
CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(Section._SubImages[4], 'Ppi') CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(Section._SubImages[4], 'Ppi')
break break
if Section.Type == 0x01: if Section.Type == 0x01:
CompressSections = Section._SubImages[4] CompressSections = Section._SubImages[4]
for CompressSection in CompressSections.Sections: for CompressSection in CompressSections.Sections:
@ -603,11 +599,12 @@ class FirmwareVolume(Image):
if IsInstalled: if IsInstalled:
self.DisPatchPei(Db) self.DisPatchPei(Db)
def __str__(self): def __str__(self):
global gIndention global gIndention
gIndention += 4 gIndention += 4
FvInfo = '\n' + ' ' * gIndention FvInfo = '\n' + ' ' * gIndention
FvInfo += "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self.Name, self.FileSystemGuid, self.Size, self.Checksum) FvInfo += "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self.Name, self.FileSystemGuid, self.Size, self.Checksum)
FfsInfo = "\n".join([str(self.FfsDict[FfsId]) for FfsId in self.FfsDict]) FfsInfo = "\n".join([str(self.FfsDict[FfsId]) for FfsId in self.FfsDict])
gIndention -= 4 gIndention -= 4
return FvInfo + FfsInfo return FvInfo + FfsInfo
@ -615,7 +612,7 @@ class FirmwareVolume(Image):
def _Unpack(self): def _Unpack(self):
Size = self._LENGTH_.unpack_from(self._BUF_, self._OFF_)[0] Size = self._LENGTH_.unpack_from(self._BUF_, self._OFF_)[0]
self.empty() self.empty()
self.extend(self._BUF_[self._OFF_:self._OFF_+Size]) self.extend(self._BUF_[self._OFF_:self._OFF_ + Size])
# traverse the FFS # traverse the FFS
EndOfFv = Size EndOfFv = Size
@ -743,10 +740,9 @@ class GuidDefinedImage(Image):
SectionList.append(Sec) SectionList.append(Sec)
elif Guid == self.TIANO_COMPRESS_GUID: elif Guid == self.TIANO_COMPRESS_GUID:
try: try:
from . import EfiCompressor
# skip the header # skip the header
Offset = self.DataOffset - 4 Offset = self.DataOffset - 4
TmpData = EfiCompressor.FrameworkDecompress(self[Offset:], len(self)-Offset) TmpData = DeCompress('Framework', self[self.Offset:])
DecData = array('B') DecData = array('B')
DecData.fromstring(TmpData) DecData.fromstring(TmpData)
Offset = 0 Offset = 0
@ -764,10 +760,10 @@ class GuidDefinedImage(Image):
pass pass
elif Guid == self.LZMA_COMPRESS_GUID: elif Guid == self.LZMA_COMPRESS_GUID:
try: try:
from . import LzmaCompressor
# skip the header # skip the header
Offset = self.DataOffset - 4 Offset = self.DataOffset - 4
TmpData = LzmaCompressor.LzmaDecompress(self[Offset:], len(self)-Offset)
TmpData = DeCompress('Lzma', self[self.Offset:])
DecData = array('B') DecData = array('B')
DecData.fromstring(TmpData) DecData.fromstring(TmpData)
Offset = 0 Offset = 0
@ -848,7 +844,7 @@ class Section(Image):
SectionInfo += "[SECTION:%s] offset=%x size=%x" % (self._TypeName[self.Type], self._OFF_, self.Size) SectionInfo += "[SECTION:%s] offset=%x size=%x" % (self._TypeName[self.Type], self._OFF_, self.Size)
else: else:
SectionInfo += "[SECTION:%x<unknown>] offset=%x size=%x " % (self.Type, self._OFF_, self.Size) SectionInfo += "[SECTION:%x<unknown>] offset=%x size=%x " % (self.Type, self._OFF_, self.Size)
for Offset in self._SubImages: for Offset in self._SubImages.keys():
SectionInfo += ", " + str(self._SubImages[Offset]) SectionInfo += ", " + str(self._SubImages[Offset])
gIndention -= 4 gIndention -= 4
return SectionInfo return SectionInfo
@ -982,7 +978,7 @@ class Ffs(Image):
FfsInfo = Indention FfsInfo = Indention
FfsInfo += "[FFS:%s] offset=%x size=%x guid=%s free_space=%x alignment=%s\n" % \ FfsInfo += "[FFS:%s] offset=%x size=%x guid=%s free_space=%x alignment=%s\n" % \
(Ffs._TypeName[self.Type], self._OFF_, self.Size, self.Guid, self.FreeSpace, self.Alignment) (Ffs._TypeName[self.Type], self._OFF_, self.Size, self.Guid, self.FreeSpace, self.Alignment)
SectionInfo = '\n'.join([str(self.Sections[Offset]) for Offset in self.Sections]) SectionInfo = '\n'.join([str(self.Sections[Offset]) for Offset in self.Sections.keys()])
gIndention -= 4 gIndention -= 4
return FfsInfo + SectionInfo + "\n" return FfsInfo + SectionInfo + "\n"
@ -1087,379 +1083,6 @@ class Ffs(Image):
Alignment = property(_GetAlignment) Alignment = property(_GetAlignment)
State = property(_GetState, _SetState) State = property(_GetState, _SetState)
## FirmwareVolume() class
#
# A class for Firmware Volume
#
class FirmwareVolume(Image):
# Read FvLength, Attributes, HeaderLength, Checksum
_HEADER_ = struct.Struct("16x 1I2H8B 1Q 4x 1I 1H 1H")
_HEADER_SIZE_ = _HEADER_.size
_FfsGuid = "8C8CE578-8A3D-4F1C-9935-896185C32DD3"
_GUID_ = struct.Struct("16x 1I2H8B")
_LENGTH_ = struct.Struct("16x 16x 1Q")
_SIG_ = struct.Struct("16x 16x 8x 1I")
_ATTR_ = struct.Struct("16x 16x 8x 4x 1I")
_HLEN_ = struct.Struct("16x 16x 8x 4x 4x 1H")
_CHECKSUM_ = struct.Struct("16x 16x 8x 4x 4x 2x 1H")
def __init__(self, Name=''):
Image.__init__(self)
self.Name = Name
self.FfsDict = sdict()
self.OrderedFfsDict = sdict()
self.UnDispatchedFfsDict = sdict()
self.ProtocolList = sdict()
def CheckArchProtocol(self):
for Item in EotGlobalData.gArchProtocolGuids:
if Item.lower() not in EotGlobalData.gProtocolList:
return False
return True
def ParseDepex(self, Depex, Type):
List = None
if Type == 'Ppi':
List = EotGlobalData.gPpiList
if Type == 'Protocol':
List = EotGlobalData.gProtocolList
DepexStack = []
DepexList = []
DepexString = ''
FileDepex = None
CouldBeLoaded = True
for Index in range(0, len(Depex.Expression)):
Item = Depex.Expression[Index]
if Item == 0x00:
Index = Index + 1
Guid = gGuidStringFormat % Depex.Expression[Index]
if Guid in self.OrderedFfsDict and Depex.Expression[Index + 1] == 0x08:
return (True, 'BEFORE %s' % Guid, [Guid, 'BEFORE'])
elif Item == 0x01:
Index = Index + 1
Guid = gGuidStringFormat % Depex.Expression[Index]
if Guid in self.OrderedFfsDict and Depex.Expression[Index + 1] == 0x08:
return (True, 'AFTER %s' % Guid, [Guid, 'AFTER'])
elif Item == 0x02:
Index = Index + 1
Guid = gGuidStringFormat % Depex.Expression[Index]
if Guid.lower() in List:
DepexStack.append(True)
DepexList.append(Guid)
else:
DepexStack.append(False)
DepexList.append(Guid)
continue
elif Item == 0x03 or Item == 0x04:
DepexStack.append(eval(str(DepexStack.pop()) + ' ' + Depex._OPCODE_STRING_[Item].lower() + ' ' + str(DepexStack.pop())))
DepexList.append(str(DepexList.pop()) + ' ' + Depex._OPCODE_STRING_[Item].upper() + ' ' + str(DepexList.pop()))
elif Item == 0x05:
DepexStack.append(eval(Depex._OPCODE_STRING_[Item].lower() + ' ' + str(DepexStack.pop())))
DepexList.append(Depex._OPCODE_STRING_[Item].lower() + ' ' + str(DepexList.pop()))
elif Item == 0x06:
DepexStack.append(True)
DepexList.append('TRUE')
DepexString = DepexString + 'TRUE' + ' '
elif Item == 0x07:
DepexStack.append(False)
DepexList.append('False')
DepexString = DepexString + 'FALSE' + ' '
elif Item == 0x08:
if Index != len(Depex.Expression) - 1:
CouldBeLoaded = False
else:
CouldBeLoaded = DepexStack.pop()
else:
CouldBeLoaded = False
if DepexList != []:
DepexString = DepexList[0].strip()
return (CouldBeLoaded, DepexString, FileDepex)
def Dispatch(self, Db = None):
if Db is None:
return False
self.UnDispatchedFfsDict = copy.copy(self.FfsDict)
# Find PeiCore, DexCore, PeiPriori, DxePriori first
FfsSecCoreGuid = None
FfsPeiCoreGuid = None
FfsDxeCoreGuid = None
FfsPeiPrioriGuid = None
FfsDxePrioriGuid = None
for FfsID in self.UnDispatchedFfsDict:
Ffs = self.UnDispatchedFfsDict[FfsID]
if Ffs.Type == 0x03:
FfsSecCoreGuid = FfsID
continue
if Ffs.Type == 0x04:
FfsPeiCoreGuid = FfsID
continue
if Ffs.Type == 0x05:
FfsDxeCoreGuid = FfsID
continue
if Ffs.Guid.lower() == gPeiAprioriFileNameGuid:
FfsPeiPrioriGuid = FfsID
continue
if Ffs.Guid.lower() == gAprioriGuid:
FfsDxePrioriGuid = FfsID
continue
# Parse SEC_CORE first
if FfsSecCoreGuid is not None:
self.OrderedFfsDict[FfsSecCoreGuid] = self.UnDispatchedFfsDict.pop(FfsSecCoreGuid)
self.LoadPpi(Db, FfsSecCoreGuid)
# Parse PEI first
if FfsPeiCoreGuid is not None:
self.OrderedFfsDict[FfsPeiCoreGuid] = self.UnDispatchedFfsDict.pop(FfsPeiCoreGuid)
self.LoadPpi(Db, FfsPeiCoreGuid)
if FfsPeiPrioriGuid is not None:
# Load PEIM described in priori file
FfsPeiPriori = self.UnDispatchedFfsDict.pop(FfsPeiPrioriGuid)
if len(FfsPeiPriori.Sections) == 1:
Section = FfsPeiPriori.Sections.popitem()[1]
if Section.Type == 0x19:
GuidStruct = struct.Struct('1I2H8B')
Start = 4
while len(Section) > Start:
Guid = GuidStruct.unpack_from(Section[Start : Start + 16])
GuidString = gGuidStringFormat % Guid
Start = Start + 16
if GuidString in self.UnDispatchedFfsDict:
self.OrderedFfsDict[GuidString] = self.UnDispatchedFfsDict.pop(GuidString)
self.LoadPpi(Db, GuidString)
self.DisPatchPei(Db)
# Parse DXE then
if FfsDxeCoreGuid is not None:
self.OrderedFfsDict[FfsDxeCoreGuid] = self.UnDispatchedFfsDict.pop(FfsDxeCoreGuid)
self.LoadProtocol(Db, FfsDxeCoreGuid)
if FfsDxePrioriGuid is not None:
# Load PEIM described in priori file
FfsDxePriori = self.UnDispatchedFfsDict.pop(FfsDxePrioriGuid)
if len(FfsDxePriori.Sections) == 1:
Section = FfsDxePriori.Sections.popitem()[1]
if Section.Type == 0x19:
GuidStruct = struct.Struct('1I2H8B')
Start = 4
while len(Section) > Start:
Guid = GuidStruct.unpack_from(Section[Start : Start + 16])
GuidString = gGuidStringFormat % Guid
Start = Start + 16
if GuidString in self.UnDispatchedFfsDict:
self.OrderedFfsDict[GuidString] = self.UnDispatchedFfsDict.pop(GuidString)
self.LoadProtocol(Db, GuidString)
self.DisPatchDxe(Db)
def LoadProtocol(self, Db, ModuleGuid):
SqlCommand = """select GuidValue from Report
where SourceFileFullPath in
(select Value1 from Inf where BelongsToFile =
(select BelongsToFile from Inf
where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
and Model = %s)
and ItemType = 'Protocol' and ItemMode = 'Produced'""" \
% (ModuleGuid, 5001, 3007)
RecordSet = Db.TblReport.Exec(SqlCommand)
for Record in RecordSet:
SqlCommand = """select Value2 from Inf where BelongsToFile =
(select DISTINCT BelongsToFile from Inf
where Value1 =
(select SourceFileFullPath from Report
where GuidValue like '%s' and ItemMode = 'Callback'))
and Value1 = 'FILE_GUID'""" % Record[0]
CallBackSet = Db.TblReport.Exec(SqlCommand)
if CallBackSet != []:
EotGlobalData.gProtocolList[Record[0].lower()] = ModuleGuid
else:
EotGlobalData.gProtocolList[Record[0].lower()] = ModuleGuid
def LoadPpi(self, Db, ModuleGuid):
SqlCommand = """select GuidValue from Report
where SourceFileFullPath in
(select Value1 from Inf where BelongsToFile =
(select BelongsToFile from Inf
where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
and Model = %s)
and ItemType = 'Ppi' and ItemMode = 'Produced'""" \
% (ModuleGuid, 5001, 3007)
RecordSet = Db.TblReport.Exec(SqlCommand)
for Record in RecordSet:
EotGlobalData.gPpiList[Record[0].lower()] = ModuleGuid
def DisPatchDxe(self, Db):
IsInstalled = False
ScheduleList = sdict()
for FfsID in self.UnDispatchedFfsDict:
CouldBeLoaded = False
DepexString = ''
FileDepex = None
Ffs = self.UnDispatchedFfsDict[FfsID]
if Ffs.Type == 0x07:
# Get Depex
IsFoundDepex = False
for Section in Ffs.Sections.values():
# Find Depex
if Section.Type == 0x13:
IsFoundDepex = True
CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(Section._SubImages[4], 'Protocol')
break
if Section.Type == 0x01:
CompressSections = Section._SubImages[4]
for CompressSection in CompressSections.Sections:
if CompressSection.Type == 0x13:
IsFoundDepex = True
CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(CompressSection._SubImages[4], 'Protocol')
break
if CompressSection.Type == 0x02:
NewSections = CompressSection._SubImages[4]
for NewSection in NewSections.Sections:
if NewSection.Type == 0x13:
IsFoundDepex = True
CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(NewSection._SubImages[4], 'Protocol')
break
# Not find Depex
if not IsFoundDepex:
CouldBeLoaded = self.CheckArchProtocol()
DepexString = ''
FileDepex = None
# Append New Ffs
if CouldBeLoaded:
IsInstalled = True
NewFfs = self.UnDispatchedFfsDict.pop(FfsID)
NewFfs.Depex = DepexString
if FileDepex is not None:
ScheduleList.insert(FileDepex[1], FfsID, NewFfs, FileDepex[0])
else:
ScheduleList[FfsID] = NewFfs
else:
self.UnDispatchedFfsDict[FfsID].Depex = DepexString
for FfsID in ScheduleList:
NewFfs = ScheduleList.pop(FfsID)
FfsName = 'UnKnown'
self.OrderedFfsDict[FfsID] = NewFfs
self.LoadProtocol(Db, FfsID)
SqlCommand = """select Value2 from Inf
where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
and Model = %s and Value1='BASE_NAME'""" % (FfsID, 5001, 5001)
RecordSet = Db.TblReport.Exec(SqlCommand)
if RecordSet != []:
FfsName = RecordSet[0][0]
if IsInstalled:
self.DisPatchDxe(Db)
def DisPatchPei(self, Db):
IsInstalled = False
for FfsID in self.UnDispatchedFfsDict:
CouldBeLoaded = True
DepexString = ''
FileDepex = None
Ffs = self.UnDispatchedFfsDict[FfsID]
if Ffs.Type == 0x06 or Ffs.Type == 0x08:
# Get Depex
for Section in Ffs.Sections.values():
if Section.Type == 0x1B:
CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(Section._SubImages[4], 'Ppi')
break
if Section.Type == 0x01:
CompressSections = Section._SubImages[4]
for CompressSection in CompressSections.Sections:
if CompressSection.Type == 0x1B:
CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(CompressSection._SubImages[4], 'Ppi')
break
if CompressSection.Type == 0x02:
NewSections = CompressSection._SubImages[4]
for NewSection in NewSections.Sections:
if NewSection.Type == 0x1B:
CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(NewSection._SubImages[4], 'Ppi')
break
# Append New Ffs
if CouldBeLoaded:
IsInstalled = True
NewFfs = self.UnDispatchedFfsDict.pop(FfsID)
NewFfs.Depex = DepexString
self.OrderedFfsDict[FfsID] = NewFfs
self.LoadPpi(Db, FfsID)
else:
self.UnDispatchedFfsDict[FfsID].Depex = DepexString
if IsInstalled:
self.DisPatchPei(Db)
def __str__(self):
global gIndention
gIndention += 4
FvInfo = '\n' + ' ' * gIndention
FvInfo += "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self.Name, self.FileSystemGuid, self.Size, self.Checksum)
FfsInfo = "\n".join([str(self.FfsDict[FfsId]) for FfsId in self.FfsDict])
gIndention -= 4
return FvInfo + FfsInfo
def _Unpack(self):
Size = self._LENGTH_.unpack_from(self._BUF_, self._OFF_)[0]
self.empty()
self.extend(self._BUF_[self._OFF_:self._OFF_+Size])
# traverse the FFS
EndOfFv = Size
FfsStartAddress = self.HeaderSize
LastFfsObj = None
while FfsStartAddress < EndOfFv:
FfsObj = Ffs()
FfsObj.frombuffer(self, FfsStartAddress)
FfsId = repr(FfsObj)
if ((self.Attributes & 0x00000800) != 0 and len(FfsObj) == 0xFFFFFF) \
or ((self.Attributes & 0x00000800) == 0 and len(FfsObj) == 0):
if LastFfsObj is not None:
LastFfsObj.FreeSpace = EndOfFv - LastFfsObj._OFF_ - len(LastFfsObj)
else:
if FfsId in self.FfsDict:
EdkLogger.error("FV", 0, "Duplicate GUID in FFS",
ExtraData="\t%s @ %s\n\t%s @ %s" \
% (FfsObj.Guid, FfsObj.Offset,
self.FfsDict[FfsId].Guid, self.FfsDict[FfsId].Offset))
self.FfsDict[FfsId] = FfsObj
if LastFfsObj is not None:
LastFfsObj.FreeSpace = FfsStartAddress - LastFfsObj._OFF_ - len(LastFfsObj)
FfsStartAddress += len(FfsObj)
#
# align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))
# The next FFS must be at the latest next 8-byte aligned address
#
FfsStartAddress = (FfsStartAddress + 7) & (~7)
LastFfsObj = FfsObj
def _GetAttributes(self):
return self.GetField(self._ATTR_, 0)[0]
def _GetSize(self):
return self.GetField(self._LENGTH_, 0)[0]
def _GetChecksum(self):
return self.GetField(self._CHECKSUM_, 0)[0]
def _GetHeaderLength(self):
return self.GetField(self._HLEN_, 0)[0]
def _GetFileSystemGuid(self):
return gGuidStringFormat % self.GetField(self._GUID_, 0)
Attributes = property(_GetAttributes)
Size = property(_GetSize)
Checksum = property(_GetChecksum)
HeaderSize = property(_GetHeaderLength)
FileSystemGuid = property(_GetFileSystemGuid)
## MultipleFv() class ## MultipleFv() class
# #
@ -1470,8 +1093,10 @@ class MultipleFv(FirmwareVolume):
FirmwareVolume.__init__(self) FirmwareVolume.__init__(self)
self.BasicInfo = [] self.BasicInfo = []
for FvPath in FvList: for FvPath in FvList:
Fd = None
FvName = os.path.splitext(os.path.split(FvPath)[1])[0] FvName = os.path.splitext(os.path.split(FvPath)[1])[0]
Fd = open(FvPath, 'rb') if FvPath.strip():
Fd = open(FvPath, 'rb')
Buf = array('B') Buf = array('B')
try: try:
Buf.fromfile(Fd, os.path.getsize(FvPath)) Buf.fromfile(Fd, os.path.getsize(FvPath))
@ -1632,8 +1257,9 @@ class Eot(object):
Path = os.path.join(EotGlobalData.gWORKSPACE, GuidList) Path = os.path.join(EotGlobalData.gWORKSPACE, GuidList)
if os.path.isfile(Path): if os.path.isfile(Path):
for Line in open(Path): for Line in open(Path):
(GuidName, GuidValue) = Line.split() if Line.strip():
EotGlobalData.gGuidDict[GuidName] = GuidValue (GuidName, GuidValue) = Line.split()
EotGlobalData.gGuidDict[GuidName] = GuidValue
## ConvertLogFile() method ## ConvertLogFile() method
# #
@ -1694,7 +1320,7 @@ class Eot(object):
mCurrentSourceFileList = [] mCurrentSourceFileList = []
if SourceFileList: if SourceFileList:
sfl = open(SourceFileList, 'rb') sfl = open(SourceFileList, 'r')
for line in sfl: for line in sfl:
line = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line.strip())) line = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line.strip()))
if line[-2:].upper() == '.C' or line[-2:].upper() == '.H': if line[-2:].upper() == '.C' or line[-2:].upper() == '.H':
@ -1970,6 +1596,8 @@ class Eot(object):
def BuildMetaDataFileDatabase(self, Inf_Files): def BuildMetaDataFileDatabase(self, Inf_Files):
EdkLogger.quiet("Building database for meta data files ...") EdkLogger.quiet("Building database for meta data files ...")
for InfFile in Inf_Files: for InfFile in Inf_Files:
if not InfFile:
continue
EdkLogger.quiet("Parsing %s ..." % str(InfFile)) EdkLogger.quiet("Parsing %s ..." % str(InfFile))
EdkInfParser(InfFile, EotGlobalData.gDb, Inf_Files[InfFile], '') EdkInfParser(InfFile, EotGlobalData.gDb, Inf_Files[InfFile], '')
@ -2083,7 +1711,10 @@ if __name__ == '__main__':
EdkLogger.quiet(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[00:00]" + "\n") EdkLogger.quiet(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[00:00]" + "\n")
StartTime = time.clock() StartTime = time.clock()
Eot = Eot() Eot = Eot(CommandLineOption=False,
SourceFileList=r'C:\TestEot\Source.txt',
GuidList=r'C:\TestEot\Guid.txt',
FvFileList=r'C:\TestEot\FVRECOVERY.Fv')
FinishTime = time.clock() FinishTime = time.clock()
BuildDuration = time.strftime("%M:%S", time.gmtime(int(round(FinishTime - StartTime)))) BuildDuration = time.strftime("%M:%S", time.gmtime(int(round(FinishTime - StartTime))))

View File

@ -1,7 +1,7 @@
## @file ## @file
# This file is used to parse INF file of EDK project # This file is used to parse INF file of EDK project
# #
# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2008 - 2018, 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
# which accompanies this distribution. The full text of the license may be found at # which accompanies this distribution. The full text of the license may be found at
@ -22,8 +22,9 @@ from Common.DataType import *
from CommonDataClass.DataClass import * from CommonDataClass.DataClass import *
from Common.Identification import * from Common.Identification import *
from Common.StringUtils import * from Common.StringUtils import *
from .Parser import * from Eot.Parser import *
from . import Database from Eot import Database
from Eot import EotGlobalData
## EdkInfParser() class ## EdkInfParser() class
# #
@ -153,21 +154,4 @@ class EdkInfParser(object):
self.ParserSource(CurrentSection, SectionItemList, ArchList, ThirdList) self.ParserSource(CurrentSection, SectionItemList, ArchList, ThirdList)
#End of For #End of For
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == '__main__':
EdkLogger.Initialize()
EdkLogger.SetLevel(EdkLogger.QUIET)
Db = Database.Database('Inf.db')
Db.InitDatabase()
P = EdkInfParser(os.path.normpath("C:\Framework\Edk\Sample\Platform\Nt32\Dxe\PlatformBds\PlatformBds.inf"), Db, '', '')
for Inf in P.Sources:
print(Inf)
for Item in P.Macros:
print(Item, P.Macros[Item])
Db.Close()

View File

@ -2,7 +2,7 @@
# This file is used to define common parsing related functions used in parsing # This file is used to define common parsing related functions used in parsing
# Inf/Dsc/Makefile process # Inf/Dsc/Makefile process
# #
# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2008 - 2018, 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
# which accompanies this distribution. The full text of the license may be found at # which accompanies this distribution. The full text of the license may be found at
@ -25,6 +25,32 @@ from . import EotGlobalData
from Common.StringUtils import GetSplitList from Common.StringUtils import GetSplitList
from Common.LongFilePathSupport import OpenLongFilePath as open from Common.LongFilePathSupport import OpenLongFilePath as open
import subprocess
## DeCompress
#
# Call external decompress tool to decompress the fv section
#
def DeCompress(Method, Input):
# Write the input to a temp file
open('_Temp.bin', 'wb').write(Input)
cmd = ''
if Method == 'Lzma':
cmd = r'LzmaCompress -o _New.bin -d _Temp.bin'
if Method == 'Efi':
cmd = r'TianoCompress -d --uefi -o _New.bin _Temp.bin'
if Method == 'Framework':
cmd = r'TianoCompress -d -o _New.bin _Temp.bin'
# Call tool to create the decompressed output file
Process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
Process.communicate()[0]
# Return the beffer of New.bin
if os.path.exists('_New.bin'):
return open('_New.bin', 'rb').read()
## PreProcess() method ## PreProcess() method
# #
# Pre process a file # Pre process a file

View File

@ -77,7 +77,7 @@ class Report(object):
def GenerateUnDispatchedList(self): def GenerateUnDispatchedList(self):
FvObj = self.FvObj FvObj = self.FvObj
EotGlobalData.gOP_UN_DISPATCHED.write('%s\n' % FvObj.Name) EotGlobalData.gOP_UN_DISPATCHED.write('%s\n' % FvObj.Name)
for Item in FvObj.UnDispatchedFfsDict: for Item in FvObj.UnDispatchedFfsDict.keys():
EotGlobalData.gOP_UN_DISPATCHED.write('%s\n' % FvObj.UnDispatchedFfsDict[Item]) EotGlobalData.gOP_UN_DISPATCHED.write('%s\n' % FvObj.UnDispatchedFfsDict[Item])
## GenerateFv() method ## GenerateFv() method
@ -112,7 +112,7 @@ class Report(object):
self.WriteLn(Content) self.WriteLn(Content)
EotGlobalData.gOP_DISPATCH_ORDER.write('Dispatched:\n') EotGlobalData.gOP_DISPATCH_ORDER.write('Dispatched:\n')
for FfsId in FvObj.OrderedFfsDict: for FfsId in FvObj.OrderedFfsDict.keys():
self.GenerateFfs(FvObj.OrderedFfsDict[FfsId]) self.GenerateFfs(FvObj.OrderedFfsDict[FfsId])
Content = """ </table></td> Content = """ </table></td>
</tr>""" </tr>"""
@ -125,7 +125,7 @@ class Report(object):
self.WriteLn(Content) self.WriteLn(Content)
EotGlobalData.gOP_DISPATCH_ORDER.write('\nUnDispatched:\n') EotGlobalData.gOP_DISPATCH_ORDER.write('\nUnDispatched:\n')
for FfsId in FvObj.UnDispatchedFfsDict: for FfsId in FvObj.UnDispatchedFfsDict.keys():
self.GenerateFfs(FvObj.UnDispatchedFfsDict[FfsId]) self.GenerateFfs(FvObj.UnDispatchedFfsDict[FfsId])
Content = """ </table></td> Content = """ </table></td>
</tr>""" </tr>"""

View File

@ -1626,7 +1626,7 @@ class PredictionReport(object):
TempFile.close() TempFile.close()
try: try:
from Eot.Eot import Eot from Eot.EotMain import Eot
# #
# Invoke EOT tool and echo its runtime performance # Invoke EOT tool and echo its runtime performance