diff options
Diffstat (limited to 'SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug')
8 files changed, 602 insertions, 602 deletions
diff --git a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.nasm b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.nasm index 9442d3adc5..3ef8b4d804 100644 --- a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.nasm +++ b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.nasm @@ -1,22 +1,22 @@ -;------------------------------------------------------------------------------
-;
-; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
-; SPDX-License-Identifier: BSD-2-Clause-Patent
-;
-; Module Name:
-;
-; IntHandler.nasm
-;
-; Abstract:
-;
-; Assembly interrupt handler function.
-;
-;------------------------------------------------------------------------------
-
-global ASM_PFX(AsmInterruptHandle)
-
-SECTION .text
-ASM_PFX(AsmInterruptHandle):
- cli
- mov al, 1
- iretd
+;------------------------------------------------------------------------------ +; +; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; IntHandler.nasm +; +; Abstract: +; +; Assembly interrupt handler function. +; +;------------------------------------------------------------------------------ + +global ASM_PFX(AsmInterruptHandle) + +SECTION .text +ASM_PFX(AsmInterruptHandle): + cli + mov al, 1 + iretd diff --git a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandlerFuncs.c b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandlerFuncs.c index 3e6db0db86..a0795b0751 100644 --- a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandlerFuncs.c +++ b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandlerFuncs.c @@ -1,93 +1,93 @@ -/** @file
- Ia32 arch functions to access IDT vector.
-
- Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <PeCoffExtraActionLib.h>
-
-/**
- Read IDT entry to check if IDT entries are setup by Debug Agent.
-
- @param[in] IdtDescriptor Pointer to IDT Descriptor.
- @param[in] InterruptType Interrupt type.
-
- @retval TRUE IDT entries were setup by Debug Agent.
- @retval FALSE IDT entries were not setup by Debug Agent.
-
-**/
-BOOLEAN
-CheckDebugAgentHandler (
- IN IA32_DESCRIPTOR *IdtDescriptor,
- IN UINTN InterruptType
- )
-{
- IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
- UINTN InterruptHandler;
-
- IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base;
- if (IdtEntry == NULL) {
- return FALSE;
- }
-
- InterruptHandler = IdtEntry[InterruptType].Bits.OffsetLow +
- (IdtEntry[InterruptType].Bits.OffsetHigh << 16);
- if ((InterruptHandler >= sizeof (UINT32)) && (*(UINT32 *)(InterruptHandler - sizeof (UINT32)) == AGENT_HANDLER_SIGNATURE)) {
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-/**
- Save IDT entry for INT1 and update it.
-
- @param[in] IdtDescriptor Pointer to IDT Descriptor.
- @param[out] SavedIdtEntry Original IDT entry returned.
-
-**/
-VOID
-SaveAndUpdateIdtEntry1 (
- IN IA32_DESCRIPTOR *IdtDescriptor,
- OUT IA32_IDT_GATE_DESCRIPTOR *SavedIdtEntry
- )
-{
- IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
- UINT16 CodeSegment;
- UINTN InterruptHandler;
-
- IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base;
- CopyMem (SavedIdtEntry, &IdtEntry[1], sizeof (IA32_IDT_GATE_DESCRIPTOR));
-
- //
- // Use current CS as the segment selector of interrupt gate in IDT
- //
- CodeSegment = AsmReadCs ();
-
- InterruptHandler = (UINTN)&AsmInterruptHandle;
- IdtEntry[1].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
- IdtEntry[1].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
- IdtEntry[1].Bits.Selector = CodeSegment;
- IdtEntry[1].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
-}
-
-/**
- Restore IDT entry for INT1.
-
- @param[in] IdtDescriptor Pointer to IDT Descriptor.
- @param[in] RestoredIdtEntry IDT entry to be restored.
-
-**/
-VOID
-RestoreIdtEntry1 (
- IN IA32_DESCRIPTOR *IdtDescriptor,
- IN IA32_IDT_GATE_DESCRIPTOR *RestoredIdtEntry
- )
-{
- IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
-
- IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base;
- CopyMem (&IdtEntry[1], RestoredIdtEntry, sizeof (IA32_IDT_GATE_DESCRIPTOR));
-}
+/** @file + Ia32 arch functions to access IDT vector. + + Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <PeCoffExtraActionLib.h> + +/** + Read IDT entry to check if IDT entries are setup by Debug Agent. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[in] InterruptType Interrupt type. + + @retval TRUE IDT entries were setup by Debug Agent. + @retval FALSE IDT entries were not setup by Debug Agent. + +**/ +BOOLEAN +CheckDebugAgentHandler ( + IN IA32_DESCRIPTOR *IdtDescriptor, + IN UINTN InterruptType + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + UINTN InterruptHandler; + + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base; + if (IdtEntry == NULL) { + return FALSE; + } + + InterruptHandler = IdtEntry[InterruptType].Bits.OffsetLow + + (IdtEntry[InterruptType].Bits.OffsetHigh << 16); + if ((InterruptHandler >= sizeof (UINT32)) && (*(UINT32 *)(InterruptHandler - sizeof (UINT32)) == AGENT_HANDLER_SIGNATURE)) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Save IDT entry for INT1 and update it. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[out] SavedIdtEntry Original IDT entry returned. + +**/ +VOID +SaveAndUpdateIdtEntry1 ( + IN IA32_DESCRIPTOR *IdtDescriptor, + OUT IA32_IDT_GATE_DESCRIPTOR *SavedIdtEntry + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + UINT16 CodeSegment; + UINTN InterruptHandler; + + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base; + CopyMem (SavedIdtEntry, &IdtEntry[1], sizeof (IA32_IDT_GATE_DESCRIPTOR)); + + // + // Use current CS as the segment selector of interrupt gate in IDT + // + CodeSegment = AsmReadCs (); + + InterruptHandler = (UINTN)&AsmInterruptHandle; + IdtEntry[1].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; + IdtEntry[1].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16); + IdtEntry[1].Bits.Selector = CodeSegment; + IdtEntry[1].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; +} + +/** + Restore IDT entry for INT1. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[in] RestoredIdtEntry IDT entry to be restored. + +**/ +VOID +RestoreIdtEntry1 ( + IN IA32_DESCRIPTOR *IdtDescriptor, + IN IA32_IDT_GATE_DESCRIPTOR *RestoredIdtEntry + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base; + CopyMem (&IdtEntry[1], RestoredIdtEntry, sizeof (IA32_IDT_GATE_DESCRIPTOR)); +} diff --git a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c index 2c80f7e22d..755de384d3 100644 --- a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c +++ b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c @@ -1,231 +1,231 @@ -/** @file
- PE/Coff Extra Action library instances.
-
- Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <PeCoffExtraActionLib.h>
-
-/**
- Check if the hardware breakpoint in Drx is enabled by checking the Lx and Gx bit in Dr7.
-
- It assumes that DebugAgent will set both Lx and Gx bit when setting up the hardware breakpoint.
-
-
- @param RegisterIndex Index of Dr register. The value range is from 0 to 3.
- @param Dr7 Value of Dr7 register.
-
- @return TRUE The hardware breakpoint specified in the Drx is enabled.
- @return FALSE The hardware breakpoint specified in the Drx is disabled.
-
-**/
-BOOLEAN
-IsDrxEnabled (
- IN UINT8 RegisterIndex,
- IN UINTN Dr7
- )
-{
- return (BOOLEAN)(((Dr7 >> (RegisterIndex * 2)) & (BIT0 | BIT1)) == (BIT0 | BIT1));
-}
-
-/**
- Common routine to report the PE/COFF image loading/relocating or unloading event.
-
- If ImageContext is NULL, then ASSERT().
-
- @param ImageContext Pointer to the image context structure that describes the
- PE/COFF image.
- @param Signature IMAGE_LOAD_SIGNATURE or IMAGE_UNLOAD_SIGNATURE.
-
-**/
-VOID
-PeCoffLoaderExtraActionCommon (
- IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
- IN UINTN Signature
- )
-{
- BOOLEAN InterruptState;
- UINTN Dr0;
- UINTN Dr1;
- UINTN Dr2;
- UINTN Dr3;
- UINTN Dr7;
- UINTN Cr4;
- UINTN NewDr7;
- UINT8 LoadImageMethod;
- UINT8 DebugAgentStatus;
- IA32_DESCRIPTOR IdtDescriptor;
- IA32_IDT_GATE_DESCRIPTOR OriginalIdtEntry;
- BOOLEAN IdtEntryHooked;
- UINT32 RegEdx;
-
- ASSERT (ImageContext != NULL);
-
- if (ImageContext->PdbPointer != NULL) {
- DEBUG ((DEBUG_ERROR, " PDB = %a\n", ImageContext->PdbPointer));
- }
-
- //
- // Disable interrupts and save the current interrupt state
- //
- InterruptState = SaveAndDisableInterrupts ();
-
- IdtEntryHooked = FALSE;
- LoadImageMethod = PcdGet8 (PcdDebugLoadImageMethod);
- if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) {
- //
- // If the CPU does not support Debug Extensions(CPUID:01 EDX:BIT2)
- // then force use of DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3
- //
- AsmCpuid (1, NULL, NULL, NULL, &RegEdx);
- if ((RegEdx & BIT2) == 0) {
- LoadImageMethod = DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3;
- }
- }
-
- AsmReadIdtr (&IdtDescriptor);
- if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) {
- if (!CheckDebugAgentHandler (&IdtDescriptor, SOFT_INT_VECTOR_NUM)) {
- //
- // Do not trigger INT3 if Debug Agent did not setup IDT entries.
- //
- return;
- }
- } else {
- if (!CheckDebugAgentHandler (&IdtDescriptor, IO_HW_BREAKPOINT_VECTOR_NUM)) {
- //
- // Save and update IDT entry for INT1
- //
- SaveAndUpdateIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry);
- IdtEntryHooked = TRUE;
- }
- }
-
- //
- // Save Debug Register State
- //
- Dr0 = AsmReadDr0 ();
- Dr1 = AsmReadDr1 ();
- Dr2 = AsmReadDr2 ();
- Dr3 = AsmReadDr3 ();
- Dr7 = AsmReadDr7 () | BIT10; // H/w sets bit 10, some simulators don't
- Cr4 = AsmReadCr4 ();
-
- //
- // DR0 = Signature
- // DR1 = The address of the Null-terminated ASCII string for the PE/COFF image's PDB file name
- // DR2 = The pointer to the ImageContext structure
- // DR3 = IO_PORT_BREAKPOINT_ADDRESS
- // DR7 = Disables all HW breakpoints except for DR3 I/O port access of length 1 byte
- // CR4 = Make sure DE(BIT3) is set
- //
- AsmWriteDr7 (BIT10);
- AsmWriteDr0 (Signature);
- AsmWriteDr1 ((UINTN)ImageContext->PdbPointer);
- AsmWriteDr2 ((UINTN)ImageContext);
- AsmWriteDr3 (IO_PORT_BREAKPOINT_ADDRESS);
-
- if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) {
- AsmWriteDr7 (0x20000480);
- AsmWriteCr4 (Cr4 | BIT3);
- //
- // Do an IN from IO_PORT_BREAKPOINT_ADDRESS to generate a HW breakpoint until the port
- // returns a read value other than DEBUG_AGENT_IMAGE_WAIT
- //
- do {
- DebugAgentStatus = IoRead8 (IO_PORT_BREAKPOINT_ADDRESS);
- } while (DebugAgentStatus == DEBUG_AGENT_IMAGE_WAIT);
- } else if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) {
- //
- // Generate a software break point.
- //
- CpuBreakpoint ();
- }
-
- //
- // Restore Debug Register State only when Host didn't change it inside exception handler.
- // E.g.: User halts the target and sets the HW breakpoint while target is
- // in the above exception handler
- //
- NewDr7 = AsmReadDr7 () | BIT10; // H/w sets bit 10, some simulators don't
- if (!IsDrxEnabled (0, NewDr7) && ((AsmReadDr0 () == 0) || (AsmReadDr0 () == Signature))) {
- //
- // If user changed Dr3 (by setting HW bp in the above exception handler,
- // we will not set Dr0 to 0 in GO/STEP handler because the break cause is not IMAGE_LOAD/_UNLOAD.
- //
- AsmWriteDr0 (Dr0);
- }
-
- if (!IsDrxEnabled (1, NewDr7) && (AsmReadDr1 () == (UINTN)ImageContext->PdbPointer)) {
- AsmWriteDr1 (Dr1);
- }
-
- if (!IsDrxEnabled (2, NewDr7) && (AsmReadDr2 () == (UINTN)ImageContext)) {
- AsmWriteDr2 (Dr2);
- }
-
- if (!IsDrxEnabled (3, NewDr7) && (AsmReadDr3 () == IO_PORT_BREAKPOINT_ADDRESS)) {
- AsmWriteDr3 (Dr3);
- }
-
- if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) {
- if (AsmReadCr4 () == (Cr4 | BIT3)) {
- AsmWriteCr4 (Cr4);
- }
-
- if (NewDr7 == 0x20000480) {
- AsmWriteDr7 (Dr7);
- }
- } else if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) {
- if (NewDr7 == BIT10) {
- AsmWriteDr7 (Dr7);
- }
- }
-
- //
- // Restore original IDT entry for INT1 if it was hooked.
- //
- if (IdtEntryHooked) {
- RestoreIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry);
- }
-
- //
- // Restore the interrupt state
- //
- SetInterruptState (InterruptState);
-}
-
-/**
- Performs additional actions after a PE/COFF image has been loaded and relocated.
-
- @param ImageContext Pointer to the image context structure that describes the
- PE/COFF image that has already been loaded and relocated.
-
-**/
-VOID
-EFIAPI
-PeCoffLoaderRelocateImageExtraAction (
- IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
- )
-{
- PeCoffLoaderExtraActionCommon (ImageContext, IMAGE_LOAD_SIGNATURE);
-}
-
-/**
- Performs additional actions just before a PE/COFF image is unloaded. Any resources
- that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.
-
- @param ImageContext Pointer to the image context structure that describes the
- PE/COFF image that is being unloaded.
-
-**/
-VOID
-EFIAPI
-PeCoffLoaderUnloadImageExtraAction (
- IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
- )
-{
- PeCoffLoaderExtraActionCommon (ImageContext, IMAGE_UNLOAD_SIGNATURE);
-}
+/** @file + PE/Coff Extra Action library instances. + + Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <PeCoffExtraActionLib.h> + +/** + Check if the hardware breakpoint in Drx is enabled by checking the Lx and Gx bit in Dr7. + + It assumes that DebugAgent will set both Lx and Gx bit when setting up the hardware breakpoint. + + + @param RegisterIndex Index of Dr register. The value range is from 0 to 3. + @param Dr7 Value of Dr7 register. + + @return TRUE The hardware breakpoint specified in the Drx is enabled. + @return FALSE The hardware breakpoint specified in the Drx is disabled. + +**/ +BOOLEAN +IsDrxEnabled ( + IN UINT8 RegisterIndex, + IN UINTN Dr7 + ) +{ + return (BOOLEAN)(((Dr7 >> (RegisterIndex * 2)) & (BIT0 | BIT1)) == (BIT0 | BIT1)); +} + +/** + Common routine to report the PE/COFF image loading/relocating or unloading event. + + If ImageContext is NULL, then ASSERT(). + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image. + @param Signature IMAGE_LOAD_SIGNATURE or IMAGE_UNLOAD_SIGNATURE. + +**/ +VOID +PeCoffLoaderExtraActionCommon ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext, + IN UINTN Signature + ) +{ + BOOLEAN InterruptState; + UINTN Dr0; + UINTN Dr1; + UINTN Dr2; + UINTN Dr3; + UINTN Dr7; + UINTN Cr4; + UINTN NewDr7; + UINT8 LoadImageMethod; + UINT8 DebugAgentStatus; + IA32_DESCRIPTOR IdtDescriptor; + IA32_IDT_GATE_DESCRIPTOR OriginalIdtEntry; + BOOLEAN IdtEntryHooked; + UINT32 RegEdx; + + ASSERT (ImageContext != NULL); + + if (ImageContext->PdbPointer != NULL) { + DEBUG ((DEBUG_ERROR, " PDB = %a\n", ImageContext->PdbPointer)); + } + + // + // Disable interrupts and save the current interrupt state + // + InterruptState = SaveAndDisableInterrupts (); + + IdtEntryHooked = FALSE; + LoadImageMethod = PcdGet8 (PcdDebugLoadImageMethod); + if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) { + // + // If the CPU does not support Debug Extensions(CPUID:01 EDX:BIT2) + // then force use of DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3 + // + AsmCpuid (1, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & BIT2) == 0) { + LoadImageMethod = DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3; + } + } + + AsmReadIdtr (&IdtDescriptor); + if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) { + if (!CheckDebugAgentHandler (&IdtDescriptor, SOFT_INT_VECTOR_NUM)) { + // + // Do not trigger INT3 if Debug Agent did not setup IDT entries. + // + return; + } + } else { + if (!CheckDebugAgentHandler (&IdtDescriptor, IO_HW_BREAKPOINT_VECTOR_NUM)) { + // + // Save and update IDT entry for INT1 + // + SaveAndUpdateIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry); + IdtEntryHooked = TRUE; + } + } + + // + // Save Debug Register State + // + Dr0 = AsmReadDr0 (); + Dr1 = AsmReadDr1 (); + Dr2 = AsmReadDr2 (); + Dr3 = AsmReadDr3 (); + Dr7 = AsmReadDr7 () | BIT10; // H/w sets bit 10, some simulators don't + Cr4 = AsmReadCr4 (); + + // + // DR0 = Signature + // DR1 = The address of the Null-terminated ASCII string for the PE/COFF image's PDB file name + // DR2 = The pointer to the ImageContext structure + // DR3 = IO_PORT_BREAKPOINT_ADDRESS + // DR7 = Disables all HW breakpoints except for DR3 I/O port access of length 1 byte + // CR4 = Make sure DE(BIT3) is set + // + AsmWriteDr7 (BIT10); + AsmWriteDr0 (Signature); + AsmWriteDr1 ((UINTN)ImageContext->PdbPointer); + AsmWriteDr2 ((UINTN)ImageContext); + AsmWriteDr3 (IO_PORT_BREAKPOINT_ADDRESS); + + if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) { + AsmWriteDr7 (0x20000480); + AsmWriteCr4 (Cr4 | BIT3); + // + // Do an IN from IO_PORT_BREAKPOINT_ADDRESS to generate a HW breakpoint until the port + // returns a read value other than DEBUG_AGENT_IMAGE_WAIT + // + do { + DebugAgentStatus = IoRead8 (IO_PORT_BREAKPOINT_ADDRESS); + } while (DebugAgentStatus == DEBUG_AGENT_IMAGE_WAIT); + } else if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) { + // + // Generate a software break point. + // + CpuBreakpoint (); + } + + // + // Restore Debug Register State only when Host didn't change it inside exception handler. + // E.g.: User halts the target and sets the HW breakpoint while target is + // in the above exception handler + // + NewDr7 = AsmReadDr7 () | BIT10; // H/w sets bit 10, some simulators don't + if (!IsDrxEnabled (0, NewDr7) && ((AsmReadDr0 () == 0) || (AsmReadDr0 () == Signature))) { + // + // If user changed Dr3 (by setting HW bp in the above exception handler, + // we will not set Dr0 to 0 in GO/STEP handler because the break cause is not IMAGE_LOAD/_UNLOAD. + // + AsmWriteDr0 (Dr0); + } + + if (!IsDrxEnabled (1, NewDr7) && (AsmReadDr1 () == (UINTN)ImageContext->PdbPointer)) { + AsmWriteDr1 (Dr1); + } + + if (!IsDrxEnabled (2, NewDr7) && (AsmReadDr2 () == (UINTN)ImageContext)) { + AsmWriteDr2 (Dr2); + } + + if (!IsDrxEnabled (3, NewDr7) && (AsmReadDr3 () == IO_PORT_BREAKPOINT_ADDRESS)) { + AsmWriteDr3 (Dr3); + } + + if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) { + if (AsmReadCr4 () == (Cr4 | BIT3)) { + AsmWriteCr4 (Cr4); + } + + if (NewDr7 == 0x20000480) { + AsmWriteDr7 (Dr7); + } + } else if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) { + if (NewDr7 == BIT10) { + AsmWriteDr7 (Dr7); + } + } + + // + // Restore original IDT entry for INT1 if it was hooked. + // + if (IdtEntryHooked) { + RestoreIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry); + } + + // + // Restore the interrupt state + // + SetInterruptState (InterruptState); +} + +/** + Performs additional actions after a PE/COFF image has been loaded and relocated. + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that has already been loaded and relocated. + +**/ +VOID +EFIAPI +PeCoffLoaderRelocateImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + PeCoffLoaderExtraActionCommon (ImageContext, IMAGE_LOAD_SIGNATURE); +} + +/** + Performs additional actions just before a PE/COFF image is unloaded. Any resources + that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed. + + @param ImageContext Pointer to the image context structure that describes the + PE/COFF image that is being unloaded. + +**/ +VOID +EFIAPI +PeCoffLoaderUnloadImageExtraAction ( + IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext + ) +{ + PeCoffLoaderExtraActionCommon (ImageContext, IMAGE_UNLOAD_SIGNATURE); +} diff --git a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.h b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.h index f428af9632..141493dbbc 100644 --- a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.h +++ b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.h @@ -1,72 +1,72 @@ -/** @file
- PE/Coff Extra Action library instances, it will report image debug info.
-
- Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef _PE_COFF_EXTRA_ACTION_LIB_H_
-#define _PE_COFF_EXTRA_ACTION_LIB_H_
-
-#include <Base.h>
-#include <Library/PeCoffExtraActionLib.h>
-#include <Library/DebugLib.h>
-#include <Library/BaseLib.h>
-#include <Library/IoLib.h>
-#include <Library/PcdLib.h>
-#include <Library/BaseMemoryLib.h>
-
-#include <ImageDebugSupport.h>
-
-#define DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT 1
-#define DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3 2
-
-#define IO_HW_BREAKPOINT_VECTOR_NUM 1
-#define SOFT_INT_VECTOR_NUM 3
-
-extern UINTN AsmInterruptHandle;
-
-/**
- Read IDT entry to check if IDT entries are setup by Debug Agent.
-
- @param[in] IdtDescriptor Pointer to IDT Descriptor.
- @param[in] InterruptType Interrupt type.
-
- @retval TRUE IDT entries were setup by Debug Agent.
- @retval FALSE IDT entries were not setup by Debug Agent.
-
-**/
-BOOLEAN
-CheckDebugAgentHandler (
- IN IA32_DESCRIPTOR *IdtDescriptor,
- IN UINTN InterruptType
- );
-
-/**
- Save IDT entry for INT1 and update it.
-
- @param[in] IdtDescriptor Pointer to IDT Descriptor.
- @param[out] SavedIdtEntry Original IDT entry returned.
-
-**/
-VOID
-SaveAndUpdateIdtEntry1 (
- IN IA32_DESCRIPTOR *IdtDescriptor,
- OUT IA32_IDT_GATE_DESCRIPTOR *SavedIdtEntry
- );
-
-/**
- Restore IDT entry for INT1.
-
- @param[in] IdtDescriptor Pointer to IDT Descriptor.
- @param[in] RestoredIdtEntry IDT entry to be restored.
-
-**/
-VOID
-RestoreIdtEntry1 (
- IN IA32_DESCRIPTOR *IdtDescriptor,
- IN IA32_IDT_GATE_DESCRIPTOR *RestoredIdtEntry
- );
-
-#endif
+/** @file + PE/Coff Extra Action library instances, it will report image debug info. + + Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _PE_COFF_EXTRA_ACTION_LIB_H_ +#define _PE_COFF_EXTRA_ACTION_LIB_H_ + +#include <Base.h> +#include <Library/PeCoffExtraActionLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseLib.h> +#include <Library/IoLib.h> +#include <Library/PcdLib.h> +#include <Library/BaseMemoryLib.h> + +#include <ImageDebugSupport.h> + +#define DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT 1 +#define DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3 2 + +#define IO_HW_BREAKPOINT_VECTOR_NUM 1 +#define SOFT_INT_VECTOR_NUM 3 + +extern UINTN AsmInterruptHandle; + +/** + Read IDT entry to check if IDT entries are setup by Debug Agent. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[in] InterruptType Interrupt type. + + @retval TRUE IDT entries were setup by Debug Agent. + @retval FALSE IDT entries were not setup by Debug Agent. + +**/ +BOOLEAN +CheckDebugAgentHandler ( + IN IA32_DESCRIPTOR *IdtDescriptor, + IN UINTN InterruptType + ); + +/** + Save IDT entry for INT1 and update it. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[out] SavedIdtEntry Original IDT entry returned. + +**/ +VOID +SaveAndUpdateIdtEntry1 ( + IN IA32_DESCRIPTOR *IdtDescriptor, + OUT IA32_IDT_GATE_DESCRIPTOR *SavedIdtEntry + ); + +/** + Restore IDT entry for INT1. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[in] RestoredIdtEntry IDT entry to be restored. + +**/ +VOID +RestoreIdtEntry1 ( + IN IA32_DESCRIPTOR *IdtDescriptor, + IN IA32_IDT_GATE_DESCRIPTOR *RestoredIdtEntry + ); + +#endif diff --git a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.uni b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.uni index 965aa644ab..b86a5fc4c7 100644 --- a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.uni +++ b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.uni @@ -1,16 +1,16 @@ -// /** @file
-// PeCoffExtraAction Library to support source level debug.
-//
-// PeCoffExtraAction Library to support source level debug.
-//
-// Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-
-#string STR_MODULE_ABSTRACT #language en-US "PeCoffExtraAction Library to support source level debug"
-
-#string STR_MODULE_DESCRIPTION #language en-US "PeCoffExtraAction Library to support source level debug."
-
+// /** @file +// PeCoffExtraAction Library to support source level debug. +// +// PeCoffExtraAction Library to support source level debug. +// +// Copyright (c) 2010 - 2014, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "PeCoffExtraAction Library to support source level debug" + +#string STR_MODULE_DESCRIPTION #language en-US "PeCoffExtraAction Library to support source level debug." + diff --git a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf index 1feed2c3c8..06a8ae1a6c 100644 --- a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf +++ b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf @@ -1,50 +1,50 @@ -## @file
-# PeCoffExtraAction Library to support source level debug.
-#
-# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = PeCoffExtraActionLib
- MODULE_UNI_FILE = PeCoffExtraActionLib.uni
- FILE_GUID = 8F01CBD5-E069-44d7-90C9-35F0318603AD
- MODULE_TYPE = BASE
- VERSION_STRING = 0.8
- LIBRARY_CLASS = PeCoffExtraActionLib
-
-#
-# The following information is for reference only and not required by the build tools.
-#
-# VALID_ARCHITECTURES = IA32 X64
-#
-
-[Sources.common]
- PeCoffExtraActionLib.h
- PeCoffExtraActionLib.c
-
-[Sources.IA32]
- Ia32/IntHandlerFuncs.c
- Ia32/IntHandler.nasm
-
-[Sources.X64]
- X64/IntHandlerFuncs.c
- X64/IntHandler.nasm
-
-[Packages]
- MdePkg/MdePkg.dec
- SourceLevelDebugPkg/SourceLevelDebugPkg.dec
-
-[LibraryClasses]
- BaseLib
- DebugLib
- IoLib
- PcdLib
-
-[Pcd]
- gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod ## CONSUMES
-
+## @file +# PeCoffExtraAction Library to support source level debug. +# +# Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PeCoffExtraActionLib + MODULE_UNI_FILE = PeCoffExtraActionLib.uni + FILE_GUID = 8F01CBD5-E069-44d7-90C9-35F0318603AD + MODULE_TYPE = BASE + VERSION_STRING = 0.8 + LIBRARY_CLASS = PeCoffExtraActionLib + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources.common] + PeCoffExtraActionLib.h + PeCoffExtraActionLib.c + +[Sources.IA32] + Ia32/IntHandlerFuncs.c + Ia32/IntHandler.nasm + +[Sources.X64] + X64/IntHandlerFuncs.c + X64/IntHandler.nasm + +[Packages] + MdePkg/MdePkg.dec + SourceLevelDebugPkg/SourceLevelDebugPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + IoLib + PcdLib + +[Pcd] + gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod ## CONSUMES + diff --git a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.nasm b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.nasm index 6b3a7a526f..4e63774975 100644 --- a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.nasm +++ b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.nasm @@ -1,23 +1,23 @@ -;------------------------------------------------------------------------------
-;
-; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
-; SPDX-License-Identifier: BSD-2-Clause-Patent
-;
-; Module Name:
-;
-; IntHandler.nasm
-;
-; Abstract:
-;
-; Assembly interrupt handler function.
-;
-;------------------------------------------------------------------------------
-
-global ASM_PFX(AsmInterruptHandle)
-
-DEFAULT REL
-SECTION .text
-ASM_PFX(AsmInterruptHandle):
- cli
- mov al, 1
- iretq
+;------------------------------------------------------------------------------ +; +; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> +; SPDX-License-Identifier: BSD-2-Clause-Patent +; +; Module Name: +; +; IntHandler.nasm +; +; Abstract: +; +; Assembly interrupt handler function. +; +;------------------------------------------------------------------------------ + +global ASM_PFX(AsmInterruptHandle) + +DEFAULT REL +SECTION .text +ASM_PFX(AsmInterruptHandle): + cli + mov al, 1 + iretq diff --git a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandlerFuncs.c b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandlerFuncs.c index 1baa88206b..a4e7b88f2d 100644 --- a/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandlerFuncs.c +++ b/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandlerFuncs.c @@ -1,95 +1,95 @@ -/** @file
- X64 arch function to access IDT vector.
-
- Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include <PeCoffExtraActionLib.h>
-
-/**
- Read IDT entry to check if IDT entries are setup by Debug Agent.
-
- @param[in] IdtDescriptor Pointer to IDT Descriptor.
- @param[in] InterruptType Interrupt type.
-
- @retval TRUE IDT entries were setup by Debug Agent.
- @retval FALSE IDT entries were not setup by Debug Agent.
-
-**/
-BOOLEAN
-CheckDebugAgentHandler (
- IN IA32_DESCRIPTOR *IdtDescriptor,
- IN UINTN InterruptType
- )
-{
- IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
- UINTN InterruptHandler;
-
- IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base;
- if (IdtEntry == NULL) {
- return FALSE;
- }
-
- InterruptHandler = IdtEntry[InterruptType].Bits.OffsetLow +
- (((UINTN)IdtEntry[InterruptType].Bits.OffsetHigh) << 16) +
- (((UINTN)IdtEntry[InterruptType].Bits.OffsetUpper) << 32);
- if ((InterruptHandler >= sizeof (UINT32)) && (*(UINT32 *)(InterruptHandler - sizeof (UINT32)) == AGENT_HANDLER_SIGNATURE)) {
- return TRUE;
- } else {
- return FALSE;
- }
-}
-
-/**
- Save IDT entry for INT1 and update it.
-
- @param[in] IdtDescriptor Pointer to IDT Descriptor.
- @param[out] SavedIdtEntry Original IDT entry returned.
-
-**/
-VOID
-SaveAndUpdateIdtEntry1 (
- IN IA32_DESCRIPTOR *IdtDescriptor,
- OUT IA32_IDT_GATE_DESCRIPTOR *SavedIdtEntry
- )
-{
- IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
- UINT16 CodeSegment;
- UINTN InterruptHandler;
-
- IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base;
- CopyMem (SavedIdtEntry, &IdtEntry[1], sizeof (IA32_IDT_GATE_DESCRIPTOR));
-
- //
- // Use current CS as the segment selector of interrupt gate in IDT
- //
- CodeSegment = AsmReadCs ();
-
- InterruptHandler = (UINTN)&AsmInterruptHandle;
- IdtEntry[1].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
- IdtEntry[1].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
- IdtEntry[1].Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32);
- IdtEntry[1].Bits.Selector = CodeSegment;
- IdtEntry[1].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
-}
-
-/**
- Restore IDT entry for INT1.
-
- @param[in] IdtDescriptor Pointer to IDT Descriptor.
- @param[in] RestoredIdtEntry IDT entry to be restored.
-
-**/
-VOID
-RestoreIdtEntry1 (
- IN IA32_DESCRIPTOR *IdtDescriptor,
- IN IA32_IDT_GATE_DESCRIPTOR *RestoredIdtEntry
- )
-{
- IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
-
- IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base;
- CopyMem (&IdtEntry[1], RestoredIdtEntry, sizeof (IA32_IDT_GATE_DESCRIPTOR));
-}
+/** @file + X64 arch function to access IDT vector. + + Copyright (c) 2013 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <PeCoffExtraActionLib.h> + +/** + Read IDT entry to check if IDT entries are setup by Debug Agent. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[in] InterruptType Interrupt type. + + @retval TRUE IDT entries were setup by Debug Agent. + @retval FALSE IDT entries were not setup by Debug Agent. + +**/ +BOOLEAN +CheckDebugAgentHandler ( + IN IA32_DESCRIPTOR *IdtDescriptor, + IN UINTN InterruptType + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + UINTN InterruptHandler; + + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base; + if (IdtEntry == NULL) { + return FALSE; + } + + InterruptHandler = IdtEntry[InterruptType].Bits.OffsetLow + + (((UINTN)IdtEntry[InterruptType].Bits.OffsetHigh) << 16) + + (((UINTN)IdtEntry[InterruptType].Bits.OffsetUpper) << 32); + if ((InterruptHandler >= sizeof (UINT32)) && (*(UINT32 *)(InterruptHandler - sizeof (UINT32)) == AGENT_HANDLER_SIGNATURE)) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Save IDT entry for INT1 and update it. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[out] SavedIdtEntry Original IDT entry returned. + +**/ +VOID +SaveAndUpdateIdtEntry1 ( + IN IA32_DESCRIPTOR *IdtDescriptor, + OUT IA32_IDT_GATE_DESCRIPTOR *SavedIdtEntry + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + UINT16 CodeSegment; + UINTN InterruptHandler; + + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base; + CopyMem (SavedIdtEntry, &IdtEntry[1], sizeof (IA32_IDT_GATE_DESCRIPTOR)); + + // + // Use current CS as the segment selector of interrupt gate in IDT + // + CodeSegment = AsmReadCs (); + + InterruptHandler = (UINTN)&AsmInterruptHandle; + IdtEntry[1].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; + IdtEntry[1].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16); + IdtEntry[1].Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32); + IdtEntry[1].Bits.Selector = CodeSegment; + IdtEntry[1].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; +} + +/** + Restore IDT entry for INT1. + + @param[in] IdtDescriptor Pointer to IDT Descriptor. + @param[in] RestoredIdtEntry IDT entry to be restored. + +**/ +VOID +RestoreIdtEntry1 ( + IN IA32_DESCRIPTOR *IdtDescriptor, + IN IA32_IDT_GATE_DESCRIPTOR *RestoredIdtEntry + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *)IdtDescriptor->Base; + CopyMem (&IdtEntry[1], RestoredIdtEntry, sizeof (IA32_IDT_GATE_DESCRIPTOR)); +} |
