diff --git a/MdePkg/Library/UefiDebugLibConOut/DebugLib.c b/MdePkg/Library/UefiDebugLibConOut/DebugLib.c index c430419c99..cf168d05cf 100644 --- a/MdePkg/Library/UefiDebugLibConOut/DebugLib.c +++ b/MdePkg/Library/UefiDebugLibConOut/DebugLib.c @@ -9,7 +9,6 @@ #include #include -#include #include #include #include @@ -27,6 +26,9 @@ // 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. @@ -85,33 +87,35 @@ 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 Console Output device - // - if ((gST != NULL) && (gST->ConOut != NULL)) { - gST->ConOut->OutputString (gST->ConOut, Buffer); + // + // Send the print string to the Console Output device + // + if ((mDebugST != NULL) && (mDebugST->ConOut != NULL)) { + mDebugST->ConOut->OutputString (mDebugST->ConOut, Buffer); + } } } @@ -205,33 +209,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 Console Output device - // - if ((gST != NULL) && (gST->ConOut != NULL)) { - gST->ConOut->OutputString (gST->ConOut, Buffer); - } + // + // Send the print string to the Console Output device + // + if ((mDebugST != NULL) && (mDebugST->ConOut != NULL)) { + mDebugST->ConOut->OutputString (mDebugST->ConOut, 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/UefiDebugLibConOut/DebugLibConstructor.c b/MdePkg/Library/UefiDebugLibConOut/DebugLibConstructor.c new file mode 100644 index 0000000000..d4fdfbab55 --- /dev/null +++ b/MdePkg/Library/UefiDebugLibConOut/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/UefiDebugLibConOut/UefiDebugLibConOut.inf b/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf index 12af4a9e98..4c279a5bf2 100644 --- a/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf +++ b/MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf @@ -3,7 +3,9 @@ # # Debug Lib that sends messages to the Console Output 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 = 5cddfaf3-e9a7-4d16-bdce-1e002df475bb 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 @@ -27,6 +30,7 @@ [Sources] DebugLib.c + DebugLibConstructor.c @@ -39,9 +43,11 @@ BaseLib PcdLib PrintLib - UefiBootServicesTableLib DebugPrintErrorLevelLib +[Guids] + gEfiEventExitBootServicesGuid ## CONSUMES + [Pcd] gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue ## SOMETIMES_CONSUMES gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask ## CONSUMES