| 23 | # @param object: Inherited from object class |
| 24 | # |
| 25 | class Check(object): |
| 26 | def __init__(self): |
| 27 | pass |
| 28 | |
| 29 | # Check all required checkpoints |
| 30 | def Check(self): |
| 31 | self.GeneralCheck() |
| 32 | self.MetaDataFileCheck() |
| 33 | self.DoxygenCheck() |
| 34 | self.IncludeFileCheck() |
| 35 | self.PredicateExpressionCheck() |
| 36 | self.DeclAndDataTypeCheck() |
| 37 | self.FunctionLayoutCheck() |
| 38 | self.NamingConventionCheck() |
| 39 | self.SmmCommParaCheck() |
| 40 | |
| 41 | def SmmCommParaCheck(self): |
| 42 | self.SmmCommParaCheckBufferType() |
| 43 | |
| 44 | |
| 45 | # Check if SMM communication function has correct parameter type |
| 46 | # 1. Get function calling with instance./->Communicate() interface |
| 47 | # and make sure the protocol instance is of type EFI_SMM_COMMUNICATION_PROTOCOL. |
| 48 | # 2. Find the origin of the 2nd parameter of Communicate() interface, if - |
| 49 | # a. it is a local buffer on stack |
| 50 | # report error. |
| 51 | # b. it is a global buffer, check the driver that holds the global buffer is of type DXE_RUNTIME_DRIVER |
| 52 | # report success. |
| 53 | # c. it is a buffer by AllocatePage/AllocatePool (may be wrapped by nested function calls), |
| 54 | # check the EFI_MEMORY_TYPE to be EfiRuntimeServicesCode,EfiRuntimeServicesData, |
| 55 | # EfiACPIMemoryNVS or EfiReservedMemoryType |
| 56 | # report success. |
| 57 | # d. it is a buffer located via EFI_SYSTEM_TABLE.ConfigurationTable (may be wrapped by nested function calls) |
| 58 | # report warning to indicate human code review. |
| 59 | # e. it is a buffer from other kind of pointers (may need to trace into nested function calls to locate), |
| 60 | # repeat checks in a.b.c and d. |
| 61 | def SmmCommParaCheckBufferType(self): |
| 62 | if EccGlobalData.gConfig.SmmCommParaCheckBufferType == '1' or EccGlobalData.gConfig.SmmCommParaCheckAll == '1': |
| 63 | EdkLogger.quiet("Checking SMM communication parameter type ...") |
| 64 | # Get all EFI_SMM_COMMUNICATION_PROTOCOL interface |
| 65 | CommApiList = [] |
| 66 | for IdentifierTable in EccGlobalData.gIdentifierTableList: |
| 67 | SqlCommand = """select ID, Name, BelongsToFile from %s |
| 68 | where Modifier = 'EFI_SMM_COMMUNICATION_PROTOCOL*' """ % (IdentifierTable) |
| 69 | RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) |
| 70 | if RecordSet: |
| 71 | for Record in RecordSet: |
| 72 | if Record[1] not in CommApiList: |
| 73 | CommApiList.append(Record[1]) |
| 74 | # For each interface, check the second parameter |
| 75 | for CommApi in CommApiList: |
| 76 | for IdentifierTable in EccGlobalData.gIdentifierTableList: |
| 77 | SqlCommand = """select ID, Name, Value, BelongsToFile, StartLine from %s |
| 78 | where Name = '%s->Communicate' and Model = %s""" \ |
| 79 | % (IdentifierTable, CommApi, MODEL_IDENTIFIER_FUNCTION_CALLING) |
| 80 | RecordSet = EccGlobalData.gDb.TblFile.Exec(SqlCommand) |
| 81 | if RecordSet: |
| 82 | # print IdentifierTable |
no outgoing calls
no test coverage detected