X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FEcc%2FCheck.py;h=ea739043e0bca88c58b52d2e5025941e938e15d5;hb=87d2afd07c822e6d5ab12bc8dc0f0bfa31bea679;hp=062120c0e51a8288934ce66ea6348611554de7e2;hpb=f8c1facf34a1f65082fa22fdbc20a6e0ab8887b4;p=mirror_edk2.git diff --git a/BaseTools/Source/Python/Ecc/Check.py b/BaseTools/Source/Python/Ecc/Check.py index 062120c0e5..ea739043e0 100644 --- a/BaseTools/Source/Python/Ecc/Check.py +++ b/BaseTools/Source/Python/Ecc/Check.py @@ -1,7 +1,7 @@ ## @file # This file is used to define checkpoints used by ECC tool # -# Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.
+# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.
# This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at @@ -41,6 +41,134 @@ class Check(object): self.DeclAndDataTypeCheck() self.FunctionLayoutCheck() self.NamingConventionCheck() + self.SmmCommParaCheck() + + def SmmCommParaCheck(self): + self.SmmCommParaCheckBufferType() + + + # Check if SMM communication function has correct parameter type + # 1. Get function calling with instance./->Communicate() interface + # and make sure the protocol instance is of type EFI_SMM_COMMUNICATION_PROTOCOL. + # 2. Find the origin of the 2nd parameter of Communicate() interface, if - + # a. it is a local buffer on stack + # report error. + # b. it is a global buffer, check the driver that holds the global buffer is of type DXE_RUNTIME_DRIVER + # report success. + # c. it is a buffer by AllocatePage/AllocatePool (may be wrapped by nested function calls), + # check the EFI_MEMORY_TYPE to be EfiRuntimeServicesCode,EfiRuntimeServicesData, + # EfiACPIMemoryNVS or EfiReservedMemoryType + # report success. + # d. it is a buffer located via EFI_SYSTEM_TABLE.ConfigurationTable (may be wrapped by nested function calls) + # report warning to indicate human code review. + # e. it is a buffer from other kind of pointers (may need to trace into nested function calls to locate), + # repeat checks in a.b.c and d. + def SmmCommParaCheckBufferType(self): + if EccGlobalData.gConfig.SmmCommParaCheckBufferType == '1' or EccGlobalData.gConfig.SmmCommParaCheckAll == '1': + EdkLogger.quiet("Checking SMM communication parameter type ...") + # Get all EFI_SMM_COMMUNICATION_PROTOCOL interface + CommApiList = [] + for IdentifierTable in EccGlobalData.gIdentifierTableList: + SqlCommand = """select ID, Name, BelongsToFile from %s + where Modifier = 'EFI_SMM_COMMUNICATION_PROTOCOL*' """ % (IdentifierTable) + RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + if RecordSet: + for Record in RecordSet: + if Record[1] not in CommApiList: + CommApiList.append(Record[1]) + # For each interface, check the second parameter + for CommApi in CommApiList: + for IdentifierTable in EccGlobalData.gIdentifierTableList: + SqlCommand = """select ID, Name, Value, BelongsToFile, StartLine from %s + where Name = '%s->Communicate' and Model = %s""" \ + % (IdentifierTable, CommApi, MODEL_IDENTIFIER_FUNCTION_CALLING) + RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + if RecordSet: + # print IdentifierTable + for Record in RecordSet: + # Get the second parameter for Communicate function + SecondPara = Record[2].split(',')[1].strip() + SecondParaIndex = None + if SecondPara.startswith('&'): + SecondPara = SecondPara[1:] + if SecondPara.endswith(']'): + SecondParaIndex = SecondPara[SecondPara.find('[') + 1:-1] + SecondPara = SecondPara[:SecondPara.find('[')] + # Get the ID + Id = Record[0] + # Get the BelongsToFile + BelongsToFile = Record[3] + # Get the source file path + SqlCommand = """select FullPath from File where ID = %s""" % BelongsToFile + NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + FullPath = NewRecordSet[0][0] + # Get the line no of function calling + StartLine = Record[4] + # Get the module type + SqlCommand = """select Value3 from INF where BelongsToFile = (select ID from File + where Path = (select Path from File where ID = %s) and Model = 1011) + and Value2 = 'MODULE_TYPE'""" % BelongsToFile + NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + ModuleType = NewRecordSet[0][0] if NewRecordSet else None + + # print BelongsToFile, FullPath, StartLine, ModuleType, SecondPara + + Value = FindPara(FullPath, SecondPara, StartLine) + # Find the value of the parameter + if Value: + if 'AllocatePage' in Value \ + or 'AllocatePool' in Value \ + or 'AllocateRuntimePool' in Value \ + or 'AllocateZeroPool' in Value: + pass + else: + if '->' in Value: + if not EccGlobalData.gException.IsException( + ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE, Value): + EccGlobalData.gDb.TblReport.Insert(ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE, + OtherMsg="Please review the buffer type" + + "is correct or not. If it is correct" + + " please add [%s] to exception list" + % Value, + BelongsToTable=IdentifierTable, + BelongsToItem=Id) + else: + if not EccGlobalData.gException.IsException( + ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE, Value): + EccGlobalData.gDb.TblReport.Insert(ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE, + OtherMsg="Please review the buffer type" + + "is correct or not. If it is correct" + + " please add [%s] to exception list" + % Value, + BelongsToTable=IdentifierTable, + BelongsToItem=Id) + + + # Not find the value of the parameter + else: + SqlCommand = """select ID, Modifier, Name, Value, Model, BelongsToFunction from %s + where Name = '%s' and StartLine < %s order by StartLine DESC""" \ + % (IdentifierTable, SecondPara, StartLine) + NewRecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) + if NewRecordSet: + Value = NewRecordSet[0][1] + if 'AllocatePage' in Value \ + or 'AllocatePool' in Value \ + or 'AllocateRuntimePool' in Value \ + or 'AllocateZeroPool' in Value: + pass + else: + if not EccGlobalData.gException.IsException( + ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE, Value): + EccGlobalData.gDb.TblReport.Insert(ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE, + OtherMsg="Please review the buffer type" + + "is correct or not. If it is correct" + + " please add [%s] to exception list" + % Value, + BelongsToTable=IdentifierTable, + BelongsToItem=Id) + else: + pass # Check UNI files def UniCheck(self): @@ -616,7 +744,7 @@ class Check(object): if Item not in LibraryClasses[List[0]]: LibraryClasses[List[0]].append(Item) - if Record[2] != 'BASE' and Record[2] not in SupModType: + if Record[2] != DT.SUP_MODULE_BASE and Record[2] not in SupModType: EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_2, OtherMsg="The Library Class '%s' does not specify its supported module types" % (List[0]), BelongsToTable='Inf', BelongsToItem=Record[0]) SqlCommand = """select A.ID, A.Value1, B.Value3 from Inf as A left join Inf as B @@ -635,7 +763,7 @@ class Check(object): for Record in RecordSet: if Record[1] in LibraryClasses: - if Record[2] not in LibraryClasses[Record[1]] and 'BASE' not in RecordDict[Record[1]]: + if Record[2] not in LibraryClasses[Record[1]] and DT.SUP_MODULE_BASE not in RecordDict[Record[1]]: if not EccGlobalData.gException.IsException(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, Record[1]): EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_INSTANCE_1, OtherMsg="The type of Library Class [%s] defined in Inf file does not match the type of the module" % (Record[1]), BelongsToTable='Inf', BelongsToItem=Record[0]) else: @@ -659,7 +787,7 @@ class Check(object): continue SqlCommand = """select Value3 from Inf where BelongsToFile = (select ID from File where lower(FullPath) = lower('%s')) - and Value2 = '%s'""" % (LibraryIns, 'LIBRARY_CLASS') + and Value2 = '%s'""" % (LibraryIns, DT.PLATFORM_COMPONENT_TYPE_LIBRARY_CLASS) RecordSet = EccGlobalData.gDb.TblInf.Exec(SqlCommand) IsFound = False for Record in RecordSet: @@ -688,8 +816,8 @@ class Check(object): EccGlobalData.gDb.TblReport.Insert(ERROR_META_DATA_FILE_CHECK_LIBRARY_NO_USE, OtherMsg="The Library Class [%s] is not used in any platform" % (Record[1]), BelongsToTable='Inf', BelongsToItem=Record[0]) SqlCommand = """ select A.ID, A.Value1, A.BelongsToFile, A.StartLine, B.StartLine from Dsc as A left join Dsc as B - where A.Model = %s and B.Model = %s and A.Scope1 = B.Scope1 and A.Scope2 = B.Scope2 and A.ID <> B.ID - and A.Value1 = B.Value1 and A.Value2 <> B.Value2 and A.BelongsToItem = -1 and B.BelongsToItem = -1 and A.StartLine <> B.StartLine and B.BelongsToFile = A.BelongsToFile""" \ + where A.Model = %s and B.Model = %s and A.Scope1 = B.Scope1 and A.Scope2 = B.Scope2 and A.ID != B.ID + and A.Value1 = B.Value1 and A.Value2 != B.Value2 and A.BelongsToItem = -1 and B.BelongsToItem = -1 and A.StartLine != B.StartLine and B.BelongsToFile = A.BelongsToFile""" \ % (MODEL_EFI_LIBRARY_CLASS, MODEL_EFI_LIBRARY_CLASS) RecordSet = EccGlobalData.gDb.TblDsc.Exec(SqlCommand) for Record in RecordSet: @@ -775,7 +903,7 @@ class Check(object): and A.Value1 = B.Value1 and A.Value2 = B.Value2 and A.Scope1 = B.Scope1 - and A.ID <> B.ID + and A.ID != B.ID and A.Model = B.Model and A.Enabled > -1 and B.Enabled > -1 @@ -927,7 +1055,7 @@ class Check(object): SqlCommand = """ select A.ID, A.Value3, A.BelongsToFile, B.BelongsToFile from %s as A, %s as B where A.Value2 = 'FILE_GUID' and B.Value2 = 'FILE_GUID' and - A.Value3 = B.Value3 and A.ID <> B.ID group by A.ID + A.Value3 = B.Value3 and A.ID != B.ID group by A.ID """ % (Table.Table, Table.Table) RecordSet = Table.Exec(SqlCommand) for Record in RecordSet: @@ -1087,7 +1215,7 @@ class Check(object): SqlCommand = """ select A.ID, A.Value1 from %s as A, %s as B where A.Model = %s and B.Model = %s - and A.Value1 like B.Value1 and A.ID <> B.ID + and A.Value1 like B.Value1 and A.ID != B.ID and A.Scope1 = B.Scope1 and A.Enabled > -1 and B.Enabled > -1 @@ -1111,8 +1239,8 @@ class Check(object): SqlCommand = """ select A.ID, A.Value1, A.Value2 from %s as A, %s as B where A.Model = %s and B.Model = %s - and A.Value2 like B.Value2 and A.ID <> B.ID - and A.Scope1 = B.Scope1 and A.Value1 <> B.Value1 + and A.Value2 like B.Value2 and A.ID != B.ID + and A.Scope1 = B.Scope1 and A.Value1 != B.Value1 group by A.ID """ % (Table.Table, Table.Table, Model, Model) RecordSet = Table.Exec(SqlCommand) @@ -1171,7 +1299,7 @@ class Check(object): RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) for Record in RecordSet: Name = Record[1].strip() - if Name != '' and Name != None: + if Name != '' and Name is not None: if Name[0] == '(': Name = Name[1:Name.find(')')] if Name.find('(') > -1: @@ -1261,6 +1389,19 @@ class Check(object): if not EccGlobalData.gException.IsException(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, Record[1]): EccGlobalData.gDb.TblReport.Insert(ERROR_NAMING_CONVENTION_CHECK_SINGLE_CHARACTER_VARIABLE, OtherMsg="The variable name [%s] does not follow the rules" % (Record[1]), BelongsToTable=FileTable, BelongsToItem=Record[0]) +def FindPara(FilePath, Para, CallingLine): + Lines = open(FilePath).readlines() + Line = '' + for Index in range(CallingLine - 1, 0, -1): + # Find the nearest statement for Para + Line = Lines[Index].strip() + if Line.startswith('%s = ' % Para): + Line = Line.strip() + return Line + break + + return '' + ## # # This acts like the main() function for the script, unless it is 'import'ed into another