MdeModulePkg: Add VarCheckPcdLib NULL class library

The check will be based on PcdVarCheck binary that generated
by BaseTools.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Star Zeng <star.zeng@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18294 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Star Zeng 2015-08-25 03:10:32 +00:00 committed by lzeng14
parent 1241af9510
commit a2918326ac
5 changed files with 618 additions and 0 deletions

View File

@ -0,0 +1,65 @@
## @file
# NULL class library to register var check PCD handler.
#
# In platform *.fdf, the example build rule for the driver this library linked to.
# [Rule.Common.DXE_RUNTIME_DRIVER.VARCHECKPCD]
# FILE DRIVER = $(NAMED_GUID) {
# RAW BIN $(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/PcdVarCheck.bin
# DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
# PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
# UI STRING="$(MODULE_NAME)" Optional
# VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
# }
#
# or
#
# [Rule.Common.DXE_SMM_DRIVER.VARCHECKPCD]
# FILE SMM = $(NAMED_GUID) {
# RAW BIN $(WORKSPACE)/$(OUTPUT_DIRECTORY)/$(TARGET)_$(TOOL_CHAIN_TAG)/FV/PcdVarCheck.bin
# DXE_DEPEX DXE_DEPEX Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
# PE32 PE32 $(INF_OUTPUT)/$(MODULE_NAME).efi
# UI STRING="$(MODULE_NAME)" Optional
# VERSION STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
# }
#
# In platform *.dsc, also need add one line below to enable PcdVarCheck.bin generation by BaseTools.
# PCD_VAR_CHECK_GENERATION = TRUE
#
# Copyright (c) 2015, 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
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = VarCheckPcdLib
MODULE_UNI_FILE = VarCheckPcdLib.uni
FILE_GUID = D4FA5311-5F1F-4B1E-9AC3-90C4DFC029F1
MODULE_TYPE = DXE_RUNTIME_DRIVER
VERSION_STRING = 1.0
LIBRARY_CLASS = NULL|DXE_RUNTIME_DRIVER DXE_SMM_DRIVER
CONSTRUCTOR = VarCheckPcdLibNullClassConstructor
[Sources]
VarCheckPcdLibNullClass.c
VarCheckPcdStructure.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
BaseLib
DebugLib
BaseMemoryLib
DxeServicesLib
MemoryAllocationLib
VarCheckLib

Binary file not shown.

View File

