Import SourceLevelDebugPkg.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10867 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
/** @file
|
||||
PE/Coff Extra Action library instances.
|
||||
|
||||
Copyright (c) 2010, 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 <Base.h>
|
||||
#include <Library/PeCoffExtraActionLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/IoLib.h>
|
||||
#include <Library/PcdLib.h>
|
||||
|
||||
#include <ImageDebugSupport.h>
|
||||
|
||||
#define DEBUG_LOAD_IMAGE_METHOD_IO_HW_BREAKPOINT 1
|
||||
#define DEBUG_LOAD_IMAGE_METHOD_SOFT_INT3 2
|
||||
|
||||
/**
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
Performs additional actions after a PE/COFF image has been loaded and relocated.
|
||||
|
||||
If ImageContext is NULL, then ASSERT().
|
||||
|
||||
@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
|
||||
)
|
||||
{
|
||||
BOOLEAN InterruptState;
|
||||
UINTN Dr0;
|
||||
UINTN Dr1;
|
||||
UINTN Dr2;
|
||||
UINTN Dr3;
|
||||
UINTN Dr7;
|
||||
UINTN Cr4;
|
||||
UINTN NewDr7;
|
||||
UINT8 LoadImageMethod;
|
||||
UINT8 DebugAgentStatus;
|
||||
|
||||
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 ();
|
||||
|
||||
//
|
||||
// Save Debug Register State
|
||||
//
|
||||
Dr0 = AsmReadDr0 ();
|
||||
Dr1 = AsmReadDr1 ();
|
||||
Dr2 = AsmReadDr2 ();
|
||||
Dr3 = AsmReadDr3 ();
|
||||
Dr7 = AsmReadDr7 ();
|
||||
Cr4 = AsmReadCr4 ();
|
||||
|
||||
//
|
||||
// DR0 = IMAGE_LOAD_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 (0);
|
||||
AsmWriteDr0 (IMAGE_LOAD_SIGNATURE);
|
||||
AsmWriteDr1 ((UINTN)ImageContext->PdbPointer);
|
||||
AsmWriteDr2 ((UINTN)ImageContext);
|
||||
AsmWriteDr3 (IO_PORT_BREAKPOINT_ADDRESS);
|
||||
|
||||
LoadImageMethod = PcdGet8 (PcdDebugLoadImageMethod);
|
||||
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 ();
|
||||
if (!IsDrxEnabled (0, NewDr7)) {
|
||||
AsmWriteDr0 (Dr0);
|
||||
}
|
||||
if (!IsDrxEnabled (1, NewDr7)) {
|
||||
AsmWriteDr1 (Dr1);
|
||||
}
|
||||
if (!IsDrxEnabled (2, NewDr7)) {
|
||||
AsmWriteDr2 (Dr2);
|
||||
}
|
||||
if (!IsDrxEnabled (3, NewDr7)) {
|
||||
AsmWriteDr3 (Dr3);
|
||||
}
|
||||
if (AsmReadCr4 () == (Cr4 | BIT3)) {
|
||||
AsmWriteCr4 (Cr4);
|
||||
}
|
||||
if (NewDr7 == 0x20000480) {
|
||||
AsmWriteDr7 (Dr7);
|
||||
}
|
||||
//
|
||||
// Restore the interrupt state
|
||||
//
|
||||
SetInterruptState (InterruptState);
|
||||
}
|
||||
|
||||
/**
|
||||
Performs additional actions just before a PE/COFF image is unloaded. Any resources
|
||||
that were allocated by PeCoffLoaderRelocateImageExtraAction() must be freed.
|
||||
|
||||
If ImageContext is NULL, then ASSERT().
|
||||
|
||||
@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
|
||||
)
|
||||
{
|
||||
BOOLEAN InterruptState;
|
||||
UINTN Dr0;
|
||||
UINTN Dr1;
|
||||
UINTN Dr2;
|
||||
UINTN Dr3;
|
||||
UINTN Dr7;
|
||||
UINTN Cr4;
|
||||
UINTN NewDr7;
|
||||
UINT8 LoadImageMethod;
|
||||
UINT8 DebugAgentStatus;
|
||||
|
||||
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 ();
|
||||
|
||||
//
|
||||
// Save Debug Register State
|
||||
//
|
||||
Dr0 = AsmReadDr0 ();
|
||||
Dr1 = AsmReadDr1 ();
|
||||
Dr2 = AsmReadDr2 ();
|
||||
Dr3 = AsmReadDr3 ();
|
||||
Dr7 = AsmReadDr7 ();
|
||||
Cr4 = AsmReadCr4 ();
|
||||
|
||||
//
|
||||
// DR0 = IMAGE_UNLOAD_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 (0);
|
||||
AsmWriteDr0 (IMAGE_UNLOAD_SIGNATURE);
|
||||
AsmWriteDr1 ((UINTN)ImageContext->PdbPointer);
|
||||
AsmWriteDr2 ((UINTN)ImageContext);
|
||||
AsmWriteDr3 (IO_PORT_BREAKPOINT_ADDRESS);
|
||||
|
||||
LoadImageMethod = PcdGet8 (PcdDebugLoadImageMethod);
|
||||
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 ();
|
||||
if (!IsDrxEnabled (0, NewDr7)) {
|
||||
AsmWriteDr0 (Dr0);
|
||||
}
|
||||
if (!IsDrxEnabled (1, NewDr7)) {
|
||||
AsmWriteDr1 (Dr1);
|
||||
}
|
||||
if (!IsDrxEnabled (2, NewDr7)) {
|
||||
AsmWriteDr2 (Dr2);
|
||||
}
|
||||
if (!IsDrxEnabled (3, NewDr7)) {
|
||||
AsmWriteDr3 (Dr3);
|
||||
}
|
||||
if (AsmReadCr4 () == (Cr4 | BIT3)) {
|
||||
AsmWriteCr4 (Cr4);
|
||||
}
|
||||
if (NewDr7 == 0x20000480) {
|
||||
AsmWriteDr7 (Dr7);
|
||||
}
|
||||
|
||||
//
|
||||
// Restore the interrupt state
|
||||
//
|
||||
SetInterruptState (InterruptState);
|
||||
}
|
Reference in New Issue
Block a user