2010-03-01 00:39:39 +01:00
## @file
# This file is used to be the main entrance of EOT tool
#
2018-04-16 19:48:22 +02:00
# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
2019-04-04 01:03:11 +02:00
# SPDX-License-Identifier: BSD-2-Clause-Patent
2010-03-01 00:39:39 +01:00
#
##
# Import Modules
#
2018-07-13 12:18:43 +02:00
from __future__ import absolute_import
2014-08-15 05:06:48 +02:00
import Common . LongFilePathOs as os , time , glob
2010-03-01 00:39:39 +01:00
import Common . EdkLogger as EdkLogger
2018-10-15 10:29:09 +02:00
import Eot . EotGlobalData as EotGlobalData
2010-03-01 00:39:39 +01:00
from optparse import OptionParser
2018-05-19 12:50:25 +02:00
from Common . StringUtils import NormPath
2010-03-01 00:39:39 +01:00
from Common import BuildToolError
2019-02-03 16:22:26 +01:00
from Common . Misc import GuidStructureStringToGuidString
from collections import OrderedDict as sdict
2018-10-15 10:29:09 +02:00
from Eot . Parser import *
from Eot . InfParserLite import EdkInfParser
from Common . StringUtils import GetSplitValueList
from Eot import c
from Eot import Database
2010-03-01 00:39:39 +01:00
from array import array
2018-10-15 10:29:09 +02:00
from Eot . Report import Report
2011-09-18 14:17:25 +02:00
from Common . BuildVersion import gBUILD_VERSION
2018-10-15 10:29:09 +02:00
from Eot . Parser import ConvertGuid
2014-08-15 05:06:48 +02:00
from Common . LongFilePathSupport import OpenLongFilePath as open
2018-05-24 16:17:53 +02:00
import struct
import uuid
import copy
import codecs
2018-10-23 19:29:19 +02:00
from GenFds . AprioriSection import DXE_APRIORI_GUID , PEI_APRIORI_GUID
2018-05-24 16:17:53 +02:00
gGuidStringFormat = " %08X - %04X - %04X - %02X %02X - %02X %02X %02X %02X %02X %02X "
gIndention = - 4
class Image ( array ) :
_HEADER_ = struct . Struct ( " " )
_HEADER_SIZE_ = _HEADER_ . size
def __new__ ( cls , * args , * * kwargs ) :
return array . __new__ ( cls , ' B ' )
def __init__ ( self , ID = None ) :
if ID is None :
self . _ID_ = str ( uuid . uuid1 ( ) ) . upper ( )
else :
self . _ID_ = ID
self . _BUF_ = None
self . _LEN_ = None
self . _OFF_ = None
self . _SubImages = sdict ( ) # {offset: Image()}
2018-10-15 10:29:09 +02:00
array . __init__ ( self )
2018-05-24 16:17:53 +02:00
def __repr__ ( self ) :
return self . _ID_
def __len__ ( self ) :
Len = array . __len__ ( self )
2018-10-15 10:29:09 +02:00
for Offset in self . _SubImages . keys ( ) :
2018-05-24 16:17:53 +02:00
Len + = 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 = 0xFF ) :
raise NotImplementedError
def frombuffer ( self , Buffer , Offset = 0 , Size = None ) :
self . _BUF_ = Buffer
self . _OFF_ = Offset
# we may need the Size information in advance if it's given
self . _LEN_ = Size
self . _LEN_ = self . _Unpack ( )
def empty ( self ) :
del self [ 0 : ]
def GetField ( self , FieldStruct , Offset = 0 ) :
return FieldStruct . unpack_from ( self , Offset )
def SetField ( self , FieldStruct , Offset , * args ) :
# check if there's enough space
Size = 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 = property ( _GetData , _SetData )
## CompressedImage() class
#
# A class for Compressed Image
#
class CompressedImage ( Image ) :
# UncompressedLength = 4-byte
# CompressionType = 1-byte
_HEADER_ = struct . Struct ( " 1I 1B " )
_HEADER_SIZE_ = _HEADER_ . size
_ORIG_SIZE_ = struct . Struct ( " 1I " )
_CMPRS_TYPE_ = struct . Struct ( " 4x 1B " )
2018-08-08 00:37:14 +02:00
def __init__ ( self , CompressedData = None , CompressionType = None , UncompressedLength = None ) :
Image . __init__ ( self )
2018-05-24 16:17:53 +02:00
if UncompressedLength is not None :
2018-08-08 00:37:14 +02:00
self . UncompressedLength = UncompressedLength
2018-05-24 16:17:53 +02:00
if CompressionType is not None :
2018-08-08 00:37:14 +02:00
self . CompressionType = CompressionType
2018-05-24 16:17:53 +02:00
if CompressedData is not None :
2018-08-08 00:37:14 +02:00
self . Data = CompressedData
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def __str__ ( self ) :
2018-05-24 16:17:53 +02:00
global gIndention
2018-08-08 00:37:14 +02:00
S = " algorithm= %s uncompressed= %x " % ( self . CompressionType , self . UncompressedLength )
for Sec in self . Sections :
2018-05-24 16:17:53 +02:00
S + = ' \n ' + str ( Sec )
return S
2018-08-08 00:37:14 +02:00
def _SetOriginalSize ( self , Size ) :
self . SetField ( self . _ORIG_SIZE_ , 0 , Size )
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _GetOriginalSize ( self ) :
return self . GetField ( self . _ORIG_SIZE_ ) [ 0 ]
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _SetCompressionType ( self , Type ) :
self . SetField ( self . _CMPRS_TYPE_ , 0 , Type )
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _GetCompressionType ( self ) :
return self . GetField ( self . _CMPRS_TYPE_ ) [ 0 ]
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _GetSections ( self ) :
2018-05-24 16:17:53 +02:00
try :
2018-10-15 10:29:09 +02:00
TmpData = DeCompress ( ' Efi ' , self [ self . _HEADER_SIZE_ : ] )
2018-05-24 16:17:53 +02:00
DecData = array ( ' B ' )
DecData . fromstring ( TmpData )
except :
2018-10-15 10:29:09 +02:00
TmpData = DeCompress ( ' Framework ' , self [ self . _HEADER_SIZE_ : ] )
2018-05-24 16:17:53 +02:00
DecData = array ( ' B ' )
DecData . fromstring ( TmpData )
SectionList = [ ]
Offset = 0
while Offset < len ( DecData ) :
Sec = Section ( )
try :
Sec . frombuffer ( DecData , Offset )
Offset + = Sec . Size
# the section is aligned to 4-byte boundary
except :
break
SectionList . append ( Sec )
return SectionList
UncompressedLength = property ( _GetOriginalSize , _SetOriginalSize )
CompressionType = property ( _GetCompressionType , _SetCompressionType )
Sections = property ( _GetSections )
## Ui() class
#
# A class for Ui
#
class Ui ( Image ) :
_HEADER_ = struct . Struct ( " " )
_HEADER_SIZE_ = 0
2018-08-08 00:37:14 +02:00
def __init__ ( self ) :
Image . __init__ ( self )
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def __str__ ( self ) :
return self . String
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _Unpack ( self ) :
2018-05-24 16:17:53 +02:00
# keep header in this Image object
2018-08-08 00:37:14 +02:00
self . empty ( )
self . extend ( self . _BUF_ [ self . _OFF_ : self . _OFF_ + self . _LEN_ ] )
return len ( self )
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _GetUiString ( self ) :
return codecs . utf_16_decode ( self [ 0 : - 2 ] . tostring ( ) ) [ 0 ]
2018-05-24 16:17:53 +02:00
String = property ( _GetUiString )
## Depex() class
#
# A class for Depex
#
class Depex ( Image ) :
_HEADER_ = struct . Struct ( " " )
_HEADER_SIZE_ = 0
_GUID_ = struct . Struct ( " 1I2H8B " )
_OPCODE_ = struct . Struct ( " 1B " )
_OPCODE_STRING_ = {
0x00 : " BEFORE " ,
0x01 : " AFTER " ,
0x02 : " PUSH " ,
0x03 : " AND " ,
0x04 : " OR " ,
0x05 : " NOT " ,
0x06 : " TRUE " ,
0x07 : " FALSE " ,
0x08 : " END " ,
0x09 : " SOR "
}
_NEXT_ = {
- 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"
}
2018-08-08 00:37:14 +02:00
def __init__ ( self ) :
Image . __init__ ( self )
self . _ExprList = [ ]
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def __str__ ( self ) :
2018-05-24 16:17:53 +02:00
global gIndention
gIndention + = 4
Indention = ' ' * gIndention
S = ' \n '
2018-08-08 00:37:14 +02:00
for T in self . Expression :
if T in self . _OPCODE_STRING_ :
S + = Indention + self . _OPCODE_STRING_ [ T ]
2018-05-24 16:17:53 +02:00
if T not in [ 0x00 , 0x01 , 0x02 ] :
S + = ' \n '
else :
S + = ' ' + gGuidStringFormat % T + ' \n '
gIndention - = 4
return S
2018-08-08 00:37:14 +02:00
def _Unpack ( self ) :
2018-05-24 16:17:53 +02:00
# keep header in this Image object
2018-08-08 00:37:14 +02:00
self . empty ( )
self . extend ( self . _BUF_ [ self . _OFF_ : self . _OFF_ + self . _LEN_ ] )
return len ( self )
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _GetExpression ( self ) :
if self . _ExprList == [ ] :
2018-05-24 16:17:53 +02:00
Offset = 0
2018-08-08 00:37:14 +02:00
CurrentData = self . _OPCODE_
while Offset < len ( self ) :
Token = CurrentData . unpack_from ( self , Offset )
2018-05-24 16:17:53 +02:00
Offset + = CurrentData . size
if len ( Token ) == 1 :
Token = Token [ 0 ]
2018-08-08 00:37:14 +02:00
if Token in self . _NEXT_ :
CurrentData = self . _NEXT_ [ Token ]
2018-05-24 16:17:53 +02:00
else :
2018-08-08 00:37:14 +02:00
CurrentData = self . _GUID_
2018-05-24 16:17:53 +02:00
else :
2018-08-08 00:37:14 +02:00
CurrentData = self . _OPCODE_
self . _ExprList . append ( Token )
2018-05-24 16:17:53 +02:00
if CurrentData is None :
break
2018-08-08 00:37:14 +02:00
return self . _ExprList
2018-05-24 16:17:53 +02:00
Expression = property ( _GetExpression )
2018-10-15 10:29:09 +02:00
# # FirmwareVolume() class
2018-05-24 16:17:53 +02:00
#
# 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 "
2018-10-15 10:29:09 +02:00
_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 " )
2018-05-24 16:17:53 +02:00
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 )
2018-10-15 10:29:09 +02:00
def Dispatch ( self , Db = None ) :
2018-05-24 16:17:53 +02:00
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
2019-02-25 10:19:02 +01:00
for FfsID in list ( self . UnDispatchedFfsDict . keys ( ) ) :
2018-05-24 16:17:53 +02:00
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
2018-10-23 19:29:19 +02:00
if Ffs . Guid . lower ( ) == PEI_APRIORI_GUID . lower ( ) :
2018-05-24 16:17:53 +02:00
FfsPeiPrioriGuid = FfsID
continue
2018-10-23 19:29:19 +02:00
if Ffs . Guid . lower ( ) == DXE_APRIORI_GUID . lower ( ) :
2018-05-24 16:17:53 +02:00
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 )
2018-10-15 10:29:09 +02:00
2018-05-24 16:17:53 +02:00
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 )
2018-10-15 10:29:09 +02:00
2018-05-24 16:17:53 +02:00
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 ( )
2019-02-25 10:19:02 +01:00
for FfsID in list ( self . UnDispatchedFfsDict . keys ( ) ) :
2018-05-24 16:17:53 +02:00
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
2018-10-15 10:29:09 +02:00
for FfsID in ScheduleList . keys ( ) :
2018-05-24 16:17:53 +02:00
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 ]
2018-10-15 10:29:09 +02:00
2018-05-24 16:17:53 +02:00
if IsInstalled :
self . DisPatchDxe ( Db )
def DisPatchPei ( self , Db ) :
IsInstalled = False
2019-02-25 10:19:02 +01:00
for FfsID in list ( self . UnDispatchedFfsDict . keys ( ) ) :
2018-05-24 16:17:53 +02:00
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 )
2018-10-15 10:29:09 +02:00
2018-05-24 16:17:53 +02:00
def __str__ ( self ) :
global gIndention
gIndention + = 4
FvInfo = ' \n ' + ' ' * gIndention
2018-10-15 10:29:09 +02:00
FvInfo + = " [FV: %s ] file_system= %s size= %x checksum= %s \n " % ( self . Name , self . FileSystemGuid , self . Size , self . Checksum )
2018-05-24 16:17:53 +02:00
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 ( )
2018-10-15 10:29:09 +02:00
self . extend ( self . _BUF_ [ self . _OFF_ : self . _OFF_ + Size ] )
2018-05-24 16:17:53 +02:00
# 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 )
## GuidDefinedImage() class
#
# A class for GUID Defined Image
#
class GuidDefinedImage ( Image ) :
_HEADER_ = struct . Struct ( " 1I2H8B 1H 1H " )
_HEADER_SIZE_ = _HEADER_ . size
_GUID_ = struct . Struct ( " 1I2H8B " )
_DATA_OFFSET_ = struct . Struct ( " 16x 1H " )
_ATTR_ = struct . Struct ( " 18x 1H " )
CRC32_GUID = " FC1BCDB0-7D31-49AA-936A-A4600D9DD083 "
TIANO_COMPRESS_GUID = ' A31280AD-481E-41B6-95E8-127F4C984779 '
LZMA_COMPRESS_GUID = ' EE4E5898-3914-4259-9D6E-DC7BD79403CF '
2018-08-08 00:37:14 +02:00
def __init__ ( self , SectionDefinitionGuid = None , DataOffset = None , Attributes = None , Data = None ) :
Image . __init__ ( self )
2018-05-24 16:17:53 +02:00
if SectionDefinitionGuid is not None :
2018-08-08 00:37:14 +02:00
self . SectionDefinitionGuid = SectionDefinitionGuid
2018-05-24 16:17:53 +02:00
if DataOffset is not None :
2018-08-08 00:37:14 +02:00
self . DataOffset = DataOffset
2018-05-24 16:17:53 +02:00
if Attributes is not None :
2018-08-08 00:37:14 +02:00
self . Attributes = Attributes
2018-05-24 16:17:53 +02:00
if Data is not None :
2018-08-08 00:37:14 +02:00
self . Data = Data
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def __str__ ( self ) :
S = " guid= %s " % ( gGuidStringFormat % self . SectionDefinitionGuid )
for Sec in self . Sections :
2018-05-24 16:17:53 +02:00
S + = " \n " + str ( Sec )
return S
2018-08-08 00:37:14 +02:00
def _Unpack ( self ) :
2018-05-24 16:17:53 +02:00
# keep header in this Image object
2018-08-08 00:37:14 +02:00
self . empty ( )
self . extend ( self . _BUF_ [ self . _OFF_ : self . _OFF_ + self . _LEN_ ] )
return len ( self )
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _SetAttribute ( self , Attribute ) :
self . SetField ( self . _ATTR_ , 0 , Attribute )
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _GetAttribute ( self ) :
return self . GetField ( self . _ATTR_ ) [ 0 ]
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _SetGuid ( self , Guid ) :
self . SetField ( self . _GUID_ , 0 , Guid )
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _GetGuid ( self ) :
return self . GetField ( self . _GUID_ )
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _SetDataOffset ( self , Offset ) :
self . SetField ( self . _DATA_OFFSET_ , 0 , Offset )
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _GetDataOffset ( self ) :
return self . GetField ( self . _DATA_OFFSET_ ) [ 0 ]
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _GetSections ( self ) :
2018-05-24 16:17:53 +02:00
SectionList = [ ]
2018-08-08 00:37:14 +02:00
Guid = gGuidStringFormat % self . SectionDefinitionGuid
if Guid == self . CRC32_GUID :
2018-05-24 16:17:53 +02:00
# skip the CRC32 value, we don't do CRC32 verification here
2018-08-08 00:37:14 +02:00
Offset = self . DataOffset - 4
while Offset < len ( self ) :
2018-05-24 16:17:53 +02:00
Sec = Section ( )
try :
2018-08-08 00:37:14 +02:00
Sec . frombuffer ( self , Offset )
2018-05-24 16:17:53 +02:00
Offset + = Sec . Size
# the section is aligned to 4-byte boundary
Offset = ( Offset + 3 ) & ( ~ 3 )
except :
break
SectionList . append ( Sec )
2018-08-08 00:37:14 +02:00
elif Guid == self . TIANO_COMPRESS_GUID :
2018-05-24 16:17:53 +02:00
try :
# skip the header
2018-08-08 00:37:14 +02:00
Offset = self . DataOffset - 4
2018-10-15 10:29:09 +02:00
TmpData = DeCompress ( ' Framework ' , self [ self . Offset : ] )
2018-05-24 16:17:53 +02:00
DecData = array ( ' B ' )
DecData . fromstring ( TmpData )
Offset = 0
while Offset < len ( DecData ) :
Sec = Section ( )
try :
Sec . frombuffer ( DecData , Offset )
Offset + = Sec . Size
# the section is aligned to 4-byte boundary
Offset = ( Offset + 3 ) & ( ~ 3 )
except :
break
SectionList . append ( Sec )
except :
pass
2018-08-08 00:37:14 +02:00
elif Guid == self . LZMA_COMPRESS_GUID :
2018-05-24 16:17:53 +02:00
try :
# skip the header
2018-08-08 00:37:14 +02:00
Offset = self . DataOffset - 4
2018-10-15 10:29:09 +02:00
TmpData = DeCompress ( ' Lzma ' , self [ self . Offset : ] )
2018-05-24 16:17:53 +02:00
DecData = array ( ' B ' )
DecData . fromstring ( TmpData )
Offset = 0
while Offset < len ( DecData ) :
Sec = Section ( )
try :
Sec . frombuffer ( DecData , Offset )
Offset + = Sec . Size
# the section is aligned to 4-byte boundary
Offset = ( Offset + 3 ) & ( ~ 3 )
except :
break
SectionList . append ( Sec )
except :
pass
return SectionList
Attributes = property ( _GetAttribute , _SetAttribute )
SectionDefinitionGuid = property ( _GetGuid , _SetGuid )
DataOffset = property ( _GetDataOffset , _SetDataOffset )
Sections = property ( _GetSections )
## Section() class
#
# A class for Section
#
class Section ( Image ) :
_TypeName = {
0x00 : " <unknown> " ,
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 = {
0x01 : CompressedImage ,
0x02 : GuidDefinedImage ,
0x17 : FirmwareVolume ,
0x13 : Depex ,
0x1B : Depex ,
0x15 : Ui
}
# Size = 3-byte
# Type = 1-byte
_HEADER_ = struct . Struct ( " 3B 1B " )
_HEADER_SIZE_ = _HEADER_ . size
# SubTypeGuid
# _FREE_FORM_SUBTYPE_GUID_HEADER_ = struct.Struct("1I2H8B")
_SIZE_ = struct . Struct ( " 3B " )
_TYPE_ = struct . Struct ( " 3x 1B " )
2018-08-08 00:37:14 +02:00
def __init__ ( self , Type = None , Size = None ) :
Image . __init__ ( self )
self . _Alignment = 1
2018-05-24 16:17:53 +02:00
if Type is not None :
2018-08-08 00:37:14 +02:00
self . Type = Type
2018-05-24 16:17:53 +02:00
if Size is not None :
2018-08-08 00:37:14 +02:00
self . Size = Size
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def __str__ ( self ) :
2018-05-24 16:17:53 +02:00
global gIndention
gIndention + = 4
SectionInfo = ' ' * gIndention
2018-08-08 00:37:14 +02:00
if self . Type in self . _TypeName :
SectionInfo + = " [SECTION: %s ] offset= %x size= %x " % ( self . _TypeName [ self . Type ] , self . _OFF_ , self . Size )
2018-05-24 16:17:53 +02:00
else :
2018-08-08 00:37:14 +02:00
SectionInfo + = " [SECTION: %x <unknown>] offset= %x size= %x " % ( self . Type , self . _OFF_ , self . Size )
2018-10-15 10:29:09 +02:00
for Offset in self . _SubImages . keys ( ) :
2018-08-08 00:37:14 +02:00
SectionInfo + = " , " + str ( self . _SubImages [ Offset ] )
2018-05-24 16:17:53 +02:00
gIndention - = 4
return SectionInfo
2018-08-08 00:37:14 +02:00
def _Unpack ( self ) :
self . empty ( )
Type , = self . _TYPE_ . unpack_from ( self . _BUF_ , self . _OFF_ )
Size1 , Size2 , Size3 = self . _SIZE_ . unpack_from ( self . _BUF_ , self . _OFF_ )
2018-05-24 16:17:53 +02:00
Size = Size1 + ( Size2 << 8 ) + ( Size3 << 16 )
2018-08-08 00:37:14 +02:00
if Type not in self . _SectionSubImages :
2018-05-24 16:17:53 +02:00
# no need to extract sub-image, keep all in this Image object
2018-08-08 00:37:14 +02:00
self . extend ( self . _BUF_ [ self . _OFF_ : self . _OFF_ + Size ] )
2018-05-24 16:17:53 +02:00
else :
# keep header in this Image object
2018-08-08 00:37:14 +02:00
self . extend ( self . _BUF_ [ self . _OFF_ : self . _OFF_ + self . _HEADER_SIZE_ ] )
2018-05-24 16:17:53 +02:00
#
# use new Image object to represent payload, which may be another kind
# of image such as PE32
#
2018-08-08 00:37:14 +02:00
PayloadOffset = self . _HEADER_SIZE_
PayloadLen = self . Size - self . _HEADER_SIZE_
Payload = self . _SectionSubImages [ self . Type ] ( )
Payload . frombuffer ( self . _BUF_ , self . _OFF_ + self . _HEADER_SIZE_ , PayloadLen )
self . _SubImages [ PayloadOffset ] = Payload
2018-05-24 16:17:53 +02:00
return Size
2018-08-08 00:37:14 +02:00
def _SetSize ( self , Size ) :
2018-05-24 16:17:53 +02:00
Size1 = Size & 0xFF
Size2 = ( Size & 0xFF00 ) >> 8
Size3 = ( Size & 0xFF0000 ) >> 16
2018-08-08 00:37:14 +02:00
self . SetField ( self . _SIZE_ , 0 , Size1 , Size2 , Size3 )
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _GetSize ( self ) :
Size1 , Size2 , Size3 = self . GetField ( self . _SIZE_ )
2018-05-24 16:17:53 +02:00
return Size1 + ( Size2 << 8 ) + ( Size3 << 16 )
2018-08-08 00:37:14 +02:00
def _SetType ( self , Type ) :
self . SetField ( self . _TYPE_ , 0 , Type )
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _GetType ( self ) :
return self . GetField ( self . _TYPE_ ) [ 0 ]
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _GetAlignment ( self ) :
return self . _Alignment
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _SetAlignment ( self , Alignment ) :
self . _Alignment = Alignment
2018-05-24 16:17:53 +02:00
AlignmentMask = Alignment - 1
# section alignment is actually for payload, so we need to add header size
2018-08-08 00:37:14 +02:00
PayloadOffset = self . _OFF_ + self . _HEADER_SIZE_
2018-05-24 16:17:53 +02:00
if ( PayloadOffset & ( ~ AlignmentMask ) ) == 0 :
return
NewOffset = ( PayloadOffset + AlignmentMask ) & ( ~ AlignmentMask )
2018-08-08 00:37:14 +02:00
while ( NewOffset - PayloadOffset ) < self . _HEADER_SIZE_ :
NewOffset + = self . _Alignment
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def tofile ( self , f ) :
self . Size = len ( self )
Image . tofile ( self , f )
for Offset in self . _SubImages :
self . _SubImages [ Offset ] . tofile ( f )
2018-05-24 16:17:53 +02:00
Type = property ( _GetType , _SetType )
Size = property ( _GetSize , _SetSize )
Alignment = property ( _GetAlignment , _SetAlignment )
## Ffs() class
#
# A class for Ffs Section
#
class Ffs ( Image ) :
_FfsFormat = " 24B %(payload_size)s B "
# skip IntegrityCheck
_HEADER_ = struct . Struct ( " 1I2H8B 2x 1B 1B 3B 1B " )
_HEADER_SIZE_ = _HEADER_ . size
_NAME_ = struct . Struct ( " 1I2H8B " )
_INT_CHECK_ = struct . Struct ( " 16x 1H " )
_TYPE_ = struct . Struct ( " 18x 1B " )
_ATTR_ = struct . Struct ( " 19x 1B " )
_SIZE_ = struct . Struct ( " 20x 3B " )
_STATE_ = struct . Struct ( " 23x 1B " )
FFS_ATTRIB_FIXED = 0x04
FFS_ATTRIB_DATA_ALIGNMENT = 0x38
FFS_ATTRIB_CHECKSUM = 0x40
_TypeName = {
0x00 : " <unknown> " ,
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 = 0
self . Sections = sdict ( )
self . Depex = ' '
self . __ID__ = None
def __str__ ( self ) :
global gIndention
gIndention + = 4
Indention = ' ' * gIndention
FfsInfo = Indention
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 )
2018-10-15 10:29:09 +02:00
SectionInfo = ' \n ' . join ( [ str ( self . Sections [ Offset ] ) for Offset in self . Sections . keys ( ) ] )
2018-05-24 16:17:53 +02:00
gIndention - = 4
return FfsInfo + SectionInfo + " \n "
def __len__ ( self ) :
return self . Size
def __repr__ ( self ) :
return self . __ID__
def _Unpack ( self ) :
Size1 , Size2 , Size3 = self . _SIZE_ . unpack_from ( self . _BUF_ , self . _OFF_ )
Size = 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 == 0xf0 :
self . __ID__ = str ( uuid . uuid1 ( ) ) . upper ( )
else :
self . __ID__ = 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 = Size
SectionStartAddress = self . _HEADER_SIZE_
while SectionStartAddress < EndOfFfs :
SectionObj = Section ( )
SectionObj . frombuffer ( self , SectionStartAddress )
#f = open(repr(SectionObj), 'wb')
#SectionObj.Size = 0
#SectionObj.tofile(f)
#f.close()
self . Sections [ SectionStartAddress ] = SectionObj
SectionStartAddress + = len ( SectionObj )
SectionStartAddress = ( SectionStartAddress + 3 ) & ( ~ 3 )
def Pack ( self ) :
pass
def SetFreeSpace ( self , Size ) :
self . FreeSpace = Size
def _GetGuid ( self ) :
return gGuidStringFormat % self . Name
def _SetName ( self , Value ) :
# Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
self . SetField ( self . _NAME_ , 0 , Value )
def _GetName ( self ) :
# Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
return self . GetField ( self . _NAME_ )
2018-08-08 00:37:14 +02:00
def _SetSize ( self , Size ) :
2018-05-24 16:17:53 +02:00
Size1 = Size & 0xFF
Size2 = ( Size & 0xFF00 ) >> 8
Size3 = ( Size & 0xFF0000 ) >> 16
2018-08-08 00:37:14 +02:00
self . SetField ( self . _SIZE_ , 0 , Size1 , Size2 , Size3 )
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _GetSize ( self ) :
Size1 , Size2 , Size3 = self . GetField ( self . _SIZE_ )
2018-05-24 16:17:53 +02:00
return Size1 + ( Size2 << 8 ) + ( Size3 << 16 )
2018-08-08 00:37:14 +02:00
def _SetType ( self , Type ) :
self . SetField ( self . _TYPE_ , 0 , Type )
2018-05-24 16:17:53 +02:00
2018-08-08 00:37:14 +02:00
def _GetType ( self ) :
return self . GetField ( self . _TYPE_ ) [ 0 ]
2018-05-24 16:17:53 +02:00
def _SetAttributes ( self , Value ) :
2018-08-08 00:37:14 +02:00
self . SetField ( self . _ATTR_ , 0 , Value )
2018-05-24 16:17:53 +02:00
def _GetAttributes ( self ) :
return self . GetField ( self . _ATTR_ ) [ 0 ]
def _GetFixed ( self ) :
if ( self . Attributes & self . FFS_ATTRIB_FIXED ) != 0 :
return True
return False
def _GetCheckSum ( self ) :
if ( self . Attributes & self . FFS_ATTRIB_CHECKSUM ) != 0 :
return True
return False
def _GetAlignment ( self ) :
return ( self . Attributes & self . FFS_ATTRIB_DATA_ALIGNMENT ) >> 3
def _SetState ( self , Value ) :
2018-08-08 00:37:14 +02:00
self . SetField ( self . _STATE_ , 0 , Value )
2018-05-24 16:17:53 +02:00
def _GetState ( self ) :
2018-08-08 00:37:14 +02:00
return self . GetField ( self . _STATE_ ) [ 0 ]
2018-05-24 16:17:53 +02:00
Name = property ( _GetName , _SetName )
Guid = property ( _GetGuid )
Type = property ( _GetType , _SetType )
Size = property ( _GetSize , _SetSize )
Attributes = property ( _GetAttributes , _SetAttributes )
Fixed = property ( _GetFixed )
Checksum = property ( _GetCheckSum )
Alignment = property ( _GetAlignment )
State = property ( _GetState , _SetState )
2010-03-01 00:39:39 +01:00
2018-04-16 19:48:22 +02:00
## MultipleFv() class
#
# A class for Multiple FV
#
class MultipleFv ( FirmwareVolume ) :
def __init__ ( self , FvList ) :
FirmwareVolume . __init__ ( self )
self . BasicInfo = [ ]
for FvPath in FvList :
2018-10-15 10:29:09 +02:00
Fd = None
2018-04-16 19:48:22 +02:00
FvName = os . path . splitext ( os . path . split ( FvPath ) [ 1 ] ) [ 0 ]
2018-10-15 10:29:09 +02:00
if FvPath . strip ( ) :
Fd = open ( FvPath , ' rb ' )
2018-04-16 19:48:22 +02:00
Buf = array ( ' B ' )
try :
Buf . fromfile ( Fd , os . path . getsize ( FvPath ) )
except EOFError :
pass
Fv = FirmwareVolume ( FvName )
Fv . frombuffer ( Buf , 0 , len ( Buf ) )
self . BasicInfo . append ( [ Fv . Name , Fv . FileSystemGuid , Fv . Size ] )
2019-02-25 10:00:31 +01:00
self . FfsDict . update ( Fv . FfsDict )
2018-04-16 19:48:22 +02:00
2010-03-01 00:39:39 +01:00
## Class Eot
#
# This class is used to define Eot main entrance
#
# @param object: Inherited from object class
#
class Eot ( object ) :
## The constructor
#
# @param self: The object pointer
#
def __init__ ( self , CommandLineOption = True , IsInit = True , SourceFileList = None , \
IncludeDirList = None , DecFileList = None , GuidList = None , LogFile = None ,
FvFileList = " " , MapFileList = " " , Report = ' Report.html ' , Dispatch = None ) :
# Version and Copyright
2011-09-18 14:17:25 +02:00
self . VersionNumber = ( " 0.02 " + " " + gBUILD_VERSION )
2010-03-01 00:39:39 +01:00
self . Version = " % prog Version " + self . VersionNumber
2018-07-05 11:40:04 +02:00
self . Copyright = " Copyright (c) 2008 - 2018, Intel Corporation All rights reserved. "
2010-03-01 00:39:39 +01:00
self . Report = Report
self . IsInit = IsInit
self . SourceFileList = SourceFileList
self . IncludeDirList = IncludeDirList
self . DecFileList = DecFileList
self . GuidList = GuidList
self . LogFile = LogFile
self . FvFileList = FvFileList
self . MapFileList = MapFileList
self . Dispatch = Dispatch
2018-07-05 11:40:04 +02:00
2010-03-01 00:39:39 +01:00
# Check workspace environment
if " EFI_SOURCE " not in os . environ :
if " EDK_SOURCE " not in os . environ :
pass
else :
EotGlobalData . gEDK_SOURCE = os . path . normpath ( os . getenv ( " EDK_SOURCE " ) )
else :
EotGlobalData . gEFI_SOURCE = os . path . normpath ( os . getenv ( " EFI_SOURCE " ) )
EotGlobalData . gEDK_SOURCE = os . path . join ( EotGlobalData . gEFI_SOURCE , ' Edk ' )
if " WORKSPACE " not in os . environ :
EdkLogger . error ( " EOT " , BuildToolError . ATTRIBUTE_NOT_AVAILABLE , " Environment variable not found " ,
ExtraData = " WORKSPACE " )
else :
EotGlobalData . gWORKSPACE = os . path . normpath ( os . getenv ( " WORKSPACE " ) )
EotGlobalData . gMACRO [ ' WORKSPACE ' ] = EotGlobalData . gWORKSPACE
EotGlobalData . gMACRO [ ' EFI_SOURCE ' ] = EotGlobalData . gEFI_SOURCE
EotGlobalData . gMACRO [ ' EDK_SOURCE ' ] = EotGlobalData . gEDK_SOURCE
# Parse the options and args
if CommandLineOption :
self . ParseOption ( )
if self . FvFileList :
for FvFile in GetSplitValueList ( self . FvFileList , ' ' ) :
FvFile = os . path . normpath ( FvFile )
if not os . path . isfile ( FvFile ) :
EdkLogger . error ( " Eot " , EdkLogger . EOT_ERROR , " Can not find file %s " % FvFile )
EotGlobalData . gFV_FILE . append ( FvFile )
else :
EdkLogger . error ( " Eot " , EdkLogger . EOT_ERROR , " The fv file list of target platform was not specified " )
if self . MapFileList :
for MapFile in GetSplitValueList ( self . MapFileList , ' ' ) :
MapFile = os . path . normpath ( MapFile )
if not os . path . isfile ( MapFile ) :
EdkLogger . error ( " Eot " , EdkLogger . EOT_ERROR , " Can not find file %s " % MapFile )
EotGlobalData . gMAP_FILE . append ( MapFile )
2018-07-05 11:40:04 +02:00
2010-03-01 00:39:39 +01:00
# Generate source file list
self . GenerateSourceFileList ( self . SourceFileList , self . IncludeDirList )
# Generate guid list of dec file list
self . ParseDecFile ( self . DecFileList )
2018-07-05 11:40:04 +02:00
2010-03-01 00:39:39 +01:00
# Generate guid list from GUID list file
self . ParseGuidList ( self . GuidList )
# Init Eot database
EotGlobalData . gDb = Database . Database ( Database . DATABASE_PATH )
EotGlobalData . gDb . InitDatabase ( self . IsInit )
# Build ECC database
self . BuildDatabase ( )
# Parse Ppi/Protocol
self . ParseExecutionOrder ( )
# Merge Identifier tables
self . GenerateQueryTable ( )
# Generate report database
self . GenerateReportDatabase ( )
# Load Fv Info
self . LoadFvInfo ( )
# Load Map Info
self . LoadMapInfo ( )
# Generate Report
self . GenerateReport ( )
# Convert log file
self . ConvertLogFile ( self . LogFile )
# DONE
EdkLogger . quiet ( " EOT FINISHED! " )
# Close Database
EotGlobalData . gDb . Close ( )
## ParseDecFile() method
#
# parse DEC file and get all GUID names with GUID values as {GuidName : GuidValue}
# The Dict is stored in EotGlobalData.gGuidDict
#
# @param self: The object pointer
# @param DecFileList: A list of all DEC files
#
def ParseDecFile ( self , DecFileList ) :
if DecFileList :
path = os . path . normpath ( DecFileList )
lfr = open ( path , ' rb ' )
for line in lfr :
path = os . path . normpath ( os . path . join ( EotGlobalData . gWORKSPACE , line . strip ( ) ) )
if os . path . exists ( path ) :
dfr = open ( path , ' rb ' )
for line in dfr :
line = CleanString ( line )
list = line . split ( ' = ' )
if len ( list ) == 2 :
EotGlobalData . gGuidDict [ list [ 0 ] . strip ( ) ] = GuidStructureStringToGuidString ( list [ 1 ] . strip ( ) )
2018-07-05 11:40:04 +02:00
2010-03-01 00:39:39 +01:00
## ParseGuidList() method
#
# Parse Guid list and get all GUID names with GUID values as {GuidName : GuidValue}
# The Dict is stored in EotGlobalData.gGuidDict
#
# @param self: The object pointer
# @param GuidList: A list of all GUID and its value
#
def ParseGuidList ( self , GuidList ) :
Path = os . path . join ( EotGlobalData . gWORKSPACE , GuidList )
if os . path . isfile ( Path ) :
for Line in open ( Path ) :
2018-10-15 10:29:09 +02:00
if Line . strip ( ) :
( GuidName , GuidValue ) = Line . split ( )
EotGlobalData . gGuidDict [ GuidName ] = GuidValue
2018-07-05 11:40:04 +02:00
2010-03-01 00:39:39 +01:00
## ConvertLogFile() method
#
# Parse a real running log file to get real dispatch order
# The result is saved to old file name + '.new'
#
# @param self: The object pointer
# @param LogFile: A real running log file name
#
def ConvertLogFile ( self , LogFile ) :
newline = [ ]
lfr = None
lfw = None
if LogFile :
lfr = open ( LogFile , ' rb ' )
lfw = open ( LogFile + ' .new ' , ' wb ' )
for line in lfr :
line = line . strip ( )
line = line . replace ( ' .efi ' , ' ' )
index = line . find ( " Loading PEIM at " )
if index > - 1 :
newline . append ( line [ index + 55 : ] )
continue
index = line . find ( " Loading driver at " )
if index > - 1 :
newline . append ( line [ index + 57 : ] )
continue
for line in newline :
lfw . write ( line + ' \r \n ' )
if lfr :
lfr . close ( )
if lfw :
lfw . close ( )
## GenerateSourceFileList() method
#
# Generate a list of all source files
# 1. Search the file list one by one
# 2. Store inf file name with source file names under it like
# { INF file name: [source file1, source file2, ...]}
# 3. Search the include list to find all .h files
# 4. Store source file list to EotGlobalData.gSOURCE_FILES
# 5. Store INF file list to EotGlobalData.gINF_FILES
#
# @param self: The object pointer
# @param SourceFileList: A list of all source files
# @param IncludeFileList: A list of all include files
#
def GenerateSourceFileList ( self , SourceFileList , IncludeFileList ) :
EdkLogger . quiet ( " Generating source files list ... " )
mSourceFileList = [ ]
mInfFileList = [ ]
mDecFileList = [ ]
mFileList = { }
mCurrentInfFile = ' '
mCurrentSourceFileList = [ ]
if SourceFileList :
2018-10-15 10:29:09 +02:00
sfl = open ( SourceFileList , ' r ' )
2010-03-01 00:39:39 +01:00
for line in sfl :
line = os . path . normpath ( os . path . join ( EotGlobalData . gWORKSPACE , line . strip ( ) ) )
if line [ - 2 : ] . upper ( ) == ' .C ' or line [ - 2 : ] . upper ( ) == ' .H ' :
if line not in mCurrentSourceFileList :
mCurrentSourceFileList . append ( line )
mSourceFileList . append ( line )
EotGlobalData . gOP_SOURCE_FILES . write ( ' %s \n ' % line )
if line [ - 4 : ] . upper ( ) == ' .INF ' :
if mCurrentInfFile != ' ' :
mFileList [ mCurrentInfFile ] = mCurrentSourceFileList
mCurrentSourceFileList = [ ]
mCurrentInfFile = os . path . normpath ( os . path . join ( EotGlobalData . gWORKSPACE , line ) )
EotGlobalData . gOP_INF . write ( ' %s \n ' % mCurrentInfFile )
if mCurrentInfFile not in mFileList :
mFileList [ mCurrentInfFile ] = mCurrentSourceFileList
# Get all include files from packages
if IncludeFileList :
ifl = open ( IncludeFileList , ' rb ' )
for line in ifl :
if not line . strip ( ) :
continue
newline = os . path . normpath ( os . path . join ( EotGlobalData . gWORKSPACE , line . strip ( ) ) )
for Root , Dirs , Files in os . walk ( str ( newline ) ) :
for File in Files :
FullPath = os . path . normpath ( os . path . join ( Root , File ) )
if FullPath not in mSourceFileList and File [ - 2 : ] . upper ( ) == ' .H ' :
mSourceFileList . append ( FullPath )
EotGlobalData . gOP_SOURCE_FILES . write ( ' %s \n ' % FullPath )
if FullPath not in mDecFileList and File . upper ( ) . find ( ' .DEC ' ) > - 1 :
mDecFileList . append ( FullPath )
EotGlobalData . gSOURCE_FILES = mSourceFileList
EotGlobalData . gOP_SOURCE_FILES . close ( )
EotGlobalData . gINF_FILES = mFileList
EotGlobalData . gOP_INF . close ( )
## GenerateReport() method
#
# Generate final HTML report
#
# @param self: The object pointer
#
def GenerateReport ( self ) :
EdkLogger . quiet ( " Generating report file ... " )
Rep = Report ( self . Report , EotGlobalData . gFV , self . Dispatch )
Rep . GenerateReport ( )
## LoadMapInfo() method
#
# Load map files and parse them
#
# @param self: The object pointer
#
def LoadMapInfo ( self ) :
if EotGlobalData . gMAP_FILE != [ ] :
EdkLogger . quiet ( " Parsing Map file ... " )
EotGlobalData . gMap = ParseMapFile ( EotGlobalData . gMAP_FILE )
## LoadFvInfo() method
#
# Load FV binary files and parse them
#
# @param self: The object pointer
#
def LoadFvInfo ( self ) :
EdkLogger . quiet ( " Parsing FV file ... " )
EotGlobalData . gFV = MultipleFv ( EotGlobalData . gFV_FILE )
EotGlobalData . gFV . Dispatch ( EotGlobalData . gDb )
for Protocol in EotGlobalData . gProtocolList :
EotGlobalData . gOP_UN_MATCHED_IN_LIBRARY_CALLING . write ( ' %s \n ' % Protocol )
## GenerateReportDatabase() method
#
# Generate data for the information needed by report
# 1. Update name, macro and value of all found PPI/PROTOCOL GUID
# 2. Install hard coded PPI/PROTOCOL
#
# @param self: The object pointer
#
def GenerateReportDatabase ( self ) :
EdkLogger . quiet ( " Generating the cross-reference table of GUID for Ppi/Protocol ... " )
# Update Protocol/Ppi Guid
SqlCommand = """ select DISTINCT GuidName from Report """
RecordSet = EotGlobalData . gDb . TblReport . Exec ( SqlCommand )
for Record in RecordSet :
GuidName = Record [ 0 ]
GuidMacro = ' '
GuidMacro2 = ' '
GuidValue = ' '
# Find guid value defined in Dec file
if GuidName in EotGlobalData . gGuidDict :
GuidValue = EotGlobalData . gGuidDict [ GuidName ]
SqlCommand = """ update Report set GuidMacro = ' %s ' , GuidValue = ' %s ' where GuidName = ' %s ' """ % ( GuidMacro , GuidValue , GuidName )
EotGlobalData . gDb . TblReport . Exec ( SqlCommand )
continue
# Search defined Macros for guid name
SqlCommand = """ select DISTINCT Value, Modifier from Query where Name like ' %s ' """ % GuidName
GuidMacroSet = EotGlobalData . gDb . TblReport . Exec ( SqlCommand )
# Ignore NULL result
if not GuidMacroSet :
continue
GuidMacro = GuidMacroSet [ 0 ] [ 0 ] . strip ( )
if not GuidMacro :
continue
# Find Guid value of Guid Macro
SqlCommand = """ select DISTINCT Value from Query2 where Value like ' %% %s %% ' and Model = %s """ % ( GuidMacro , MODEL_IDENTIFIER_MACRO_DEFINE )
GuidValueSet = EotGlobalData . gDb . TblReport . Exec ( SqlCommand )
if GuidValueSet != [ ] :
GuidValue = GuidValueSet [ 0 ] [ 0 ]
GuidValue = GuidValue [ GuidValue . find ( GuidMacro ) + len ( GuidMacro ) : ]
GuidValue = GuidValue . lower ( ) . replace ( ' \\ ' , ' ' ) . replace ( ' \r ' , ' ' ) . replace ( ' \n ' , ' ' ) . replace ( ' l ' , ' ' ) . strip ( )
GuidValue = GuidStructureStringToGuidString ( GuidValue )
SqlCommand = """ update Report set GuidMacro = ' %s ' , GuidValue = ' %s ' where GuidName = ' %s ' """ % ( GuidMacro , GuidValue , GuidName )
EotGlobalData . gDb . TblReport . Exec ( SqlCommand )
continue
# Update Hard Coded Ppi/Protocol
SqlCommand = """ select DISTINCT GuidValue, ItemType from Report where ModuleID = -2 and ItemMode = ' Produced ' """
RecordSet = EotGlobalData . gDb . TblReport . Exec ( SqlCommand )
for Record in RecordSet :
2018-05-24 16:17:53 +02:00
if Record [ 1 ] == ' Ppi ' :
EotGlobalData . gPpiList [ Record [ 0 ] . lower ( ) ] = - 2
2010-03-01 00:39:39 +01:00
if Record [ 1 ] == ' Protocol ' :
EotGlobalData . gProtocolList [ Record [ 0 ] . lower ( ) ] = - 2
## GenerateQueryTable() method
#
# Generate two tables improve query performance
#
# @param self: The object pointer
#
def GenerateQueryTable ( self ) :
EdkLogger . quiet ( " Generating temp query table for analysis ... " )
for Identifier in EotGlobalData . gIdentifierTableList :
SqlCommand = """ insert into Query (Name, Modifier, Value, Model)
select Name , Modifier , Value , Model from % s where ( Model = % s or Model = % s ) """ \
% ( Identifier [ 0 ] , MODEL_IDENTIFIER_VARIABLE , MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION )
EotGlobalData . gDb . TblReport . Exec ( SqlCommand )
SqlCommand = """ insert into Query2 (Name, Modifier, Value, Model)
select Name , Modifier , Value , Model from % s where Model = % s """ \
% ( Identifier [ 0 ] , MODEL_IDENTIFIER_MACRO_DEFINE )
EotGlobalData . gDb . TblReport . Exec ( SqlCommand )
## ParseExecutionOrder() method
#
# Get final execution order
# 1. Search all PPI
# 2. Search all PROTOCOL
#
# @param self: The object pointer
#
def ParseExecutionOrder ( self ) :
EdkLogger . quiet ( " Searching Ppi/Protocol ... " )
for Identifier in EotGlobalData . gIdentifierTableList :
ModuleID , ModuleName , ModuleGuid , SourceFileID , SourceFileFullPath , ItemName , ItemType , ItemMode , GuidName , GuidMacro , GuidValue , BelongsToFunction , Enabled = \
- 1 , ' ' , ' ' , - 1 , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , ' ' , 0
SourceFileID = Identifier [ 0 ] . replace ( ' Identifier ' , ' ' )
SourceFileFullPath = Identifier [ 1 ]
Identifier = Identifier [ 0 ]
# Find Ppis
ItemMode = ' Produced '
SqlCommand = """ select Value, Name, BelongsToFile, StartLine, EndLine from %s
where ( Name like ' %% %s %% ' or Name like ' %% %s %% ' or Name like ' %% %s %% ' ) and Model = % s """ \
% ( Identifier , ' .InstallPpi ' , ' ->InstallPpi ' , ' PeiInstallPpi ' , MODEL_IDENTIFIER_FUNCTION_CALLING )
SearchPpi ( SqlCommand , Identifier , SourceFileID , SourceFileFullPath , ItemMode )
ItemMode = ' Produced '
SqlCommand = """ select Value, Name, BelongsToFile, StartLine, EndLine from %s
where ( Name like ' %% %s %% ' or Name like ' %% %s %% ' ) and Model = % s """ \
% ( Identifier , ' .ReInstallPpi ' , ' ->ReInstallPpi ' , MODEL_IDENTIFIER_FUNCTION_CALLING )
SearchPpi ( SqlCommand , Identifier , SourceFileID , SourceFileFullPath , ItemMode , 2 )
SearchPpiCallFunction ( Identifier , SourceFileID , SourceFileFullPath , ItemMode )
ItemMode = ' Consumed '
SqlCommand = """ select Value, Name, BelongsToFile, StartLine, EndLine from %s
where ( Name like ' %% %s %% ' or Name like ' %% %s %% ' ) and Model = % s """ \
% ( Identifier , ' .LocatePpi ' , ' ->LocatePpi ' , MODEL_IDENTIFIER_FUNCTION_CALLING )
SearchPpi ( SqlCommand , Identifier , SourceFileID , SourceFileFullPath , ItemMode )
SearchFunctionCalling ( Identifier , SourceFileID , SourceFileFullPath , ' Ppi ' , ItemMode )
ItemMode = ' Callback '
SqlCommand = """ select Value, Name, BelongsToFile, StartLine, EndLine from %s
where ( Name like ' %% %s %% ' or Name like ' %% %s %% ' ) and Model = % s """ \
% ( Identifier , ' .NotifyPpi ' , ' ->NotifyPpi ' , MODEL_IDENTIFIER_FUNCTION_CALLING )
SearchPpi ( SqlCommand , Identifier , SourceFileID , SourceFileFullPath , ItemMode )
2019-02-06 08:44:39 +01:00
# Find Protocols
2010-03-01 00:39:39 +01:00
ItemMode = ' Produced '
SqlCommand = """ select Value, Name, BelongsToFile, StartLine, EndLine from %s
where ( Name like ' %% %s %% ' or Name like ' %% %s %% ' or Name like ' %% %s %% ' or Name like ' %% %s %% ' ) and Model = % s """ \
% ( Identifier , ' .InstallProtocolInterface ' , ' .ReInstallProtocolInterface ' , ' ->InstallProtocolInterface ' , ' ->ReInstallProtocolInterface ' , MODEL_IDENTIFIER_FUNCTION_CALLING )
SearchProtocols ( SqlCommand , Identifier , SourceFileID , SourceFileFullPath , ItemMode , 1 )
SqlCommand = """ select Value, Name, BelongsToFile, StartLine, EndLine from %s
where ( Name like ' %% %s %% ' or Name like ' %% %s %% ' ) and Model = % s """ \
% ( Identifier , ' .InstallMultipleProtocolInterfaces ' , ' ->InstallMultipleProtocolInterfaces ' , MODEL_IDENTIFIER_FUNCTION_CALLING )
SearchProtocols ( SqlCommand , Identifier , SourceFileID , SourceFileFullPath , ItemMode , 2 )
SearchFunctionCalling ( Identifier , SourceFileID , SourceFileFullPath , ' Protocol ' , ItemMode )
ItemMode = ' Consumed '
SqlCommand = """ select Value, Name, BelongsToFile, StartLine, EndLine from %s
where ( Name like ' %% %s %% ' or Name like ' %% %s %% ' ) and Model = % s """ \
% ( Identifier , ' .LocateProtocol ' , ' ->LocateProtocol ' , MODEL_IDENTIFIER_FUNCTION_CALLING )
SearchProtocols ( SqlCommand , Identifier , SourceFileID , SourceFileFullPath , ItemMode , 0 )
SqlCommand = """ select Value, Name, BelongsToFile, StartLine, EndLine from %s
where ( Name like ' %% %s %% ' or Name like ' %% %s %% ' ) and Model = % s """ \
% ( Identifier , ' .HandleProtocol ' , ' ->HandleProtocol ' , MODEL_IDENTIFIER_FUNCTION_CALLING )
SearchProtocols ( SqlCommand , Identifier , SourceFileID , SourceFileFullPath , ItemMode , 1 )
SearchFunctionCalling ( Identifier , SourceFileID , SourceFileFullPath , ' Protocol ' , ItemMode )
ItemMode = ' Callback '
SqlCommand = """ select Value, Name, BelongsToFile, StartLine, EndLine from %s
where ( Name like ' %% %s %% ' or Name like ' %% %s %% ' ) and Model = % s """ \
% ( Identifier , ' .RegisterProtocolNotify ' , ' ->RegisterProtocolNotify ' , MODEL_IDENTIFIER_FUNCTION_CALLING )
SearchProtocols ( SqlCommand , Identifier , SourceFileID , SourceFileFullPath , ItemMode , 0 )
SearchFunctionCalling ( Identifier , SourceFileID , SourceFileFullPath , ' Protocol ' , ItemMode )
# Hard Code
EotGlobalData . gDb . TblReport . Insert ( - 2 , ' ' , ' ' , - 1 , ' ' , ' ' , ' Ppi ' , ' Produced ' , ' gEfiSecPlatformInformationPpiGuid ' , ' ' , ' ' , ' ' , 0 )
EotGlobalData . gDb . TblReport . Insert ( - 2 , ' ' , ' ' , - 1 , ' ' , ' ' , ' Ppi ' , ' Produced ' , ' gEfiNtLoadAsDllPpiGuid ' , ' ' , ' ' , ' ' , 0 )
EotGlobalData . gDb . TblReport . Insert ( - 2 , ' ' , ' ' , - 1 , ' ' , ' ' , ' Ppi ' , ' Produced ' , ' gNtPeiLoadFileGuid ' , ' ' , ' ' , ' ' , 0 )
EotGlobalData . gDb . TblReport . Insert ( - 2 , ' ' , ' ' , - 1 , ' ' , ' ' , ' Ppi ' , ' Produced ' , ' gPeiNtAutoScanPpiGuid ' , ' ' , ' ' , ' ' , 0 )
EotGlobalData . gDb . TblReport . Insert ( - 2 , ' ' , ' ' , - 1 , ' ' , ' ' , ' Ppi ' , ' Produced ' , ' gNtFwhPpiGuid ' , ' ' , ' ' , ' ' , 0 )
EotGlobalData . gDb . TblReport . Insert ( - 2 , ' ' , ' ' , - 1 , ' ' , ' ' , ' Ppi ' , ' Produced ' , ' gPeiNtThunkPpiGuid ' , ' ' , ' ' , ' ' , 0 )
EotGlobalData . gDb . TblReport . Insert ( - 2 , ' ' , ' ' , - 1 , ' ' , ' ' , ' Ppi ' , ' Produced ' , ' gPeiPlatformTypePpiGuid ' , ' ' , ' ' , ' ' , 0 )
EotGlobalData . gDb . TblReport . Insert ( - 2 , ' ' , ' ' , - 1 , ' ' , ' ' , ' Ppi ' , ' Produced ' , ' gPeiFrequencySelectionCpuPpiGuid ' , ' ' , ' ' , ' ' , 0 )
EotGlobalData . gDb . TblReport . Insert ( - 2 , ' ' , ' ' , - 1 , ' ' , ' ' , ' Ppi ' , ' Produced ' , ' gPeiCachePpiGuid ' , ' ' , ' ' , ' ' , 0 )
EotGlobalData . gDb . Conn . commit ( )
## BuildDatabase() methoc
#
# Build the database for target
#
# @param self: The object pointer
#
def BuildDatabase ( self ) :
# Clean report table
EotGlobalData . gDb . TblReport . Drop ( )
EotGlobalData . gDb . TblReport . Create ( )
# Build database
if self . IsInit :
self . BuildMetaDataFileDatabase ( EotGlobalData . gINF_FILES )
EdkLogger . quiet ( " Building database for source code ... " )
c . CreateCCodeDB ( EotGlobalData . gSOURCE_FILES )
EdkLogger . quiet ( " Building database for source code done! " )
EotGlobalData . gIdentifierTableList = GetTableList ( ( MODEL_FILE_C , MODEL_FILE_H ) , ' Identifier ' , EotGlobalData . gDb )
## BuildMetaDataFileDatabase() method
#
# Build the database for meta data files
#
# @param self: The object pointer
# @param Inf_Files: A list for all INF files
#
def BuildMetaDataFileDatabase ( self , Inf_Files ) :
EdkLogger . quiet ( " Building database for meta data files ... " )
for InfFile in Inf_Files :
2018-10-15 10:29:09 +02:00
if not InfFile :
continue
2010-03-01 00:39:39 +01:00
EdkLogger . quiet ( " Parsing %s ... " % str ( InfFile ) )
2019-03-15 15:59:29 +01:00
EdkInfParser ( InfFile , EotGlobalData . gDb , Inf_Files [ InfFile ] )
2010-03-01 00:39:39 +01:00
EotGlobalData . gDb . Conn . commit ( )
EdkLogger . quiet ( " Building database for meta data files done! " )
## ParseOption() method
#
# Parse command line options
#
# @param self: The object pointer
#
def ParseOption ( self ) :
( Options , Target ) = self . EotOptionParser ( )
# Set log level
self . SetLogLevel ( Options )
if Options . FvFileList :
self . FvFileList = Options . FvFileList
2018-07-05 11:40:04 +02:00
2010-03-01 00:39:39 +01:00
if Options . MapFileList :
self . MapFileList = Options . FvMapFileList
if Options . SourceFileList :
self . SourceFileList = Options . SourceFileList
if Options . IncludeDirList :
self . IncludeDirList = Options . IncludeDirList
if Options . DecFileList :
self . DecFileList = Options . DecFileList
2018-07-05 11:40:04 +02:00
2010-03-01 00:39:39 +01:00
if Options . GuidList :
self . GuidList = Options . GuidList
if Options . LogFile :
self . LogFile = Options . LogFile
if Options . keepdatabase :
self . IsInit = False
## SetLogLevel() method
#
# Set current log level of the tool based on args
#
# @param self: The object pointer
# @param Option: The option list including log level setting
#
def SetLogLevel ( self , Option ) :
2018-03-26 22:25:43 +02:00
if Option . verbose is not None :
2010-03-01 00:39:39 +01:00
EdkLogger . SetLevel ( EdkLogger . VERBOSE )
2018-03-26 22:25:43 +02:00
elif Option . quiet is not None :
2010-03-01 00:39:39 +01:00
EdkLogger . SetLevel ( EdkLogger . QUIET )
2018-03-26 22:25:43 +02:00
elif Option . debug is not None :
2010-03-01 00:39:39 +01:00
EdkLogger . SetLevel ( Option . debug + 1 )
else :
EdkLogger . SetLevel ( EdkLogger . INFO )
## EotOptionParser() method
#
# Using standard Python module optparse to parse command line option of this tool.
#
# @param self: The object pointer
#
# @retval Opt A optparse.Values object containing the parsed options
# @retval Args Target of build command
#
def EotOptionParser ( self ) :
Parser = OptionParser ( description = self . Copyright , version = self . Version , prog = " Eot.exe " , usage = " % prog [options] " )
Parser . add_option ( " -m " , " --makefile filename " , action = " store " , type = " string " , dest = ' MakeFile ' ,
help = " Specify a makefile for the platform. " )
Parser . add_option ( " -c " , " --dsc filename " , action = " store " , type = " string " , dest = " DscFile " ,
help = " Specify a dsc file for the platform. " )
Parser . add_option ( " -f " , " --fv filename " , action = " store " , type = " string " , dest = " FvFileList " ,
help = " Specify fv file list, quoted by \" \" . " )
Parser . add_option ( " -a " , " --map filename " , action = " store " , type = " string " , dest = " MapFileList " ,
help = " Specify map file list, quoted by \" \" . " )
Parser . add_option ( " -s " , " --source files " , action = " store " , type = " string " , dest = " SourceFileList " ,
help = " Specify source file list by a file " )
Parser . add_option ( " -i " , " --include dirs " , action = " store " , type = " string " , dest = " IncludeDirList " ,
help = " Specify include dir list by a file " )
Parser . add_option ( " -e " , " --dec files " , action = " store " , type = " string " , dest = " DecFileList " ,
help = " Specify dec file list by a file " )
Parser . add_option ( " -g " , " --guid list " , action = " store " , type = " string " , dest = " GuidList " ,
help = " Specify guid file list by a file " )
Parser . add_option ( " -l " , " --log filename " , action = " store " , type = " string " , dest = " LogFile " ,
help = " Specify real execution log file " )
Parser . add_option ( " -k " , " --keepdatabase " , action = " store_true " , type = None , help = " The existing Eot database will not be cleaned except report information if this option is specified. " )
Parser . add_option ( " -q " , " --quiet " , action = " store_true " , type = None , help = " Disable all messages except FATAL ERRORS. " )
Parser . add_option ( " -v " , " --verbose " , action = " store_true " , type = None , help = " Turn on verbose output with informational messages printed, " \
" including library instances selected, final dependency expression, " \
" and warning messages, etc. " )
Parser . add_option ( " -d " , " --debug " , action = " store " , type = " int " , help = " Enable debug messages at specified level. " )
( Opt , Args ) = Parser . parse_args ( )
return ( Opt , Args )
##
#
# This acts like the main() function for the script, unless it is 'import'ed into another
# script.
#
if __name__ == ' __main__ ' :
# Initialize log system
EdkLogger . Initialize ( )
EdkLogger . IsRaiseError = False
EdkLogger . quiet ( time . strftime ( " % H: % M: % S, % b. %d % Y " , time . localtime ( ) ) + " [00:00] " + " \n " )
StartTime = time . clock ( )
2018-10-15 10:29:09 +02:00
Eot = Eot ( CommandLineOption = False ,
SourceFileList = r ' C: \ TestEot \ Source.txt ' ,
GuidList = r ' C: \ TestEot \ Guid.txt ' ,
FvFileList = r ' C: \ TestEot \ FVRECOVERY.Fv ' )
2010-03-01 00:39:39 +01:00
FinishTime = time . clock ( )
BuildDuration = time . strftime ( " % M: % S " , time . gmtime ( int ( round ( FinishTime - StartTime ) ) ) )
EdkLogger . quiet ( " \n %s [ %s ] " % ( time . strftime ( " % H: % M: % S, % b. %d % Y " , time . localtime ( ) ) , BuildDuration ) )