@ -0,0 +1,474 @@
/** @file
Var Check PCD handler.
Copyright (c) 2015, 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
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Library/VarCheckLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DxeServicesLib.h>
#include "VarCheckPcdStructure.h"
//#define DUMP_VAR_CHECK_PCD
GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 mVarCheckPcdHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
/**
Dump some hexadecimal data.
@param[in] Indent How many spaces to indent the output.
@param[in] Offset The offset of the dump.
@param[in] DataSize The size in bytes of UserData.
@param[in] UserData The data to dump.
**/
VOID
VarCheckPcdInternalDumpHex (
IN UINTN Indent,
IN UINTN Offset,
IN UINTN DataSize,
IN VOID *UserData
)
{
UINT8 *Data;
CHAR8 Val[50];
CHAR8 Str[20];
UINT8 TempByte;
UINTN Size;
UINTN Index;
Data = UserData;
while (DataSize != 0) {
Size = 16;
if (Size > DataSize) {
Size = DataSize;
}
for (Index = 0; Index < Size; Index += 1) {
TempByte = Data[Index];
Val[Index * 3 + 0] = mVarCheckPcdHex[TempByte >> 4];
Val[Index * 3 + 1] = mVarCheckPcdHex[TempByte & 0xF];
Val[Index * 3 + 2] = (CHAR8) ((Index == 7) ? '-' : ' ');
Str[Index] = (CHAR8) ((TempByte < ' ' || TempByte > 'z') ? '.' : TempByte);
}
Val[Index * 3] = 0;
Str[Index] = 0;
DEBUG ((EFI_D_INFO, "%*a%08X: %-48a *%a*\r\n", Indent, "", Offset, Val, Str));
Data += Size;
Offset += Size;
DataSize -= Size;
}
}
/**
Var Check Pcd ValidData.
@param[in] PcdValidData Pointer to Pcd ValidData
@param[in] Data Data pointer.
@param[in] DataSize Size of Data to set.
@retval TRUE Check pass
@retval FALSE Check fail.
**/
BOOLEAN
VarCheckPcdValidData (
IN VAR_CHECK_PCD_VALID_DATA_HEADER *PcdValidData,
IN VOID *Data,
IN UINTN DataSize
)
{
UINT64 OneData;
UINT64 Minimum;
UINT64 Maximum;
UINT64 OneValue;
UINT8 *Ptr;
OneData = 0;
CopyMem (&OneData, (UINT8 *) Data + PcdValidData->VarOffset, PcdValidData->StorageWidth);
switch (PcdValidData->Type) {
case VarCheckPcdValidList:
Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_LIST *) PcdValidData + 1);
while ((UINTN) Ptr < (UINTN) PcdValidData + PcdValidData->Length) {
OneValue = 0;
CopyMem (&OneValue, Ptr, PcdValidData->StorageWidth);
if (OneData == OneValue) {
//
// Match
//
break;
}
Ptr += PcdValidData->StorageWidth;
}
if ((UINTN) Ptr >= ((UINTN) PcdValidData + PcdValidData->Length)) {
//
// No match
//
DEBUG ((EFI_D_INFO, "VarCheckPcdValidData fail: ValidList mismatch (0x%lx)\n", OneData));
DEBUG_CODE (VarCheckPcdInternalDumpHex (2, 0, PcdValidData->Length, (UINT8 *) PcdValidData););
return FALSE;
}
break;
case VarCheckPcdValidRange:
Minimum = 0;
Maximum = 0;
Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_RANGE *) PcdValidData + 1);
while ((UINTN) Ptr < (UINTN) PcdValidData + PcdValidData->Length) {
CopyMem (&Minimum, Ptr, PcdValidData->StorageWidth);
Ptr += PcdValidData->StorageWidth;
CopyMem (&Maximum, Ptr, PcdValidData->StorageWidth);
Ptr += PcdValidData->StorageWidth;
if ((OneData >= Minimum) && (OneData <= Maximum)) {
return TRUE;
}
}
DEBUG ((EFI_D_INFO, "VarCheckPcdValidData fail: ValidRange mismatch (0x%lx)\n", OneData));
DEBUG_CODE (VarCheckPcdInternalDumpHex (2, 0, PcdValidData->Length, (UINT8 *) PcdValidData););
return FALSE;
break;
default:
ASSERT (FALSE);
break;
}
return TRUE;
}
VAR_CHECK_PCD_VARIABLE_HEADER *mVarCheckPcdBin = NULL;
UINTN mVarCheckPcdBinSize = 0;
/**
SetVariable check handler PCD.
@param[in] VariableName Name of Variable to set.
@param[in] VendorGuid Variable vendor GUID.
@param[in] Attributes Attribute value of the variable.
@param[in] DataSize Size of Data to set.
@param[in] Data Data pointer.
@retval EFI_SUCCESS The SetVariable check result was success.
@retval EFI_SECURITY_VIOLATION Check fail.
**/
EFI_STATUS
EFIAPI
SetVariableCheckHandlerPcd (
IN CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
IN UINT32 Attributes,
IN UINTN DataSize,
IN VOID *Data
)
{
VAR_CHECK_PCD_VARIABLE_HEADER *PcdVariable;
VAR_CHECK_PCD_VALID_DATA_HEADER *PcdValidData;
if (mVarCheckPcdBin == NULL) {
return EFI_SUCCESS;
}
if ((((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) && (DataSize == 0)) || (Attributes == 0)) {
//
// Do not check delete variable.
//
return EFI_SUCCESS;
}
//
// For Pcd Variable header align.
//
PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (mVarCheckPcdBin);
while ((UINTN) PcdVariable < ((UINTN) mVarCheckPcdBin + mVarCheckPcdBinSize)) {
if ((StrCmp ((CHAR16 *) (PcdVariable + 1), VariableName) == 0) &&
(CompareGuid (&PcdVariable->Guid, VendorGuid))) {
//
// Found the Pcd Variable that could be used to do check.
//
DEBUG ((EFI_D_INFO, "VarCheckPcdVariable - %s:%g with Attributes = 0x%08x Size = 0x%x\n", VariableName, VendorGuid, Attributes, DataSize));
if ((PcdVariable->Attributes != 0) && PcdVariable->Attributes != Attributes) {
DEBUG ((EFI_D_INFO, "VarCheckPcdVariable fail for Attributes - 0x%08x\n", PcdVariable->Attributes));
return EFI_SECURITY_VIOLATION;
}
if (DataSize == 0) {
DEBUG ((EFI_D_INFO, "VarCheckPcdVariable - CHECK PASS with DataSize == 0 !\n"));
return EFI_SUCCESS;
}
//
// Do the check.
// For Pcd ValidData header align.
//
PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->HeaderLength));
while ((UINTN) PcdValidData < ((UINTN) PcdVariable + PcdVariable->Length)) {
if (((UINTN) PcdValidData->VarOffset + PcdValidData->StorageWidth) <= DataSize) {
if (!VarCheckPcdValidData (PcdValidData, Data, DataSize)) {
return EFI_SECURITY_VIOLATION;
}
}
//
// For Pcd ValidData header align.
//
PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdValidData + PcdValidData->Length));
}
DEBUG ((EFI_D_INFO, "VarCheckPcdVariable - ALL CHECK PASS!\n"));
return EFI_SUCCESS;
}
//
// For Pcd Variable header align.
//
PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->Length));
}
// Not found, so pass.
return EFI_SUCCESS;
}
#ifdef DUMP_VAR_CHECK_PCD
/**
Dump Pcd ValidData.
@param[in] PcdValidData Pointer to Pcd ValidData.
**/
VOID
DumpPcdValidData (
IN VAR_CHECK_PCD_VALID_DATA_HEADER *PcdValidData
)
{
UINT64 Minimum;
UINT64 Maximum;
UINT64 OneValue;
UINT8 *Ptr;
DEBUG ((EFI_D_INFO, " VAR_CHECK_PCD_VALID_DATA_HEADER\n"));
DEBUG ((EFI_D_INFO, " Type - 0x%02x\n", PcdValidData->Type));
DEBUG ((EFI_D_INFO, " Length - 0x%02x\n", PcdValidData->Length));
DEBUG ((EFI_D_INFO, " VarOffset - 0x%04x\n", PcdValidData->VarOffset));
DEBUG ((EFI_D_INFO, " StorageWidth - 0x%02x\n", PcdValidData->StorageWidth));
switch (PcdValidData->Type) {
case VarCheckPcdValidList:
Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_LIST *) PcdValidData + 1);
while ((UINTN) Ptr < ((UINTN) PcdValidData + PcdValidData->Length)) {
OneValue = 0;
CopyMem (&OneValue, Ptr, PcdValidData->StorageWidth);
switch (PcdValidData->StorageWidth) {
case sizeof (UINT8):
DEBUG ((EFI_D_INFO, " ValidList - 0x%02x\n", OneValue));
break;
case sizeof (UINT16):
DEBUG ((EFI_D_INFO, " ValidList - 0x%04x\n", OneValue));
break;
case sizeof (UINT32):
DEBUG ((EFI_D_INFO, " ValidList - 0x%08x\n", OneValue));
break;
case sizeof (UINT64):
DEBUG ((EFI_D_INFO, " ValidList - 0x%016lx\n", OneValue));
break;
default:
ASSERT (FALSE);
break;
}
Ptr += PcdValidData->StorageWidth;
}
break;
case VarCheckPcdValidRange:
Minimum = 0;
Maximum = 0;
Ptr = (UINT8 *) ((VAR_CHECK_PCD_VALID_RANGE *) PcdValidData + 1);
while ((UINTN) Ptr < (UINTN) PcdValidData + PcdValidData->Length) {
CopyMem (&Minimum, Ptr, PcdValidData->StorageWidth);
Ptr += PcdValidData->StorageWidth;
CopyMem (&Maximum, Ptr, PcdValidData->StorageWidth);
Ptr += PcdValidData->StorageWidth;
switch (PcdValidData->StorageWidth) {
case sizeof (UINT8):
DEBUG ((EFI_D_INFO, " Minimum - 0x%02x\n", Minimum));
DEBUG ((EFI_D_INFO, " Maximum - 0x%02x\n", Maximum));
break;
case sizeof (UINT16):
DEBUG ((EFI_D_INFO, " Minimum - 0x%04x\n", Minimum));
DEBUG ((EFI_D_INFO, " Maximum - 0x%04x\n", Maximum));
break;
case sizeof (UINT32):
DEBUG ((EFI_D_INFO, " Minimum - 0x%08x\n", Minimum));
DEBUG ((EFI_D_INFO, " Maximum - 0x%08x\n", Maximum));
break;
case sizeof (UINT64):
DEBUG ((EFI_D_INFO, " Minimum - 0x%016lx\n", Minimum));
DEBUG ((EFI_D_INFO, " Maximum - 0x%016lx\n", Maximum));
break;
default:
ASSERT (FALSE);
break;
}
}
break;
default:
ASSERT (FALSE);
break;
}
}
/**
Dump Pcd Variable.
@param[in] PcdVariable Pointer to Pcd Variable.
**/
VOID
DumpPcdVariable (
IN VAR_CHECK_PCD_VARIABLE_HEADER *PcdVariable
)
{
VAR_CHECK_PCD_VALID_DATA_HEADER *PcdValidData;
DEBUG ((EFI_D_INFO, "VAR_CHECK_PCD_VARIABLE_HEADER\n"));
DEBUG ((EFI_D_INFO, " Revision - 0x%04x\n", PcdVariable->Revision));
DEBUG ((EFI_D_INFO, " HeaderLength - 0x%04x\n", PcdVariable->HeaderLength));
DEBUG ((EFI_D_INFO, " Length - 0x%08x\n", PcdVariable->Length));
DEBUG ((EFI_D_INFO, " Type - 0x%02x\n", PcdVariable->Type));
DEBUG ((EFI_D_INFO, " Attributes - 0x%08x\n", PcdVariable->Attributes));
DEBUG ((EFI_D_INFO, " Guid - %g\n", &PcdVariable->Guid));
DEBUG ((EFI_D_INFO, " Name - %s\n", PcdVariable + 1));
//
// For Pcd ValidData header align.
//
PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->HeaderLength));
while ((UINTN) PcdValidData < ((UINTN) PcdVariable + PcdVariable->Length)) {
//
// Dump Pcd ValidData related to the Pcd Variable.
//
DumpPcdValidData (PcdValidData);
//
// For Pcd ValidData header align.
//
PcdValidData = (VAR_CHECK_PCD_VALID_DATA_HEADER *) HEADER_ALIGN (((UINTN) PcdValidData + PcdValidData->Length));
}
}
/**
Dump Var Check PCD.
@param[in] VarCheckPcdBin Pointer to VarCheckPcdBin.
@param[in] VarCheckPcdBinSize VarCheckPcdBin size.
**/
VOID
DumpVarCheckPcd (
IN VOID *VarCheckPcdBin,
IN UINTN VarCheckPcdBinSize
)
{
VAR_CHECK_PCD_VARIABLE_HEADER *PcdVariable;
DEBUG ((EFI_D_INFO, "DumpVarCheckPcd\n"));
//
// For Pcd Variable header align.
//
PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (VarCheckPcdBin);
while ((UINTN) PcdVariable < ((UINTN) VarCheckPcdBin + VarCheckPcdBinSize)) {
DumpPcdVariable (PcdVariable);
//
// For Pcd Variable header align.
//
PcdVariable = (VAR_CHECK_PCD_VARIABLE_HEADER *) HEADER_ALIGN (((UINTN) PcdVariable + PcdVariable->Length));
}
}
#endif
/**
Locate VarCheckPcdBin.
**/
VOID
EFIAPI
LocateVarCheckPcdBin (
VOID
)
{
EFI_STATUS Status;
VAR_CHECK_PCD_VARIABLE_HEADER *VarCheckPcdBin;
UINTN VarCheckPcdBinSize;
//
// Search the VarCheckPcdBin from the first RAW section of current FFS.
//
Status = GetSectionFromFfs (
EFI_SECTION_RAW,
0,
(VOID **) &VarCheckPcdBin,
&VarCheckPcdBinSize
);
if (!EFI_ERROR (Status)) {
//
// AllocateRuntimeZeroPool () from MemoryAllocateLib is used for runtime access
// in SetVariable check handler.
//
mVarCheckPcdBin = AllocateRuntimeCopyPool (VarCheckPcdBinSize, VarCheckPcdBin);
ASSERT (mVarCheckPcdBin != NULL);
mVarCheckPcdBinSize = VarCheckPcdBinSize;
FreePool (VarCheckPcdBin);
DEBUG ((EFI_D_INFO, "VarCheckPcdBin - at 0x%x size = 0x%x\n", mVarCheckPcdBin, mVarCheckPcdBinSize));
#ifdef DUMP_VAR_CHECK_PCD
DEBUG_CODE (
DumpVarCheckPcd (mVarCheckPcdBin, mVarCheckPcdBinSize);
);
#endif
} else {
DEBUG ((EFI_D_INFO, "[VarCheckPcd] No VarCheckPcdBin found at the first RAW section\n"));
}
}
/**
Constructor function of VarCheckPcdLib to register var check PCD handler.
@param[in] ImageHandle The firmware allocated handle for the EFI image.
@param[in] SystemTable A pointer to the EFI System Table.
@retval EFI_SUCCESS The constructor executed correctly.
**/
EFI_STATUS
EFIAPI
VarCheckPcdLibNullClassConstructor (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
LocateVarCheckPcdBin ();
VarCheckLibRegisterAddressPointer ((VOID **) &mVarCheckPcdBin);
VarCheckLibRegisterSetVariableCheckHandler (SetVariableCheckHandlerPcd);
return EFI_SUCCESS;
}

