diff --git a/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c b/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c index 29f93cf3e3..40eb697e7e 100644 --- a/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c +++ b/MdePkg/Library/UefiDebugLibStdErr/DebugLib.c @@ -10,7 +10,6 @@ #include #include -#include #include #include #include @@ -29,6 +28,8 @@ // VA_LIST mVaListNull; +extern BOOLEAN mPostEBS; +extern EFI_SYSTEM_TABLE *mDebugST; /** Prints a debug message to the debug output device if the specified error level is enabled. @@ -88,32 +89,34 @@ DebugPrintMarker ( { CHAR16 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; - // - // If Format is NULL, then ASSERT(). - // - ASSERT (Format != NULL); + if (!mPostEBS) { + // + // If Format is NULL, then ASSERT(). + // + ASSERT (Format != NULL); - // - // Check driver debug mask value and global mask - // - if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) { - return; - } + // + // Check driver debug mask value and global mask + // + if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) { + return; + } - // - // Convert the DEBUG() message to a Unicode String - // - if (BaseListMarker == NULL) { - UnicodeVSPrintAsciiFormat (Buffer, MAX_DEBUG_MESSAGE_LENGTH, Format, VaListMarker); - } else { - UnicodeBSPrintAsciiFormat (Buffer, MAX_DEBUG_MESSAGE_LENGTH, Format, BaseListMarker); - } + // + // Convert the DEBUG() message to a Unicode String + // + if (BaseListMarker == NULL) { + UnicodeVSPrintAsciiFormat (Buffer, MAX_DEBUG_MESSAGE_LENGTH, Format, VaListMarker); + } else { + UnicodeBSPrintAsciiFormat (Buffer, MAX_DEBUG_MESSAGE_LENGTH, Format, BaseListMarker); + } - // - // Send the print string to the Standard Error device - // - if ((gST != NULL) && (gST->StdErr != NULL)) { - gST->StdErr->OutputString (gST->StdErr, Buffer); + // + // Send the print string to the Standard Error device + // + if ((mDebugST != NULL) && (mDebugST->StdErr != NULL)) { + mDebugST->StdErr->OutputString (mDebugST->StdErr, Buffer); + } } } @@ -207,33 +210,35 @@ DebugAssert ( { CHAR16 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; - // - // Generate the ASSERT() message in Unicode format - // - UnicodeSPrintAsciiFormat ( - Buffer, - sizeof (Buffer), - "ASSERT [%a] %a(%d): %a\n", - gEfiCallerBaseName, - FileName, - LineNumber, - Description - ); + if (!mPostEBS) { + // + // Generate the ASSERT() message in Unicode format + // + UnicodeSPrintAsciiFormat ( + Buffer, + sizeof (Buffer), + "ASSERT [%a] %a(%d): %a\n", + gEfiCallerBaseName, + FileName, + LineNumber, + Description + ); - // - // Send the print string to the Standard Error device - // - if ((gST != NULL) && (gST->StdErr != NULL)) { - gST->StdErr->OutputString (gST->StdErr, Buffer); - } + // + // Send the print string to the Standard Error device + // + if ((mDebugST != NULL) && (mDebugST->StdErr != NULL)) { + mDebugST->StdErr->OutputString (mDebugST->StdErr, Buffer); + } - // - // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings - // - if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) { - CpuBreakpoint (); - } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) { - CpuDeadLoop (); + // + // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings + // + if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) { + CpuBreakpoint (); + } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) { + CpuDeadLoop (); + } } } diff --git a/MdePkg/Library/UefiDebugLibStdErr/DebugLibConstructor.c b/MdePkg/Library/UefiDebugLibStdErr/DebugLibConstructor.c new file mode 100644 index 0000000000..d4fdfbab55 --- /dev/null +++ b/MdePkg/Library/UefiDebugLibStdErr/DebugLibConstructor.c @@ -0,0 +1,77 @@ +/** @file + UEFI Dxe DebugLib constructor that prevent some debug service after ExitBootServices event, + because some pointer is nulled at that phase. + + Copyright (c) 2018, Microsoft Corporation + Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + +#include +#include +#include + +// +// BOOLEAN value to indicate if it is at the post ExitBootServices pahse +// +BOOLEAN mPostEBS = FALSE; + +EFI_EVENT mExitBootServicesEvent; + +// +// Pointer to SystemTable +// This library instance may have a cycle consume with UefiBootServicesTableLib +// because of the constructors. +// +EFI_SYSTEM_TABLE *mDebugST; + +/** + This routine sets the mPostEBS for exit boot servies true + to prevent DebugPort protocol dereferences when the pointer is nulled. + + @param Event Event whose notification function is being invoked. + @param Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +ExitBootServicesCallback ( + EFI_EVENT Event, + VOID* Context + ) +{ + mPostEBS = TRUE; + return; +} + +/** + The constructor gets the pointers to the system table. + And create a event to indicate it is after ExitBootServices. + + @param ImageHandle The firmware allocated handle for the EFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS. + +**/ +EFI_STATUS +EFIAPI +DxeDebugLibConstructor( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + mDebugST = SystemTable; + + SystemTable->BootServices->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + ExitBootServicesCallback, + NULL, + &gEfiEventExitBootServicesGuid, + &mExitBootServicesEvent + ); + + return EFI_SUCCESS; +} diff --git a/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf b/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf index 865cc98753..deaa3427f6 100644 --- a/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf +++ b/MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf @@ -3,7 +3,9 @@ # # Debug Lib that sends messages to the the Standard Error Device in the EFI System Table. # -# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.
+# Copyright (c) 2018, Microsoft Corporation +# +# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -17,8 +19,9 @@ FILE_GUID = b57a1df6-ffdb-4247-a3df-3a562176751a MODULE_TYPE = UEFI_DRIVER VERSION_STRING = 1.0 - LIBRARY_CLASS = DebugLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER + LIBRARY_CLASS = DebugLib|DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER UEFI_APPLICATION UEFI_DRIVER + CONSTRUCTOR = DxeDebugLibConstructor # # VALID_ARCHITECTURES = IA32 X64 EBC @@ -26,6 +29,7 @@ [Sources] DebugLib.c + DebugLibConstructor.c [Packages] @@ -37,9 +41,11 @@ BaseLib PcdLib PrintLib - UefiBootServicesTableLib DebugPrintErrorLevelLib +[Guids] + gEfiEventExitBootServicesGuid ## CONSUMES + [Pcd] gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue ## SOMETIMES_CONSUMES gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask ## CONSUMES