From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.65; helo=mga03.intel.com; envelope-from=yonghong.zhu@intel.com; receiver=edk2-devel@lists.01.org Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 31F8C2033D1B6 for ; Sun, 27 May 2018 18:17:00 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga003.fm.intel.com ([10.253.24.29]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 May 2018 18:17:00 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,450,1520924400"; d="scan'208";a="52754270" Received: from fmsmsx104.amr.corp.intel.com ([10.18.124.202]) by FMSMGA003.fm.intel.com with ESMTP; 27 May 2018 18:17:00 -0700 Received: from fmsmsx155.amr.corp.intel.com (10.18.116.71) by fmsmsx104.amr.corp.intel.com (10.18.124.202) with Microsoft SMTP Server (TLS) id 14.3.319.2; Sun, 27 May 2018 18:17:00 -0700 Received: from shsmsx104.ccr.corp.intel.com (10.239.4.70) by FMSMSX155.amr.corp.intel.com (10.18.116.71) with Microsoft SMTP Server (TLS) id 14.3.319.2; Sun, 27 May 2018 18:16:59 -0700 Received: from shsmsx103.ccr.corp.intel.com ([169.254.4.51]) by SHSMSX104.ccr.corp.intel.com ([169.254.5.87]) with mapi id 14.03.0319.002; Mon, 28 May 2018 09:16:56 +0800 From: "Zhu, Yonghong" To: "Carsey, Jaben" , "edk2-devel@lists.01.org" CC: "Gao, Liming" , "Zhu, Yonghong" Thread-Topic: [PATCH v1 1/1] BaseTools: Add missing content to EOT tool. Thread-Index: AQHT82oE3l87kO2Gu0m4LXFlK0PFXKREXEQA Date: Mon, 28 May 2018 01:16:55 +0000 Message-ID: References: <20e0f96abb6acc6e5794ceb1b4fe382c78d59c4d.1527171329.git.jaben.carsey@intel.com> In-Reply-To: <20e0f96abb6acc6e5794ceb1b4fe382c78d59c4d.1527171329.git.jaben.carsey@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiYTYwM2Q5YmEtOWQ2YS00YjlmLWE4MzEtNDZjZWY4NTM3YWVlIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiWHg5N042V0VcL0J1MjVwbXhOa1hXYWlCR2lOXC9ZT2xkR3kwQ3N0NUtcL0JheUp5NUdkbWd0c0tWZWVrRVVTV1dXRiJ9 x-ctpclassification: CTP_NT dlp-product: dlpe-windows dlp-version: 11.0.200.100 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH v1 1/1] BaseTools: Add missing content to EOT tool. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 28 May 2018 01:17:01 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Yonghong Zhu =20 Best Regards, Zhu Yonghong -----Original Message----- From: Carsey, Jaben=20 Sent: Thursday, May 24, 2018 10:18 PM To: edk2-devel@lists.01.org Cc: Gao, Liming ; Zhu, Yonghong Subject: [PATCH v1 1/1] BaseTools: Add missing content to EOT tool. Cc: Liming Gao Cc: Yonghong Zhu Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jaben Carsey --- BaseTools/Source/Python/Eot/Eot.py | 1444 +++++++++++++++++++- BaseTools/Source/Python/Eot/EotGlobalData.py | 17 + 2 files changed, 1460 insertions(+), 1 deletion(-) diff --git a/BaseTools/Source/Python/Eot/Eot.py b/BaseTools/Source/Python/E= ot/Eot.py index fcde8fd3e22f..786868d55d99 100644 --- a/BaseTools/Source/Python/Eot/Eot.py +++ b/BaseTools/Source/Python/Eot/Eot.py @@ -20,7 +20,7 @@ import EotGlobalData from optparse import OptionParser from Common.String import NormPath from Common import BuildToolError -from Common.Misc import GuidStructureStringToGuidString +from Common.Misc import GuidStructureStringToGuidString, sdict from InfParserLite import * import c import Database @@ -29,6 +29,1446 @@ from Report import Report from Common.BuildVersion import gBUILD_VERSION from Parser import ConvertGuid from Common.LongFilePathSupport import OpenLongFilePath as open +import struct +import uuid +import copy +import codecs + +gGuidStringFormat =3D "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X" +gPeiAprioriFileNameGuid =3D '1b45cc0a-156a-428a-af62-49864da0e6e6' +gAprioriGuid =3D 'fc510ee7-ffdc-11d4-bd41-0080c73c8881' +gIndention =3D -4 + +class Image(array): + _HEADER_ =3D struct.Struct("") + _HEADER_SIZE_ =3D _HEADER_.size + + def __new__(cls, *args, **kwargs): + return array.__new__(cls, 'B') + + def __init__(self, ID=3DNone): + if ID is None: + self._ID_ =3D str(uuid.uuid1()).upper() + else: + self._ID_ =3D ID + self._BUF_ =3D None + self._LEN_ =3D None + self._OFF_ =3D None + + self._SubImages =3D sdict() # {offset: Image()} + + array.__init__(self, 'B') + + def __repr__(self): + return self._ID_ + + def __len__(self): + Len =3D array.__len__(self) + for Offset in self._SubImages: + Len +=3D len(self._SubImages[Offset]) + return Len + + def _Unpack(self): + self.extend(self._BUF_[self._OFF_ : self._OFF_ + self._LEN_]) + return len(self) + + def _Pack(self, PadByte=3D0xFF): + raise NotImplementedError + + def frombuffer(self, Buffer, Offset=3D0, Size=3DNone): + self._BUF_ =3D Buffer + self._OFF_ =3D Offset + # we may need the Size information in advance if it's given + self._LEN_ =3D Size + self._LEN_ =3D self._Unpack() + + def empty(self): + del self[0:] + + def GetField(self, FieldStruct, Offset=3D0): + return FieldStruct.unpack_from(self, Offset) + + def SetField(self, FieldStruct, Offset, *args): + # check if there's enough space + Size =3D FieldStruct.size + if Size > len(self): + self.extend([0] * (Size - len(self))) + FieldStruct.pack_into(self, Offset, *args) + + def _SetData(self, Data): + if len(self) < self._HEADER_SIZE_: + self.extend([0] * (self._HEADER_SIZE_ - len(self))) + else: + del self[self._HEADER_SIZE_:] + self.extend(Data) + + def _GetData(self): + if len(self) > self._HEADER_SIZE_: + return self[self._HEADER_SIZE_:] + return None + + Data =3D property(_GetData, _SetData) + +## CompressedImage() class +# +# A class for Compressed Image +# +class CompressedImage(Image): + # UncompressedLength =3D 4-byte + # CompressionType =3D 1-byte + _HEADER_ =3D struct.Struct("1I 1B") + _HEADER_SIZE_ =3D _HEADER_.size + + _ORIG_SIZE_ =3D struct.Struct("1I") + _CMPRS_TYPE_ =3D struct.Struct("4x 1B") + + def __init__(m, CompressedData=3DNone, CompressionType=3DNone, Uncompr= essedLength=3DNone): + Image.__init__(m) + if UncompressedLength is not None: + m.UncompressedLength =3D UncompressedLength + if CompressionType is not None: + m.CompressionType =3D CompressionType + if CompressedData is not None: + m.Data =3D CompressedData + + def __str__(m): + global gIndention + S =3D "algorithm=3D%s uncompressed=3D%x" % (m.CompressionType, m.U= ncompressedLength) + for Sec in m.Sections: + S +=3D '\n' + str(Sec) + + return S + + def _SetOriginalSize(m, Size): + m.SetField(m._ORIG_SIZE_, 0, Size) + + def _GetOriginalSize(m): + return m.GetField(m._ORIG_SIZE_)[0] + + def _SetCompressionType(m, Type): + m.SetField(m._CMPRS_TYPE_, 0, Type) + + def _GetCompressionType(m): + return m.GetField(m._CMPRS_TYPE_)[0] + + def _GetSections(m): + try: + import EfiCompressor + TmpData =3D EfiCompressor.FrameworkDecompress( + m[m._HEADER_SIZE_:], + len(m) - m._HEADER_SIZE_ + ) + DecData =3D array('B') + DecData.fromstring(TmpData) + except: + import EfiCompressor + TmpData =3D EfiCompressor.UefiDecompress( + m[m._HEADER_SIZE_:], + len(m) - m._HEADER_SIZE_ + ) + DecData =3D array('B') + DecData.fromstring(TmpData) + + SectionList =3D [] + Offset =3D 0 + while Offset < len(DecData): + Sec =3D Section() + try: + Sec.frombuffer(DecData, Offset) + Offset +=3D Sec.Size + # the section is aligned to 4-byte boundary + except: + break + SectionList.append(Sec) + return SectionList + + UncompressedLength =3D property(_GetOriginalSize, _SetOriginalSize) + CompressionType =3D property(_GetCompressionType, _SetCompressionType) + Sections =3D property(_GetSections) + +## Ui() class +# +# A class for Ui +# +class Ui(Image): + _HEADER_ =3D struct.Struct("") + _HEADER_SIZE_ =3D 0 + + def __init__(m): + Image.__init__(m) + + def __str__(m): + return m.String + + def _Unpack(m): + # keep header in this Image object + m.empty() + m.extend(m._BUF_[m._OFF_ : m._OFF_ + m._LEN_]) + return len(m) + + def _GetUiString(m): + return codecs.utf_16_decode(m[0:-2].tostring())[0] + + String =3D property(_GetUiString) + +## Depex() class +# +# A class for Depex +# +class Depex(Image): + _HEADER_ =3D struct.Struct("") + _HEADER_SIZE_ =3D 0 + + _GUID_ =3D struct.Struct("1I2H8B") + _OPCODE_ =3D struct.Struct("1B") + + _OPCODE_STRING_ =3D { + 0x00 : "BEFORE", + 0x01 : "AFTER", + 0x02 : "PUSH", + 0x03 : "AND", + 0x04 : "OR", + 0x05 : "NOT", + 0x06 : "TRUE", + 0x07 : "FALSE", + 0x08 : "END", + 0x09 : "SOR" + } + + _NEXT_ =3D { + -1 : _OPCODE_, # first one in depex must be an opcdoe + 0x00 : _GUID_, #"BEFORE", + 0x01 : _GUID_, #"AFTER", + 0x02 : _GUID_, #"PUSH", + 0x03 : _OPCODE_, #"AND", + 0x04 : _OPCODE_, #"OR", + 0x05 : _OPCODE_, #"NOT", + 0x06 : _OPCODE_, #"TRUE", + 0x07 : _OPCODE_, #"FALSE", + 0x08 : None, #"END", + 0x09 : _OPCODE_, #"SOR" + } + + def __init__(m): + Image.__init__(m) + m._ExprList =3D [] + + def __str__(m): + global gIndention + gIndention +=3D 4 + Indention =3D ' ' * gIndention + S =3D '\n' + for T in m.Expression: + if T in m._OPCODE_STRING_: + S +=3D Indention + m._OPCODE_STRING_[T] + if T not in [0x00, 0x01, 0x02]: + S +=3D '\n' + else: + S +=3D ' ' + gGuidStringFormat % T + '\n' + gIndention -=3D 4 + return S + + def _Unpack(m): + # keep header in this Image object + m.empty() + m.extend(m._BUF_[m._OFF_ : m._OFF_ + m._LEN_]) + return len(m) + + def _GetExpression(m): + if m._ExprList =3D=3D []: + Offset =3D 0 + CurrentData =3D m._OPCODE_ + while Offset < len(m): + Token =3D CurrentData.unpack_from(m, Offset) + Offset +=3D CurrentData.size + if len(Token) =3D=3D 1: + Token =3D Token[0] + if Token in m._NEXT_: + CurrentData =3D m._NEXT_[Token] + else: + CurrentData =3D m._GUID_ + else: + CurrentData =3D m._OPCODE_ + m._ExprList.append(Token) + if CurrentData is None: + break + return m._ExprList + + Expression =3D property(_GetExpression) + +## FirmwareVolume() class +# +# A class for Firmware Volume +# +class FirmwareVolume(Image): + # Read FvLength, Attributes, HeaderLength, Checksum + _HEADER_ =3D struct.Struct("16x 1I2H8B 1Q 4x 1I 1H 1H") + _HEADER_SIZE_ =3D _HEADER_.size + + _FfsGuid =3D "8C8CE578-8A3D-4F1C-9935-896185C32DD3" + + _GUID_ =3D struct.Struct("16x 1I2H8B") + _LENGTH_ =3D struct.Struct("16x 16x 1Q") + _SIG_ =3D struct.Struct("16x 16x 8x 1I") + _ATTR_ =3D struct.Struct("16x 16x 8x 4x 1I") + _HLEN_ =3D struct.Struct("16x 16x 8x 4x 4x 1H") + _CHECKSUM_ =3D struct.Struct("16x 16x 8x 4x 4x 2x 1H") + + def __init__(self, Name=3D''): + Image.__init__(self) + self.Name =3D Name + self.FfsDict =3D sdict() + self.OrderedFfsDict =3D sdict() + self.UnDispatchedFfsDict =3D sdict() + self.ProtocolList =3D 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 =3D None + if Type =3D=3D 'Ppi': + List =3D EotGlobalData.gPpiList + if Type =3D=3D 'Protocol': + List =3D EotGlobalData.gProtocolList + DepexStack =3D [] + DepexList =3D [] + DepexString =3D '' + FileDepex =3D None + CouldBeLoaded =3D True + for Index in range(0, len(Depex.Expression)): + Item =3D Depex.Expression[Index] + if Item =3D=3D 0x00: + Index =3D Index + 1 + Guid =3D gGuidStringFormat % Depex.Expression[Index] + if Guid in self.OrderedFfsDict and Depex.Expression[Index = + 1] =3D=3D 0x08: + return (True, 'BEFORE %s' % Guid, [Guid, 'BEFORE']) + elif Item =3D=3D 0x01: + Index =3D Index + 1 + Guid =3D gGuidStringFormat % Depex.Expression[Index] + if Guid in self.OrderedFfsDict and Depex.Expression[Index = + 1] =3D=3D 0x08: + return (True, 'AFTER %s' % Guid, [Guid, 'AFTER']) + elif Item =3D=3D 0x02: + Index =3D Index + 1 + Guid =3D 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 =3D=3D 0x03 or Item =3D=3D 0x04: + DepexStack.append(eval(str(DepexStack.pop()) + ' ' + Depex= ._OPCODE_STRING_[Item].lower() + ' ' + str(DepexStack.pop()))) + DepexList.append(str(DepexList.pop()) + ' ' + Depex._OPCOD= E_STRING_[Item].upper() + ' ' + str(DepexList.pop())) + elif Item =3D=3D 0x05: + DepexStack.append(eval(Depex._OPCODE_STRING_[Item].lower()= + ' ' + str(DepexStack.pop()))) + DepexList.append(Depex._OPCODE_STRING_[Item].lower() + ' '= + str(DepexList.pop())) + elif Item =3D=3D 0x06: + DepexStack.append(True) + DepexList.append('TRUE') + DepexString =3D DepexString + 'TRUE' + ' ' + elif Item =3D=3D 0x07: + DepexStack.append(False) + DepexList.append('False') + DepexString =3D DepexString + 'FALSE' + ' ' + elif Item =3D=3D 0x08: + if Index !=3D len(Depex.Expression) - 1: + CouldBeLoaded =3D False + else: + CouldBeLoaded =3D DepexStack.pop() + else: + CouldBeLoaded =3D False + if DepexList !=3D []: + DepexString =3D DepexList[0].strip() + return (CouldBeLoaded, DepexString, FileDepex) + + def Dispatch(self, Db =3D None): + if Db is None: + return False + self.UnDispatchedFfsDict =3D copy.copy(self.FfsDict) + # Find PeiCore, DexCore, PeiPriori, DxePriori first + FfsSecCoreGuid =3D None + FfsPeiCoreGuid =3D None + FfsDxeCoreGuid =3D None + FfsPeiPrioriGuid =3D None + FfsDxePrioriGuid =3D None + for FfsID in self.UnDispatchedFfsDict: + Ffs =3D self.UnDispatchedFfsDict[FfsID] + if Ffs.Type =3D=3D 0x03: + FfsSecCoreGuid =3D FfsID + continue + if Ffs.Type =3D=3D 0x04: + FfsPeiCoreGuid =3D FfsID + continue + if Ffs.Type =3D=3D 0x05: + FfsDxeCoreGuid =3D FfsID + continue + if Ffs.Guid.lower() =3D=3D gPeiAprioriFileNameGuid: + FfsPeiPrioriGuid =3D FfsID + continue + if Ffs.Guid.lower() =3D=3D gAprioriGuid: + FfsDxePrioriGuid =3D FfsID + continue + + # Parse SEC_CORE first + if FfsSecCoreGuid is not None: + self.OrderedFfsDict[FfsSecCoreGuid] =3D self.UnDispatchedFfsDi= ct.pop(FfsSecCoreGuid) + self.LoadPpi(Db, FfsSecCoreGuid) + + # Parse PEI first + if FfsPeiCoreGuid is not None: + self.OrderedFfsDict[FfsPeiCoreGuid] =3D self.UnDispatchedFfsDi= ct.pop(FfsPeiCoreGuid) + self.LoadPpi(Db, FfsPeiCoreGuid) + if FfsPeiPrioriGuid is not None: + # Load PEIM described in priori file + FfsPeiPriori =3D self.UnDispatchedFfsDict.pop(FfsPeiPriori= Guid) + if len(FfsPeiPriori.Sections) =3D=3D 1: + Section =3D FfsPeiPriori.Sections.popitem()[1] + if Section.Type =3D=3D 0x19: + GuidStruct =3D struct.Struct('1I2H8B') + Start =3D 4 + while len(Section) > Start: + Guid =3D GuidStruct.unpack_from(Section[Start = : Start + 16]) + GuidString =3D gGuidStringFormat % Guid + Start =3D Start + 16 + if GuidString in self.UnDispatchedFfsDict: + self.OrderedFfsDict[GuidString] =3D self.U= nDispatchedFfsDict.pop(GuidString) + self.LoadPpi(Db, GuidString) + + self.DisPatchPei(Db) + + # Parse DXE then + if FfsDxeCoreGuid is not None: + self.OrderedFfsDict[FfsDxeCoreGuid] =3D self.UnDispatchedFfsDi= ct.pop(FfsDxeCoreGuid) + self.LoadProtocol(Db, FfsDxeCoreGuid) + if FfsDxePrioriGuid is not None: + # Load PEIM described in priori file + FfsDxePriori =3D self.UnDispatchedFfsDict.pop(FfsDxePriori= Guid) + if len(FfsDxePriori.Sections) =3D=3D 1: + Section =3D FfsDxePriori.Sections.popitem()[1] + if Section.Type =3D=3D 0x19: + GuidStruct =3D struct.Struct('1I2H8B') + Start =3D 4 + while len(Section) > Start: + Guid =3D GuidStruct.unpack_from(Section[Start = : Start + 16]) + GuidString =3D gGuidStringFormat % Guid + Start =3D Start + 16 + if GuidString in self.UnDispatchedFfsDict: + self.OrderedFfsDict[GuidString] =3D self.U= nDispatchedFfsDict.pop(GuidString) + self.LoadProtocol(Db, GuidString) + + self.DisPatchDxe(Db) + + def LoadProtocol(self, Db, ModuleGuid): + SqlCommand =3D """select GuidValue from Report + where SourceFileFullPath in + (select Value1 from Inf where BelongsToFile =3D + (select BelongsToFile from Inf + where Value1 =3D 'FILE_GUID' and Value2 like '%s' = and Model =3D %s) + and Model =3D %s) + and ItemType =3D 'Protocol' and ItemMode =3D 'Prod= uced'""" \ + % (ModuleGuid, 5001, 3007) + RecordSet =3D Db.TblReport.Exec(SqlCommand) + for Record in RecordSet: + SqlCommand =3D """select Value2 from Inf where BelongsToFile = =3D + (select DISTINCT BelongsToFile from Inf + where Value1 =3D + (select SourceFileFullPath from Report + where GuidValue like '%s' and ItemMode =3D 'Ca= llback')) + and Value1 =3D 'FILE_GUID'""" % Record[0] + CallBackSet =3D Db.TblReport.Exec(SqlCommand) + if CallBackSet !=3D []: + EotGlobalData.gProtocolList[Record[0].lower()] =3D ModuleG= uid + else: + EotGlobalData.gProtocolList[Record[0].lower()] =3D ModuleG= uid + + def LoadPpi(self, Db, ModuleGuid): + SqlCommand =3D """select GuidValue from Report + where SourceFileFullPath in + (select Value1 from Inf where BelongsToFile =3D + (select BelongsToFile from Inf + where Value1 =3D 'FILE_GUID' and Value2 like '%s' = and Model =3D %s) + and Model =3D %s) + and ItemType =3D 'Ppi' and ItemMode =3D 'Produced'= """ \ + % (ModuleGuid, 5001, 3007) + RecordSet =3D Db.TblReport.Exec(SqlCommand) + for Record in RecordSet: + EotGlobalData.gPpiList[Record[0].lower()] =3D ModuleGuid + + def DisPatchDxe(self, Db): + IsInstalled =3D False + ScheduleList =3D sdict() + for FfsID in self.UnDispatchedFfsDict: + CouldBeLoaded =3D False + DepexString =3D '' + FileDepex =3D None + Ffs =3D self.UnDispatchedFfsDict[FfsID] + if Ffs.Type =3D=3D 0x07: + # Get Depex + IsFoundDepex =3D False + for Section in Ffs.Sections.values(): + # Find Depex + if Section.Type =3D=3D 0x13: + IsFoundDepex =3D True + CouldBeLoaded, DepexString, FileDepex =3D self.Par= seDepex(Section._SubImages[4], 'Protocol') + break + if Section.Type =3D=3D 0x01: + CompressSections =3D Section._SubImages[4] + for CompressSection in CompressSections.Sections: + if CompressSection.Type =3D=3D 0x13: + IsFoundDepex =3D True + CouldBeLoaded, DepexString, FileDepex =3D = self.ParseDepex(CompressSection._SubImages[4], 'Protocol') + break + if CompressSection.Type =3D=3D 0x02: + NewSections =3D CompressSection._SubImages= [4] + for NewSection in NewSections.Sections: + if NewSection.Type =3D=3D 0x13: + IsFoundDepex =3D True + CouldBeLoaded, DepexString, FileDe= pex =3D self.ParseDepex(NewSection._SubImages[4], 'Protocol') + break + + # Not find Depex + if not IsFoundDepex: + CouldBeLoaded =3D self.CheckArchProtocol() + DepexString =3D '' + FileDepex =3D None + + # Append New Ffs + if CouldBeLoaded: + IsInstalled =3D True + NewFfs =3D self.UnDispatchedFfsDict.pop(FfsID) + NewFfs.Depex =3D DepexString + if FileDepex is not None: + ScheduleList.insert(FileDepex[1], FfsID, NewFfs, F= ileDepex[0]) + else: + ScheduleList[FfsID] =3D NewFfs + else: + self.UnDispatchedFfsDict[FfsID].Depex =3D DepexString + + for FfsID in ScheduleList: + NewFfs =3D ScheduleList.pop(FfsID) + FfsName =3D 'UnKnown' + self.OrderedFfsDict[FfsID] =3D NewFfs + self.LoadProtocol(Db, FfsID) + + SqlCommand =3D """select Value2 from Inf + where BelongsToFile =3D (select BelongsToFile = from Inf where Value1 =3D 'FILE_GUID' and lower(Value2) =3D lower('%s') and= Model =3D %s) + and Model =3D %s and Value1=3D'BASE_NAME'""" %= (FfsID, 5001, 5001) + RecordSet =3D Db.TblReport.Exec(SqlCommand) + if RecordSet !=3D []: + FfsName =3D RecordSet[0][0] + + if IsInstalled: + self.DisPatchDxe(Db) + + def DisPatchPei(self, Db): + IsInstalled =3D False + for FfsID in self.UnDispatchedFfsDict: + CouldBeLoaded =3D True + DepexString =3D '' + FileDepex =3D None + Ffs =3D self.UnDispatchedFfsDict[FfsID] + if Ffs.Type =3D=3D 0x06 or Ffs.Type =3D=3D 0x08: + # Get Depex + for Section in Ffs.Sections.values(): + if Section.Type =3D=3D 0x1B: + CouldBeLoaded, DepexString, FileDepex =3D self.Par= seDepex(Section._SubImages[4], 'Ppi') + break + + if Section.Type =3D=3D 0x01: + CompressSections =3D Section._SubImages[4] + for CompressSection in CompressSections.Sections: + if CompressSection.Type =3D=3D 0x1B: + CouldBeLoaded, DepexString, FileDepex =3D = self.ParseDepex(CompressSection._SubImages[4], 'Ppi') + break + if CompressSection.Type =3D=3D 0x02: + NewSections =3D CompressSection._SubImages= [4] + for NewSection in NewSections.Sections: + if NewSection.Type =3D=3D 0x1B: + CouldBeLoaded, DepexString, FileDe= pex =3D self.ParseDepex(NewSection._SubImages[4], 'Ppi') + break + + # Append New Ffs + if CouldBeLoaded: + IsInstalled =3D True + NewFfs =3D self.UnDispatchedFfsDict.pop(FfsID) + NewFfs.Depex =3D DepexString + self.OrderedFfsDict[FfsID] =3D NewFfs + self.LoadPpi(Db, FfsID) + else: + self.UnDispatchedFfsDict[FfsID].Depex =3D DepexString + + if IsInstalled: + self.DisPatchPei(Db) + + + def __str__(self): + global gIndention + gIndention +=3D 4 + FvInfo =3D '\n' + ' ' * gIndention + FvInfo +=3D "[FV:%s] file_system=3D%s size=3D%x checksum=3D%s\n" = % (self.Name, self.FileSystemGuid, self.Size, self.Checksum) + FfsInfo =3D "\n".join([str(self.FfsDict[FfsId]) for FfsId in self.= FfsDict]) + gIndention -=3D 4 + return FvInfo + FfsInfo + + def _Unpack(self): + Size =3D self._LENGTH_.unpack_from(self._BUF_, self._OFF_)[0] + self.empty() + self.extend(self._BUF_[self._OFF_:self._OFF_+Size]) + + # traverse the FFS + EndOfFv =3D Size + FfsStartAddress =3D self.HeaderSize + LastFfsObj =3D None + while FfsStartAddress < EndOfFv: + FfsObj =3D Ffs() + FfsObj.frombuffer(self, FfsStartAddress) + FfsId =3D repr(FfsObj) + if ((self.Attributes & 0x00000800) !=3D 0 and len(FfsObj) =3D= =3D 0xFFFFFF) \ + or ((self.Attributes & 0x00000800) =3D=3D 0 and len(FfsObj= ) =3D=3D 0): + if LastFfsObj is not None: + LastFfsObj.FreeSpace =3D EndOfFv - LastFfsObj._OFF_ - = len(LastFfsObj) + else: + if FfsId in self.FfsDict: + EdkLogger.error("FV", 0, "Duplicate GUID in FFS", + ExtraData=3D"\t%s @ %s\n\t%s @ %s" \ + % (FfsObj.Guid, FfsObj.Offset, + self.FfsDict[FfsId].Guid, self.FfsD= ict[FfsId].Offset)) + self.FfsDict[FfsId] =3D FfsObj + if LastFfsObj is not None: + LastFfsObj.FreeSpace =3D FfsStartAddress - LastFfsObj.= _OFF_ - len(LastFfsObj) + + FfsStartAddress +=3D len(FfsObj) + # + # align to next 8-byte aligned address: A =3D (A + 8 - 1) & (~= (8 - 1)) + # The next FFS must be at the latest next 8-byte aligned addre= ss + # + FfsStartAddress =3D (FfsStartAddress + 7) & (~7) + LastFfsObj =3D 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 =3D property(_GetAttributes) + Size =3D property(_GetSize) + Checksum =3D property(_GetChecksum) + HeaderSize =3D property(_GetHeaderLength) + FileSystemGuid =3D property(_GetFileSystemGuid) + +## GuidDefinedImage() class +# +# A class for GUID Defined Image +# +class GuidDefinedImage(Image): + _HEADER_ =3D struct.Struct("1I2H8B 1H 1H") + _HEADER_SIZE_ =3D _HEADER_.size + + _GUID_ =3D struct.Struct("1I2H8B") + _DATA_OFFSET_ =3D struct.Struct("16x 1H") + _ATTR_ =3D struct.Struct("18x 1H") + + CRC32_GUID =3D "FC1BCDB0-7D31-49AA-936A-A4600D9DD083" + TIANO_COMPRESS_GUID =3D 'A31280AD-481E-41B6-95E8-127F4C984779' + LZMA_COMPRESS_GUID =3D 'EE4E5898-3914-4259-9D6E-DC7BD79403CF' + + def __init__(m, SectionDefinitionGuid=3DNone, DataOffset=3DNone, Attri= butes=3DNone, Data=3DNone): + Image.__init__(m) + if SectionDefinitionGuid is not None: + m.SectionDefinitionGuid =3D SectionDefinitionGuid + if DataOffset is not None: + m.DataOffset =3D DataOffset + if Attributes is not None: + m.Attributes =3D Attributes + if Data is not None: + m.Data =3D Data + + def __str__(m): + S =3D "guid=3D%s" % (gGuidStringFormat % m.SectionDefinitionGuid) + for Sec in m.Sections: + S +=3D "\n" + str(Sec) + return S + + def _Unpack(m): + # keep header in this Image object + m.empty() + m.extend(m._BUF_[m._OFF_ : m._OFF_ + m._LEN_]) + return len(m) + + def _SetAttribute(m, Attribute): + m.SetField(m._ATTR_, 0, Attribute) + + def _GetAttribute(m): + return m.GetField(m._ATTR_)[0] + + def _SetGuid(m, Guid): + m.SetField(m._GUID_, 0, Guid) + + def _GetGuid(m): + return m.GetField(m._GUID_) + + def _SetDataOffset(m, Offset): + m.SetField(m._DATA_OFFSET_, 0, Offset) + + def _GetDataOffset(m): + return m.GetField(m._DATA_OFFSET_)[0] + + def _GetSections(m): + SectionList =3D [] + Guid =3D gGuidStringFormat % m.SectionDefinitionGuid + if Guid =3D=3D m.CRC32_GUID: + # skip the CRC32 value, we don't do CRC32 verification here + Offset =3D m.DataOffset - 4 + while Offset < len(m): + Sec =3D Section() + try: + Sec.frombuffer(m, Offset) + Offset +=3D Sec.Size + # the section is aligned to 4-byte boundary + Offset =3D (Offset + 3) & (~3) + except: + break + SectionList.append(Sec) + elif Guid =3D=3D m.TIANO_COMPRESS_GUID: + try: + import EfiCompressor + # skip the header + Offset =3D m.DataOffset - 4 + TmpData =3D EfiCompressor.FrameworkDecompress(m[Offset:], = len(m)-Offset) + DecData =3D array('B') + DecData.fromstring(TmpData) + Offset =3D 0 + while Offset < len(DecData): + Sec =3D Section() + try: + Sec.frombuffer(DecData, Offset) + Offset +=3D Sec.Size + # the section is aligned to 4-byte boundary + Offset =3D (Offset + 3) & (~3) + except: + break + SectionList.append(Sec) + except: + pass + elif Guid =3D=3D m.LZMA_COMPRESS_GUID: + try: + import LzmaCompressor + # skip the header + Offset =3D m.DataOffset - 4 + TmpData =3D LzmaCompressor.LzmaDecompress(m[Offset:], len(= m)-Offset) + DecData =3D array('B') + DecData.fromstring(TmpData) + Offset =3D 0 + while Offset < len(DecData): + Sec =3D Section() + try: + Sec.frombuffer(DecData, Offset) + Offset +=3D Sec.Size + # the section is aligned to 4-byte boundary + Offset =3D (Offset + 3) & (~3) + except: + break + SectionList.append(Sec) + except: + pass + + return SectionList + + Attributes =3D property(_GetAttribute, _SetAttribute) + SectionDefinitionGuid =3D property(_GetGuid, _SetGuid) + DataOffset =3D property(_GetDataOffset, _SetDataOffset) + Sections =3D property(_GetSections) + +## Section() class +# +# A class for Section +# +class Section(Image): + _TypeName =3D { + 0x00 : "", + 0x01 : "COMPRESSION", + 0x02 : "GUID_DEFINED", + 0x10 : "PE32", + 0x11 : "PIC", + 0x12 : "TE", + 0x13 : "DXE_DEPEX", + 0x14 : "VERSION", + 0x15 : "USER_INTERFACE", + 0x16 : "COMPATIBILITY16", + 0x17 : "FIRMWARE_VOLUME_IMAGE", + 0x18 : "FREEFORM_SUBTYPE_GUID", + 0x19 : "RAW", + 0x1B : "PEI_DEPEX" + } + + _SectionSubImages =3D { + 0x01 : CompressedImage, + 0x02 : GuidDefinedImage, + 0x17 : FirmwareVolume, + 0x13 : Depex, + 0x1B : Depex, + 0x15 : Ui + } + + # Size =3D 3-byte + # Type =3D 1-byte + _HEADER_ =3D struct.Struct("3B 1B") + _HEADER_SIZE_ =3D _HEADER_.size + + # SubTypeGuid + # _FREE_FORM_SUBTYPE_GUID_HEADER_ =3D struct.Struct("1I2H8B") + + _SIZE_ =3D struct.Struct("3B") + _TYPE_ =3D struct.Struct("3x 1B") + + def __init__(m, Type=3DNone, Size=3DNone): + Image.__init__(m) + m._Alignment =3D 1 + if Type is not None: + m.Type =3D Type + if Size is not None: + m.Size =3D Size + + def __str__(m): + global gIndention + gIndention +=3D 4 + SectionInfo =3D ' ' * gIndention + if m.Type in m._TypeName: + SectionInfo +=3D "[SECTION:%s] offset=3D%x size=3D%x" % (m._Ty= peName[m.Type], m._OFF_, m.Size) + else: + SectionInfo +=3D "[SECTION:%x] offset=3D%x size=3D%x = " % (m.Type, m._OFF_, m.Size) + for Offset in m._SubImages: + SectionInfo +=3D ", " + str(m._SubImages[Offset]) + gIndention -=3D 4 + return SectionInfo + + def _Unpack(m): + m.empty() + Type, =3D m._TYPE_.unpack_from(m._BUF_, m._OFF_) + Size1, Size2, Size3 =3D m._SIZE_.unpack_from(m._BUF_, m._OFF_) + Size =3D Size1 + (Size2 << 8) + (Size3 << 16) + + if Type not in m._SectionSubImages: + # no need to extract sub-image, keep all in this Image object + m.extend(m._BUF_[m._OFF_ : m._OFF_ + Size]) + else: + # keep header in this Image object + m.extend(m._BUF_[m._OFF_ : m._OFF_ + m._HEADER_SIZE_]) + # + # use new Image object to represent payload, which may be anot= her kind + # of image such as PE32 + # + PayloadOffset =3D m._HEADER_SIZE_ + PayloadLen =3D m.Size - m._HEADER_SIZE_ + Payload =3D m._SectionSubImages[m.Type]() + Payload.frombuffer(m._BUF_, m._OFF_ + m._HEADER_SIZE_, Payload= Len) + m._SubImages[PayloadOffset] =3D Payload + + return Size + + def _SetSize(m, Size): + Size1 =3D Size & 0xFF + Size2 =3D (Size & 0xFF00) >> 8 + Size3 =3D (Size & 0xFF0000) >> 16 + m.SetField(m._SIZE_, 0, Size1, Size2, Size3) + + def _GetSize(m): + Size1, Size2, Size3 =3D m.GetField(m._SIZE_) + return Size1 + (Size2 << 8) + (Size3 << 16) + + def _SetType(m, Type): + m.SetField(m._TYPE_, 0, Type) + + def _GetType(m): + return m.GetField(m._TYPE_)[0] + + def _GetAlignment(m): + return m._Alignment + + def _SetAlignment(m, Alignment): + m._Alignment =3D Alignment + AlignmentMask =3D Alignment - 1 + # section alignment is actually for payload, so we need to add hea= der size + PayloadOffset =3D m._OFF_ + m._HEADER_SIZE_ + if (PayloadOffset & (~AlignmentMask)) =3D=3D 0: + return + NewOffset =3D (PayloadOffset + AlignmentMask) & (~AlignmentMask) + while (NewOffset - PayloadOffset) < m._HEADER_SIZE_: + NewOffset +=3D m._Alignment + + def tofile(m, f): + m.Size =3D len(m) + Image.tofile(m, f) + for Offset in m._SubImages: + m._SubImages[Offset].tofile(f) + + Type =3D property(_GetType, _SetType) + Size =3D property(_GetSize, _SetSize) + Alignment =3D property(_GetAlignment, _SetAlignment) + +## Ffs() class +# +# A class for Ffs Section +# +class Ffs(Image): + _FfsFormat =3D "24B%(payload_size)sB" + # skip IntegrityCheck + _HEADER_ =3D struct.Struct("1I2H8B 2x 1B 1B 3B 1B") + _HEADER_SIZE_ =3D _HEADER_.size + + _NAME_ =3D struct.Struct("1I2H8B") + _INT_CHECK_ =3D struct.Struct("16x 1H") + _TYPE_ =3D struct.Struct("18x 1B") + _ATTR_ =3D struct.Struct("19x 1B") + _SIZE_ =3D struct.Struct("20x 3B") + _STATE_ =3D struct.Struct("23x 1B") + + VTF_GUID =3D "1BA0062E-C779-4582-8566-336AE8F78F09" + + FFS_ATTRIB_FIXED =3D 0x04 + FFS_ATTRIB_DATA_ALIGNMENT =3D 0x38 + FFS_ATTRIB_CHECKSUM =3D 0x40 + + _TypeName =3D { + 0x00 : "", + 0x01 : "RAW", + 0x02 : "FREEFORM", + 0x03 : "SECURITY_CORE", + 0x04 : "PEI_CORE", + 0x05 : "DXE_CORE", + 0x06 : "PEIM", + 0x07 : "DRIVER", + 0x08 : "COMBINED_PEIM_DRIVER", + 0x09 : "APPLICATION", + 0x0A : "SMM", + 0x0B : "FIRMWARE_VOLUME_IMAGE", + 0x0C : "COMBINED_SMM_DXE", + 0x0D : "SMM_CORE", + 0x0E : "MM_STANDALONE", + 0x0F : "MM_CORE_STANDALONE", + 0xc0 : "OEM_MIN", + 0xdf : "OEM_MAX", + 0xe0 : "DEBUG_MIN", + 0xef : "DEBUG_MAX", + 0xf0 : "FFS_MIN", + 0xff : "FFS_MAX", + 0xf0 : "FFS_PAD", + } + + def __init__(self): + Image.__init__(self) + self.FreeSpace =3D 0 + + self.Sections =3D sdict() + self.Depex =3D '' + + self.__ID__ =3D None + + def __str__(self): + global gIndention + gIndention +=3D 4 + Indention =3D ' ' * gIndention + FfsInfo =3D Indention + FfsInfo +=3D "[FFS:%s] offset=3D%x size=3D%x guid=3D%s free_space= =3D%x alignment=3D%s\n" % \ + (Ffs._TypeName[self.Type], self._OFF_, self.Size, self= .Guid, self.FreeSpace, self.Alignment) + SectionInfo =3D '\n'.join([str(self.Sections[Offset]) for Offset i= n self.Sections]) + gIndention -=3D 4 + return FfsInfo + SectionInfo + "\n" + + def __len__(self): + return self.Size + + def __repr__(self): + return self.__ID__ + + def _Unpack(self): + Size1, Size2, Size3 =3D self._SIZE_.unpack_from(self._BUF_, self._= OFF_) + Size =3D Size1 + (Size2 << 8) + (Size3 << 16) + self.empty() + self.extend(self._BUF_[self._OFF_ : self._OFF_ + Size]) + + # Pad FFS may use the same GUID. We need to avoid it. + if self.Type =3D=3D 0xf0: + self.__ID__ =3D str(uuid.uuid1()).upper() + else: + self.__ID__ =3D self.Guid + + # Traverse the SECTION. RAW and PAD do not have sections + if self.Type not in [0xf0, 0x01] and Size > 0 and Size < 0xFFFFFF: + EndOfFfs =3D Size + SectionStartAddress =3D self._HEADER_SIZE_ + while SectionStartAddress < EndOfFfs: + SectionObj =3D Section() + SectionObj.frombuffer(self, SectionStartAddress) + #f =3D open(repr(SectionObj), 'wb') + #SectionObj.Size =3D 0 + #SectionObj.tofile(f) + #f.close() + self.Sections[SectionStartAddress] =3D SectionObj + SectionStartAddress +=3D len(SectionObj) + SectionStartAddress =3D (SectionStartAddress + 3) & (~3) + + def Pack(self): + pass + + def SetFreeSpace(self, Size): + self.FreeSpace =3D Size + + def _GetGuid(self): + return gGuidStringFormat % self.Name + + def _SetName(self, Value): + # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, G= uid10, Guid11 + self.SetField(self._NAME_, 0, Value) + + def _GetName(self): + # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, G= uid10, Guid11 + return self.GetField(self._NAME_) + + def _SetSize(m, Size): + Size1 =3D Size & 0xFF + Size2 =3D (Size & 0xFF00) >> 8 + Size3 =3D (Size & 0xFF0000) >> 16 + m.SetField(m._SIZE_, 0, Size1, Size2, Size3) + + def _GetSize(m): + Size1, Size2, Size3 =3D m.GetField(m._SIZE_) + return Size1 + (Size2 << 8) + (Size3 << 16) + + def _SetType(m, Type): + m.SetField(m._TYPE_, 0, Type) + + def _GetType(m): + return m.GetField(m._TYPE_)[0] + + def _SetAttributes(self, Value): + self.SetField(m._ATTR_, 0, Value) + + def _GetAttributes(self): + return self.GetField(self._ATTR_)[0] + + def _GetFixed(self): + if (self.Attributes & self.FFS_ATTRIB_FIXED) !=3D 0: + return True + return False + + def _GetCheckSum(self): + if (self.Attributes & self.FFS_ATTRIB_CHECKSUM) !=3D 0: + return True + return False + + def _GetAlignment(self): + return (self.Attributes & self.FFS_ATTRIB_DATA_ALIGNMENT) >> 3 + + def _SetState(self, Value): + self.SetField(m._STATE_, 0, Value) + + def _GetState(self): + return self.GetField(m._STATE_)[0] + + Name =3D property(_GetName, _SetName) + Guid =3D property(_GetGuid) + Type =3D property(_GetType, _SetType) + Size =3D property(_GetSize, _SetSize) + Attributes =3D property(_GetAttributes, _SetAttributes) + Fixed =3D property(_GetFixed) + Checksum =3D property(_GetCheckSum) + Alignment =3D property(_GetAlignment) + State =3D property(_GetState, _SetState) + +## FirmwareVolume() class +# +# A class for Firmware Volume +# +class FirmwareVolume(Image): + # Read FvLength, Attributes, HeaderLength, Checksum + _HEADER_ =3D struct.Struct("16x 1I2H8B 1Q 4x 1I 1H 1H") + _HEADER_SIZE_ =3D _HEADER_.size + + _FfsGuid =3D "8C8CE578-8A3D-4F1C-9935-896185C32DD3" + + _GUID_ =3D struct.Struct("16x 1I2H8B") + _LENGTH_ =3D struct.Struct("16x 16x 1Q") + _SIG_ =3D struct.Struct("16x 16x 8x 1I") + _ATTR_ =3D struct.Struct("16x 16x 8x 4x 1I") + _HLEN_ =3D struct.Struct("16x 16x 8x 4x 4x 1H") + _CHECKSUM_ =3D struct.Struct("16x 16x 8x 4x 4x 2x 1H") + + def __init__(self, Name=3D''): + Image.__init__(self) + self.Name =3D Name + self.FfsDict =3D sdict() + self.OrderedFfsDict =3D sdict() + self.UnDispatchedFfsDict =3D sdict() + self.ProtocolList =3D 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 =3D None + if Type =3D=3D 'Ppi': + List =3D EotGlobalData.gPpiList + if Type =3D=3D 'Protocol': + List =3D EotGlobalData.gProtocolList + DepexStack =3D [] + DepexList =3D [] + DepexString =3D '' + FileDepex =3D None + CouldBeLoaded =3D True + for Index in range(0, len(Depex.Expression)): + Item =3D Depex.Expression[Index] + if Item =3D=3D 0x00: + Index =3D Index + 1 + Guid =3D gGuidStringFormat % Depex.Expression[Index] + if Guid in self.OrderedFfsDict and Depex.Expression[Index = + 1] =3D=3D 0x08: + return (True, 'BEFORE %s' % Guid, [Guid, 'BEFORE']) + elif Item =3D=3D 0x01: + Index =3D Index + 1 + Guid =3D gGuidStringFormat % Depex.Expression[Index] + if Guid in self.OrderedFfsDict and Depex.Expression[Index = + 1] =3D=3D 0x08: + return (True, 'AFTER %s' % Guid, [Guid, 'AFTER']) + elif Item =3D=3D 0x02: + Index =3D Index + 1 + Guid =3D 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 =3D=3D 0x03 or Item =3D=3D 0x04: + DepexStack.append(eval(str(DepexStack.pop()) + ' ' + Depex= ._OPCODE_STRING_[Item].lower() + ' ' + str(DepexStack.pop()))) + DepexList.append(str(DepexList.pop()) + ' ' + Depex._OPCOD= E_STRING_[Item].upper() + ' ' + str(DepexList.pop())) + elif Item =3D=3D 0x05: + DepexStack.append(eval(Depex._OPCODE_STRING_[Item].lower()= + ' ' + str(DepexStack.pop()))) + DepexList.append(Depex._OPCODE_STRING_[Item].lower() + ' '= + str(DepexList.pop())) + elif Item =3D=3D 0x06: + DepexStack.append(True) + DepexList.append('TRUE') + DepexString =3D DepexString + 'TRUE' + ' ' + elif Item =3D=3D 0x07: + DepexStack.append(False) + DepexList.append('False') + DepexString =3D DepexString + 'FALSE' + ' ' + elif Item =3D=3D 0x08: + if Index !=3D len(Depex.Expression) - 1: + CouldBeLoaded =3D False + else: + CouldBeLoaded =3D DepexStack.pop() + else: + CouldBeLoaded =3D False + if DepexList !=3D []: + DepexString =3D DepexList[0].strip() + return (CouldBeLoaded, DepexString, FileDepex) + + def Dispatch(self, Db =3D None): + if Db is None: + return False + self.UnDispatchedFfsDict =3D copy.copy(self.FfsDict) + # Find PeiCore, DexCore, PeiPriori, DxePriori first + FfsSecCoreGuid =3D None + FfsPeiCoreGuid =3D None + FfsDxeCoreGuid =3D None + FfsPeiPrioriGuid =3D None + FfsDxePrioriGuid =3D None + for FfsID in self.UnDispatchedFfsDict: + Ffs =3D self.UnDispatchedFfsDict[FfsID] + if Ffs.Type =3D=3D 0x03: + FfsSecCoreGuid =3D FfsID + continue + if Ffs.Type =3D=3D 0x04: + FfsPeiCoreGuid =3D FfsID + continue + if Ffs.Type =3D=3D 0x05: + FfsDxeCoreGuid =3D FfsID + continue + if Ffs.Guid.lower() =3D=3D gPeiAprioriFileNameGuid: + FfsPeiPrioriGuid =3D FfsID + continue + if Ffs.Guid.lower() =3D=3D gAprioriGuid: + FfsDxePrioriGuid =3D FfsID + continue + + # Parse SEC_CORE first + if FfsSecCoreGuid is not None: + self.OrderedFfsDict[FfsSecCoreGuid] =3D self.UnDispatchedFfsDi= ct.pop(FfsSecCoreGuid) + self.LoadPpi(Db, FfsSecCoreGuid) + + # Parse PEI first + if FfsPeiCoreGuid is not None: + self.OrderedFfsDict[FfsPeiCoreGuid] =3D self.UnDispatchedFfsDi= ct.pop(FfsPeiCoreGuid) + self.LoadPpi(Db, FfsPeiCoreGuid) + if FfsPeiPrioriGuid is not None: + # Load PEIM described in priori file + FfsPeiPriori =3D self.UnDispatchedFfsDict.pop(FfsPeiPriori= Guid) + if len(FfsPeiPriori.Sections) =3D=3D 1: + Section =3D FfsPeiPriori.Sections.popitem()[1] + if Section.Type =3D=3D 0x19: + GuidStruct =3D struct.Struct('1I2H8B') + Start =3D 4 + while len(Section) > Start: + Guid =3D GuidStruct.unpack_from(Section[Start = : Start + 16]) + GuidString =3D gGuidStringFormat % Guid + Start =3D Start + 16 + if GuidString in self.UnDispatchedFfsDict: + self.OrderedFfsDict[GuidString] =3D self.U= nDispatchedFfsDict.pop(GuidString) + self.LoadPpi(Db, GuidString) + + self.DisPatchPei(Db) + + # Parse DXE then + if FfsDxeCoreGuid is not None: + self.OrderedFfsDict[FfsDxeCoreGuid] =3D self.UnDispatchedFfsDi= ct.pop(FfsDxeCoreGuid) + self.LoadProtocol(Db, FfsDxeCoreGuid) + if FfsDxePrioriGuid is not None: + # Load PEIM described in priori file + FfsDxePriori =3D self.UnDispatchedFfsDict.pop(FfsDxePriori= Guid) + if len(FfsDxePriori.Sections) =3D=3D 1: + Section =3D FfsDxePriori.Sections.popitem()[1] + if Section.Type =3D=3D 0x19: + GuidStruct =3D struct.Struct('1I2H8B') + Start =3D 4 + while len(Section) > Start: + Guid =3D GuidStruct.unpack_from(Section[Start = : Start + 16]) + GuidString =3D gGuidStringFormat % Guid + Start =3D Start + 16 + if GuidString in self.UnDispatchedFfsDict: + self.OrderedFfsDict[GuidString] =3D self.U= nDispatchedFfsDict.pop(GuidString) + self.LoadProtocol(Db, GuidString) + + self.DisPatchDxe(Db) + + def LoadProtocol(self, Db, ModuleGuid): + SqlCommand =3D """select GuidValue from Report + where SourceFileFullPath in + (select Value1 from Inf where BelongsToFile =3D + (select BelongsToFile from Inf + where Value1 =3D 'FILE_GUID' and Value2 like '%s' = and Model =3D %s) + and Model =3D %s) + and ItemType =3D 'Protocol' and ItemMode =3D 'Prod= uced'""" \ + % (ModuleGuid, 5001, 3007) + RecordSet =3D Db.TblReport.Exec(SqlCommand) + for Record in RecordSet: + SqlCommand =3D """select Value2 from Inf where BelongsToFile = =3D + (select DISTINCT BelongsToFile from Inf + where Value1 =3D + (select SourceFileFullPath from Report + where GuidValue like '%s' and ItemMode =3D 'Ca= llback')) + and Value1 =3D 'FILE_GUID'""" % Record[0] + CallBackSet =3D Db.TblReport.Exec(SqlCommand) + if CallBackSet !=3D []: + EotGlobalData.gProtocolList[Record[0].lower()] =3D ModuleG= uid + else: + EotGlobalData.gProtocolList[Record[0].lower()] =3D ModuleG= uid + + def LoadPpi(self, Db, ModuleGuid): + SqlCommand =3D """select GuidValue from Report + where SourceFileFullPath in + (select Value1 from Inf where BelongsToFile =3D + (select BelongsToFile from Inf + where Value1 =3D 'FILE_GUID' and Value2 like '%s' = and Model =3D %s) + and Model =3D %s) + and ItemType =3D 'Ppi' and ItemMode =3D 'Produced'= """ \ + % (ModuleGuid, 5001, 3007) + RecordSet =3D Db.TblReport.Exec(SqlCommand) + for Record in RecordSet: + EotGlobalData.gPpiList[Record[0].lower()] =3D ModuleGuid + + def DisPatchDxe(self, Db): + IsInstalled =3D False + ScheduleList =3D sdict() + for FfsID in self.UnDispatchedFfsDict: + CouldBeLoaded =3D False + DepexString =3D '' + FileDepex =3D None + Ffs =3D self.UnDispatchedFfsDict[FfsID] + if Ffs.Type =3D=3D 0x07: + # Get Depex + IsFoundDepex =3D False + for Section in Ffs.Sections.values(): + # Find Depex + if Section.Type =3D=3D 0x13: + IsFoundDepex =3D True + CouldBeLoaded, DepexString, FileDepex =3D self.Par= seDepex(Section._SubImages[4], 'Protocol') + break + if Section.Type =3D=3D 0x01: + CompressSections =3D Section._SubImages[4] + for CompressSection in CompressSections.Sections: + if CompressSection.Type =3D=3D 0x13: + IsFoundDepex =3D True + CouldBeLoaded, DepexString, FileDepex =3D = self.ParseDepex(CompressSection._SubImages[4], 'Protocol') + break + if CompressSection.Type =3D=3D 0x02: + NewSections =3D CompressSection._SubImages= [4] + for NewSection in NewSections.Sections: + if NewSection.Type =3D=3D 0x13: + IsFoundDepex =3D True + CouldBeLoaded, DepexString, FileDe= pex =3D self.ParseDepex(NewSection._SubImages[4], 'Protocol') + break + + # Not find Depex + if not IsFoundDepex: + CouldBeLoaded =3D self.CheckArchProtocol() + DepexString =3D '' + FileDepex =3D None + + # Append New Ffs + if CouldBeLoaded: + IsInstalled =3D True + NewFfs =3D self.UnDispatchedFfsDict.pop(FfsID) + NewFfs.Depex =3D DepexString + if FileDepex is not None: + ScheduleList.insert(FileDepex[1], FfsID, NewFfs, F= ileDepex[0]) + else: + ScheduleList[FfsID] =3D NewFfs + else: + self.UnDispatchedFfsDict[FfsID].Depex =3D DepexString + + for FfsID in ScheduleList: + NewFfs =3D ScheduleList.pop(FfsID) + FfsName =3D 'UnKnown' + self.OrderedFfsDict[FfsID] =3D NewFfs + self.LoadProtocol(Db, FfsID) + + SqlCommand =3D """select Value2 from Inf + where BelongsToFile =3D (select BelongsToFile = from Inf where Value1 =3D 'FILE_GUID' and lower(Value2) =3D lower('%s') and= Model =3D %s) + and Model =3D %s and Value1=3D'BASE_NAME'""" %= (FfsID, 5001, 5001) + RecordSet =3D Db.TblReport.Exec(SqlCommand) + if RecordSet !=3D []: + FfsName =3D RecordSet[0][0] + + if IsInstalled: + self.DisPatchDxe(Db) + + def DisPatchPei(self, Db): + IsInstalled =3D False + for FfsID in self.UnDispatchedFfsDict: + CouldBeLoaded =3D True + DepexString =3D '' + FileDepex =3D None + Ffs =3D self.UnDispatchedFfsDict[FfsID] + if Ffs.Type =3D=3D 0x06 or Ffs.Type =3D=3D 0x08: + # Get Depex + for Section in Ffs.Sections.values(): + if Section.Type =3D=3D 0x1B: + CouldBeLoaded, DepexString, FileDepex =3D self.Par= seDepex(Section._SubImages[4], 'Ppi') + break + + if Section.Type =3D=3D 0x01: + CompressSections =3D Section._SubImages[4] + for CompressSection in CompressSections.Sections: + if CompressSection.Type =3D=3D 0x1B: + CouldBeLoaded, DepexString, FileDepex =3D = self.ParseDepex(CompressSection._SubImages[4], 'Ppi') + break + if CompressSection.Type =3D=3D 0x02: + NewSections =3D CompressSection._SubImages= [4] + for NewSection in NewSections.Sections: + if NewSection.Type =3D=3D 0x1B: + CouldBeLoaded, DepexString, FileDe= pex =3D self.ParseDepex(NewSection._SubImages[4], 'Ppi') + break + + # Append New Ffs + if CouldBeLoaded: + IsInstalled =3D True + NewFfs =3D self.UnDispatchedFfsDict.pop(FfsID) + NewFfs.Depex =3D DepexString + self.OrderedFfsDict[FfsID] =3D NewFfs + self.LoadPpi(Db, FfsID) + else: + self.UnDispatchedFfsDict[FfsID].Depex =3D DepexString + + if IsInstalled: + self.DisPatchPei(Db) + + + def __str__(self): + global gIndention + gIndention +=3D 4 + FvInfo =3D '\n' + ' ' * gIndention + FvInfo +=3D "[FV:%s] file_system=3D%s size=3D%x checksum=3D%s\n" = % (self.Name, self.FileSystemGuid, self.Size, self.Checksum) + FfsInfo =3D "\n".join([str(self.FfsDict[FfsId]) for FfsId in self.= FfsDict]) + gIndention -=3D 4 + return FvInfo + FfsInfo + + def _Unpack(self): + Size =3D self._LENGTH_.unpack_from(self._BUF_, self._OFF_)[0] + self.empty() + self.extend(self._BUF_[self._OFF_:self._OFF_+Size]) + + # traverse the FFS + EndOfFv =3D Size + FfsStartAddress =3D self.HeaderSize + LastFfsObj =3D None + while FfsStartAddress < EndOfFv: + FfsObj =3D Ffs() + FfsObj.frombuffer(self, FfsStartAddress) + FfsId =3D repr(FfsObj) + if ((self.Attributes & 0x00000800) !=3D 0 and len(FfsObj) =3D= =3D 0xFFFFFF) \ + or ((self.Attributes & 0x00000800) =3D=3D 0 and len(FfsObj= ) =3D=3D 0): + if LastFfsObj is not None: + LastFfsObj.FreeSpace =3D EndOfFv - LastFfsObj._OFF_ - = len(LastFfsObj) + else: + if FfsId in self.FfsDict: + EdkLogger.error("FV", 0, "Duplicate GUID in FFS", + ExtraData=3D"\t%s @ %s\n\t%s @ %s" \ + % (FfsObj.Guid, FfsObj.Offset, + self.FfsDict[FfsId].Guid, self.FfsD= ict[FfsId].Offset)) + self.FfsDict[FfsId] =3D FfsObj + if LastFfsObj is not None: + LastFfsObj.FreeSpace =3D FfsStartAddress - LastFfsObj.= _OFF_ - len(LastFfsObj) + + FfsStartAddress +=3D len(FfsObj) + # + # align to next 8-byte aligned address: A =3D (A + 8 - 1) & (~= (8 - 1)) + # The next FFS must be at the latest next 8-byte aligned addre= ss + # + FfsStartAddress =3D (FfsStartAddress + 7) & (~7) + LastFfsObj =3D 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 =3D property(_GetAttributes) + Size =3D property(_GetSize) + Checksum =3D property(_GetChecksum) + HeaderSize =3D property(_GetHeaderLength) + FileSystemGuid =3D property(_GetFileSystemGuid) =20 ## MultipleFv() class # @@ -390,6 +1830,8 @@ class Eot(object): SqlCommand =3D """select DISTINCT GuidValue, ItemType from Report = where ModuleID =3D -2 and ItemMode =3D 'Produced'""" RecordSet =3D EotGlobalData.gDb.TblReport.Exec(SqlCommand) for Record in RecordSet: + if Record[1] =3D=3D 'Ppi': + EotGlobalData.gPpiList[Record[0].lower()] =3D -2 if Record[1] =3D=3D 'Protocol': EotGlobalData.gProtocolList[Record[0].lower()] =3D -2 =20 diff --git a/BaseTools/Source/Python/Eot/EotGlobalData.py b/BaseTools/Sourc= e/Python/Eot/EotGlobalData.py index a9f51189c1eb..cb6a940ab8f9 100644 --- a/BaseTools/Source/Python/Eot/EotGlobalData.py +++ b/BaseTools/Source/Python/Eot/EotGlobalData.py @@ -65,6 +65,9 @@ gGuidDict =3D dict() =20 # Dict for PROTOCOL gProtocolList =3D {} +# Dict for PPI +gPpiList =3D {} + =20 # Dict for consumed PPI function calling gConsumedPpiLibrary =3D OrderedDict() @@ -92,3 +95,17 @@ gConsumedProtocolLibrary['EfiHandleProtocol'] =3D 1 # Dict for callback PROTOCOL function callling gCallbackProtocolLibrary =3D OrderedDict() gCallbackProtocolLibrary['EfiRegisterProtocolCallback'] =3D 2 + +gArchProtocolGuids =3D {'665e3ff6-46cc-11d4-9a38-0090273fc14d', + '26baccb1-6f42-11d4-bce7-0080c73c8881', + '26baccb2-6f42-11d4-bce7-0080c73c8881', + '1da97072-bddc-4b30-99f1-72a0b56fff2a', + '27cfac87-46cc-11d4-9a38-0090273fc14d', + '27cfac88-46cc-11d4-9a38-0090273fc14d', + 'b7dfb4e1-052f-449f-87be-9818fc91b733', + 'a46423e3-4617-49f1-b9ff-d1bfa9115839', + 'd2b2b828-0826-48a7-b3df-983c006024f0', + '26baccb3-6f42-11d4-bce7-0080c73c8881', + '1e5668e2-8481-11d4-bcf1-0080c73c8881', + '6441f818-6362-4e44-b570-7dba31dd2453', + '665e3ff5-46cc-11d4-9a38-0090273fc14d'} --=20 2.16.2.windows.1