BaseTools/Source/Python/Ecc/Check.py | 141 +++++++++++++++++++++++++++ BaseTools/Source/Python/Ecc/Configuration.py | 7 +- BaseTools/Source/Python/Ecc/EccToolError.py | 6 +- BaseTools/Source/Python/Ecc/config.ini | 7 ++ 4 files changed, 159 insertions(+), 2 deletions(-)
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: hesschen <hesheng.chen@intel.com>
---
BaseTools/Source/Python/Ecc/Check.py | 141 +++++++++++++++++++++++++++
BaseTools/Source/Python/Ecc/Configuration.py | 7 +-
BaseTools/Source/Python/Ecc/EccToolError.py | 6 +-
BaseTools/Source/Python/Ecc/config.ini | 7 ++
4 files changed, 159 insertions(+), 2 deletions(-)
diff --git a/BaseTools/Source/Python/Ecc/Check.py b/BaseTools/Source/Python/Ecc/Check.py
index 062120c..5864758 100644
--- a/BaseTools/Source/Python/Ecc/Check.py
+++ b/BaseTools/Source/Python/Ecc/Check.py
@@ -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
diff --git a/BaseTools/Source/Python/Ecc/Configuration.py b/BaseTools/Source/Python/Ecc/Configuration.py
index 5262b68..b523858 100644
--- a/BaseTools/Source/Python/Ecc/Configuration.py
+++ b/BaseTools/Source/Python/Ecc/Configuration.py
@@ -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
#
diff --git a/BaseTools/Source/Python/Ecc/EccToolError.py b/BaseTools/Source/Python/Ecc/EccToolError.py
index 1eae9d1..1d51da3 100644
--- a/BaseTools/Source/Python/Ecc/EccToolError.py
+++ b/BaseTools/Source/Python/Ecc/EccToolError.py
@@ -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",
}
diff --git a/BaseTools/Source/Python/Ecc/config.ini b/BaseTools/Source/Python/Ecc/config.ini
index e97c718..9a431bf 100644
--- a/BaseTools/Source/Python/Ecc/config.ini
+++ b/BaseTools/Source/Python/Ecc/config.ini
@@ -262,6 +262,13 @@ UniCheckPCDInfo = 1
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
#
# GotoStatementCheckAll = 0
--
2.7.2.windows.1
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Reviewed-by: Yonghong Zhu <yonghong.zhu@intel.com> Best Regards, Zhu Yonghong -----Original Message----- From: Chen, Hesheng Sent: Tuesday, April 11, 2017 4:17 PM To: edk2-devel@lists.01.org Cc: Zhu, Yonghong <yonghong.zhu@intel.com> Subject: [patch] 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: hesschen <hesheng.chen@intel.com> --- BaseTools/Source/Python/Ecc/Check.py | 141 +++++++++++++++++++++++++++ BaseTools/Source/Python/Ecc/Configuration.py | 7 +- BaseTools/Source/Python/Ecc/EccToolError.py | 6 +- BaseTools/Source/Python/Ecc/config.ini | 7 ++ 4 files changed, 159 insertions(+), 2 deletions(-) diff --git a/BaseTools/Source/Python/Ecc/Check.py b/BaseTools/Source/Python/Ecc/Check.py index 062120c..5864758 100644 --- a/BaseTools/Source/Python/Ecc/Check.py +++ b/BaseTools/Source/Python/Ecc/Check.py @@ -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 diff --git a/BaseTools/Source/Python/Ecc/Configuration.py b/BaseTools/Source/Python/Ecc/Configuration.py index 5262b68..b523858 100644 --- a/BaseTools/Source/Python/Ecc/Configuration.py +++ b/BaseTools/Source/Python/Ecc/Configuration.py @@ -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 # diff --git a/BaseTools/Source/Python/Ecc/EccToolError.py b/BaseTools/Source/Python/Ecc/EccToolError.py index 1eae9d1..1d51da3 100644 --- a/BaseTools/Source/Python/Ecc/EccToolError.py +++ b/BaseTools/Source/Python/Ecc/EccToolError.py @@ -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", } diff --git a/BaseTools/Source/Python/Ecc/config.ini b/BaseTools/Source/Python/Ecc/config.ini index e97c718..9a431bf 100644 --- a/BaseTools/Source/Python/Ecc/config.ini +++ b/BaseTools/Source/Python/Ecc/config.ini @@ -262,6 +262,13 @@ UniCheckPCDInfo = 1 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 # # GotoStatementCheckAll = 0 -- 2.7.2.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
© 2016 - 2024 Red Hat, Inc.