View File

@ -0,0 +1,76 @@
/** @file
Internal structure for Var Check Pcd.
Copyright (c) 2015, 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
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#ifndef _VAR_CHECK_STRUCTURE_H_
#define _VAR_CHECK_STRUCTURE_H_
//
// Alignment for PCD Variable and check data header.
//
#define HEADER_ALIGNMENT 4
#define HEADER_ALIGN(Header) (((UINTN) (Header) + HEADER_ALIGNMENT - 1) & (~(HEADER_ALIGNMENT - 1)))
#pragma pack (1)
#define VAR_CHECK_PCD_REVISION 0x0001
typedef enum {
VarCheckPcdVariableHeader,
VarCheckPcdValidList,
VarCheckPcdValidRange,
VarCheckPcdCheckTypeMax,
} VAR_CHECK_PCD_CHECK_TYPE;
typedef struct {
UINT16 Revision;
UINT16 HeaderLength;
UINT32 Length; // Length include this header
UINT8 Type;
UINT8 Reserved[3];
UINT32 Attributes;
EFI_GUID Guid;
//CHAR16 Name[];
} VAR_CHECK_PCD_VARIABLE_HEADER;
typedef struct {
UINT8 Type;
UINT8 Length; // Length include this header
UINT16 VarOffset;
UINT8 StorageWidth;
} VAR_CHECK_PCD_VALID_DATA_HEADER;
typedef struct {
UINT8 Type;
UINT8 Length; // Length include this header
UINT16 VarOffset;
UINT8 StorageWidth;
//UINTx Data[]; // x = UINT8/UINT16/UINT32/UINT64;
} VAR_CHECK_PCD_VALID_LIST;
//typedef struct {
// UINTx Minimum; // x = UINT8/UINT16/UINT32/UINT64
// UINTx Maximum; // x = UINT8/UINT16/UINT32/UINT64
//} VAR_CHECK_PCD_VALID_RANGE_DATA;
typedef struct {
UINT8 Type;
UINT8 Length; // Length include this header
UINT16 VarOffset;
UINT8 StorageWidth;
// VAR_CHECK_PCD_VALID_RANGE_DATA ValidRange[];
} VAR_CHECK_PCD_VALID_RANGE;
#pragma pack ()
#endif

View File

@ -281,6 +281,7 @@
MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf
MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf
MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf
MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf
@ -377,6 +378,7 @@
<LibraryClasses>
NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
NULL|MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf
NULL|MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf
}
MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
@ -387,6 +389,7 @@
<LibraryClasses>
NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf
NULL|MdeModulePkg/Library/VarCheckHiiLib/VarCheckHiiLib.inf
NULL|MdeModulePkg/Library/VarCheckPcdLib/VarCheckPcdLib.inf
}
MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmmRuntimeDxe.inf
MdeModulePkg/Library/SmmReportStatusCodeLib/SmmReportStatusCodeLib.inf