mirror of https://github.com/acidanthera/audk.git
BaseTools/ECC: Add a new checkpoint
Add a new checkpoint to check if the SMM communication parameter has a correct buffer type. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Hess Chen <hesheng.chen@intel.com> Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com>
This commit is contained in:
parent
86601b7895
commit
703ef6cfd5
|
@ -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):
|
||||
|
@ -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
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## @file
|
||||
# This file is used to define class Configuration
|
||||
#
|
||||
# Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
# 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
|
||||
|
@ -256,6 +256,11 @@ class Configuration(object):
|
|||
# Check PCD whether defined the prompt, help in the DEC file and localized information in the associated UNI file.
|
||||
self.UniCheckPCDInfo = 1
|
||||
|
||||
# Check SMM communication function parameter
|
||||
self.SmmCommParaCheckAll = 0
|
||||
# Check if the EFI_SMM_COMMUNICATION_PROTOCOL parameter buffer type is Reserved / ACPI NVS or UEFI RT code/data
|
||||
self.SmmCommParaCheckBufferType = -1
|
||||
|
||||
#
|
||||
# The check points in this section are reserved
|
||||
#
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## @file
|
||||
# Standardized Error Hanlding infrastructures.
|
||||
#
|
||||
# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>
|
||||
# Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<BR>
|
||||
# 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
|
||||
|
@ -105,6 +105,8 @@ ERROR_META_DATA_FILE_CHECK_LIBRARY_NOT_DEFINED = 10022
|
|||
|
||||
ERROR_SPELLING_CHECK_ALL = 11000
|
||||
|
||||
ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE = 12001
|
||||
|
||||
gEccErrorMessage = {
|
||||
ERROR_GENERAL_CHECK_ALL : "",
|
||||
ERROR_GENERAL_CHECK_NO_TAB : "'TAB' character is not allowed in source code, please replace each 'TAB' with two spaces",
|
||||
|
@ -198,5 +200,7 @@ gEccErrorMessage = {
|
|||
ERROR_META_DATA_FILE_CHECK_FORMAT_PCD : "Wrong Pcd Format used in Module file",
|
||||
ERROR_META_DATA_FILE_CHECK_LIBRARY_NOT_DEFINED : "Not defined LibraryClass used in the Module file.",
|
||||
ERROR_SPELLING_CHECK_ALL : "",
|
||||
|
||||
ERROR_SMM_COMM_PARA_CHECK_BUFFER_TYPE : "SMM communication function may use wrong parameter type",
|
||||
}
|
||||
|
||||
|
|
|
@ -261,6 +261,13 @@ UniCheckPCDInfo = 1
|
|||
# Uncheck whether UNI file is in UTF-16 format
|
||||
GeneralCheckUni = -1
|
||||
|
||||
#
|
||||
# SMM Communicate Function Parameter Checking
|
||||
#
|
||||
SmmCommParaCheckAll = 0
|
||||
# Check if the EFI_SMM_COMMUNICATION_PROTOCOL parameter buffer type is Reserved / ACPI NVS or UEFI RT code/data
|
||||
SmmCommParaCheckBufferType = 1
|
||||
|
||||
#
|
||||
# The check points in this section are reserved
|
||||
#
|
||||
|
|
Loading…
Reference in New Issue