/** @file\r
PE/Coff Extra Action library instances.\r
\r
- Copyright (c) 2010 - 2012, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
-#include <Base.h>\r
-#include <Library/PeCoffExtraActionLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/IoLib.h>\r
-#include <Library/PcdLib.h>\r
-\r
-#include <ImageDebugSupport.h>\r
-\r
-#define DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT 1\r
-#define DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3 2\r
+#include <PeCoffExtraActionLib.h>\r
\r
/**\r
Check if the hardware breakpoint in Drx is enabled by checking the Lx and Gx bit in Dr7.\r
- \r
+\r
It assumes that DebugAgent will set both Lx and Gx bit when setting up the hardware breakpoint.\r
\r
\r
Common routine to report the PE/COFF image loading/relocating or unloading event.\r
\r
If ImageContext is NULL, then ASSERT().\r
- \r
+\r
@param ImageContext Pointer to the image context structure that describes the\r
PE/COFF image.\r
@param Signature IMAGE_LOAD_SIGNATURE or IMAGE_UNLOAD_SIGNATURE.\r
IN UINTN Signature\r
)\r
{\r
- BOOLEAN InterruptState;\r
- UINTN Dr0;\r
- UINTN Dr1;\r
- UINTN Dr2;\r
- UINTN Dr3;\r
- UINTN Dr7;\r
- UINTN Cr4;\r
- UINTN NewDr7;\r
- UINT8 LoadImageMethod;\r
- UINT8 DebugAgentStatus;\r
+ BOOLEAN InterruptState;\r
+ UINTN Dr0;\r
+ UINTN Dr1;\r
+ UINTN Dr2;\r
+ UINTN Dr3;\r
+ UINTN Dr7;\r
+ UINTN Cr4;\r
+ UINTN NewDr7;\r
+ UINT8 LoadImageMethod;\r
+ UINT8 DebugAgentStatus;\r
+ IA32_DESCRIPTOR IdtDescriptor;\r
+ IA32_IDT_GATE_DESCRIPTOR OriginalIdtEntry;\r
+ BOOLEAN IdtEntryHooked;\r
+ UINT32 RegEdx;\r
\r
ASSERT (ImageContext != NULL);\r
\r
if (ImageContext->PdbPointer != NULL) {\r
- DEBUG((EFI_D_ERROR, " PDB = %a\n", ImageContext->PdbPointer));\r
+ DEBUG((DEBUG_ERROR, " PDB = %a\n", ImageContext->PdbPointer));\r
}\r
\r
//\r
//\r
InterruptState = SaveAndDisableInterrupts ();\r
\r
+ IdtEntryHooked = FALSE;\r
+ LoadImageMethod = PcdGet8 (PcdDebugLoadImageMethod);\r
+ if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) {\r
+ //\r
+ // If the CPU does not support Debug Extensions(CPUID:01 EDX:BIT2)\r
+ // then force use of DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3\r
+ //\r
+ AsmCpuid (1, NULL, NULL, NULL, &RegEdx);\r
+ if ((RegEdx & BIT2) == 0) {\r
+ LoadImageMethod = DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3;\r
+ }\r
+ }\r
+ AsmReadIdtr (&IdtDescriptor);\r
+ if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) {\r
+ if (!CheckDebugAgentHandler (&IdtDescriptor, SOFT_INT_VECTOR_NUM)) {\r
+ //\r
+ // Do not trigger INT3 if Debug Agent did not setup IDT entries.\r
+ //\r
+ return;\r
+ }\r
+ } else {\r
+ if (!CheckDebugAgentHandler (&IdtDescriptor, IO_HW_BREAKPOINT_VECTOR_NUM)) {\r
+ //\r
+ // Save and update IDT entry for INT1\r
+ //\r
+ SaveAndUpdateIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry);\r
+ IdtEntryHooked = TRUE;\r
+ }\r
+ }\r
+\r
//\r
// Save Debug Register State\r
//\r
Dr1 = AsmReadDr1 ();\r
Dr2 = AsmReadDr2 ();\r
Dr3 = AsmReadDr3 ();\r
- Dr7 = AsmReadDr7 ();\r
+ Dr7 = AsmReadDr7 () | BIT10; // H/w sets bit 10, some simulators don't\r
Cr4 = AsmReadCr4 ();\r
\r
//\r
// DR7 = Disables all HW breakpoints except for DR3 I/O port access of length 1 byte\r
// CR4 = Make sure DE(BIT3) is set\r
//\r
- AsmWriteDr7 (0);\r
+ AsmWriteDr7 (BIT10);\r
AsmWriteDr0 (Signature);\r
AsmWriteDr1 ((UINTN) ImageContext->PdbPointer);\r
AsmWriteDr2 ((UINTN) ImageContext);\r
AsmWriteDr3 (IO_PORT_BREAKPOINT_ADDRESS);\r
\r
- LoadImageMethod = PcdGet8 (PcdDebugLoadImageMethod);\r
if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) {\r
AsmWriteDr7 (0x20000480);\r
AsmWriteCr4 (Cr4 | BIT3);\r
\r
//\r
// Restore Debug Register State only when Host didn't change it inside exception handler.\r
- // E.g.: User halts the target and sets the HW breakpoint while target is \r
+ // E.g.: User halts the target and sets the HW breakpoint while target is\r
// in the above exception handler\r
//\r
- NewDr7 = AsmReadDr7 ();\r
+ NewDr7 = AsmReadDr7 () | BIT10; // H/w sets bit 10, some simulators don't\r
if (!IsDrxEnabled (0, NewDr7) && (AsmReadDr0 () == 0 || AsmReadDr0 () == Signature)) {\r
//\r
// If user changed Dr3 (by setting HW bp in the above exception handler,\r
if (!IsDrxEnabled (3, NewDr7) && (AsmReadDr3 () == IO_PORT_BREAKPOINT_ADDRESS)) {\r
AsmWriteDr3 (Dr3);\r
}\r
- if (AsmReadCr4 () == (Cr4 | BIT3)) {\r
- AsmWriteCr4 (Cr4);\r
+ if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT) {\r
+ if (AsmReadCr4 () == (Cr4 | BIT3)) {\r
+ AsmWriteCr4 (Cr4);\r
+ }\r
+ if (NewDr7 == 0x20000480) {\r
+ AsmWriteDr7 (Dr7);\r
+ }\r
+ } else if (LoadImageMethod == DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3) {\r
+ if (NewDr7 == BIT10) {\r
+ AsmWriteDr7 (Dr7);\r
+ }\r
}\r
- if (NewDr7 == 0x20000480) {\r
- AsmWriteDr7 (Dr7);\r
+ //\r
+ // Restore original IDT entry for INT1 if it was hooked.\r
+ //\r
+ if (IdtEntryHooked) {\r
+ RestoreIdtEntry1 (&IdtDescriptor, &OriginalIdtEntry);\r
}\r
//\r
// Restore the interrupt state\r