summaryrefslogtreecommitdiff
path: root/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug
diff options
context:
space:
mode:
Diffstat (limited to 'Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug')
-rw-r--r--Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.S28
-rw-r--r--Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.asm33
-rw-r--r--Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandlerFuncs.c99
-rw-r--r--Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c230
-rw-r--r--Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.h79
-rw-r--r--Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.unibin0 -> 1806 bytes
-rw-r--r--Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf57
-rw-r--r--Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.S28
-rw-r--r--Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.asm29
-rw-r--r--Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandlerFuncs.c101
10 files changed, 684 insertions, 0 deletions
diff --git a/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.S b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.S
new file mode 100644
index 0000000000..69c903788c
--- /dev/null
+++ b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.S
@@ -0,0 +1,28 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2013, 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.
+#
+# Module Name:
+#
+# IntHandler.S
+#
+# Abstract:
+#
+# Assembly interrupt handler function.
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(AsmInterruptHandle)
+
+.text
+ASM_PFX(AsmInterruptHandle):
+ cli
+ movb $1, %al
+ iretl
diff --git a/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.asm b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.asm
new file mode 100644
index 0000000000..ce9c03b490
--- /dev/null
+++ b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandler.asm
@@ -0,0 +1,33 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2013, 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.
+;
+; Module Name:
+;
+; IntHandler.asm
+;
+; Abstract:
+;
+; Assembly interrupt handler function.
+;
+;------------------------------------------------------------------------------
+
+
+.686p
+.model flat,c
+
+public AsmInterruptHandle
+
+.code
+AsmInterruptHandle:
+ cli
+ mov al, 1
+ iretd
+END
diff --git a/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandlerFuncs.c b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandlerFuncs.c
new file mode 100644
index 0000000000..ccf3fb1842
--- /dev/null
+++ b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/Ia32/IntHandlerFuncs.c
@@ -0,0 +1,99 @@
+/** @file
+ Ia32 arch functions to access IDT vector.
+
+ Copyright (c) 2013, 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 <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 setuo 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/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c
new file mode 100644
index 0000000000..87420709f6
--- /dev/null
+++ b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.c
@@ -0,0 +1,230 @@
+/** @file
+ PE/Coff Extra Action library instances.
+
+ Copyright (c) 2010 - 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 <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((EFI_D_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/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.h b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.h
new file mode 100644
index 0000000000..3f919287e8
--- /dev/null
+++ b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.h
@@ -0,0 +1,79 @@
+/** @file
+ PE/Coff Extra Action library instances, it will report image debug info.
+
+ Copyright (c) 2013, 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 _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 setuo 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/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.uni b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.uni
new file mode 100644
index 0000000000..8bdf749b43
--- /dev/null
+++ b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLib.uni
Binary files differ
diff --git a/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
new file mode 100644
index 0000000000..e53f1d936c
--- /dev/null
+++ b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/PeCoffExtraActionLibDebug.inf
@@ -0,0 +1,57 @@
+## @file
+# PeCoffExtraAction Library to support source level debug.
+#
+# Copyright (c) 2010 - 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 = 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.asm
+ Ia32/IntHandler.S | GCC
+
+[Sources.X64]
+ X64/IntHandlerFuncs.c
+ X64/IntHandler.asm
+ X64/IntHandler.S | GCC
+
+[Packages]
+ MdePkg/MdePkg.dec
+ SourceLevelDebugPkg/SourceLevelDebugPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ DebugLib
+ IoLib
+ PcdLib
+
+[Pcd]
+ gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugLoadImageMethod ## CONSUMES
+
diff --git a/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.S b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.S
new file mode 100644
index 0000000000..108b40cf6d
--- /dev/null
+++ b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.S
@@ -0,0 +1,28 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2013, 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.
+#
+# Module Name:
+#
+# IntHandler.S
+#
+# Abstract:
+#
+# Assembly interrupt handler function.
+#
+#------------------------------------------------------------------------------
+
+ASM_GLOBAL ASM_PFX(AsmInterruptHandle)
+
+.text
+ASM_PFX(AsmInterruptHandle):
+ cli
+ movb $1, %al
+ iretq
diff --git a/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.asm b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.asm
new file mode 100644
index 0000000000..93f4d6f17f
--- /dev/null
+++ b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandler.asm
@@ -0,0 +1,29 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2013, 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.
+;
+; Module Name:
+;
+; IntHandler.asm
+;
+; Abstract:
+;
+; Assembly interrupt handler function.
+;
+;------------------------------------------------------------------------------
+
+public AsmInterruptHandle
+
+.code
+AsmInterruptHandle:
+ cli
+ mov al, 1
+ iretq
+END
diff --git a/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandlerFuncs.c b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandlerFuncs.c
new file mode 100644
index 0000000000..5431187d06
--- /dev/null
+++ b/Core/SourceLevelDebugPkg/Library/PeCoffExtraActionLibDebug/X64/IntHandlerFuncs.c
@@ -0,0 +1,101 @@
+/** @file
+ X64 arch function to access IDT vector.
+
+ Copyright (c) 2013, 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 <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 setuo 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));
+}