mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
354 lines
7.5 KiB
354 lines
7.5 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
debug.c
|
|
|
|
Abstract:
|
|
|
|
This file contains code to manage software breakpoints
|
|
|
|
Author:
|
|
|
|
Neil Sandlin (neilsa) 1-Nov-1995
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <precomp.h>
|
|
#pragma hdrstop
|
|
#include <dpmi.h>
|
|
#include <dbgsvc.h>
|
|
#include <stdio.h>
|
|
|
|
|
|
VOID
|
|
DisableBreakPoint(
|
|
VDM_BREAKPOINT *pBP
|
|
)
|
|
{
|
|
int mode;
|
|
ULONG lpAddress;
|
|
BYTE byte;
|
|
|
|
if (!(pBP->Flags & VDMBP_ENABLED)) {
|
|
return;
|
|
}
|
|
|
|
if (pBP->Flags & VDMBP_V86) {
|
|
mode = V86_MODE;
|
|
} else {
|
|
mode = PROT_MODE;
|
|
}
|
|
|
|
lpAddress = GetInfoFromSelector(pBP->Seg, mode, NULL) + GetIntelBase() + pBP->Offset;
|
|
|
|
if (READMEM((PVOID)lpAddress, &byte, 1)) {
|
|
if (byte == 0xcc) {
|
|
PRINTF("Writing %02X to %08X\n", pBP->Opcode, lpAddress);
|
|
WRITEMEM((PVOID)lpAddress, &pBP->Opcode, 1);
|
|
}
|
|
}
|
|
|
|
pBP->Flags &= ~VDMBP_ENABLED;
|
|
}
|
|
|
|
VOID
|
|
EnableBreakPoint(
|
|
VDM_BREAKPOINT *pBP
|
|
)
|
|
{
|
|
int mode;
|
|
ULONG lpAddress;
|
|
BYTE byte;
|
|
|
|
if (pBP->Flags & VDMBP_ENABLED) {
|
|
return;
|
|
}
|
|
|
|
if (pBP->Flags & VDMBP_V86) {
|
|
mode = V86_MODE;
|
|
} else {
|
|
mode = PROT_MODE;
|
|
}
|
|
|
|
lpAddress = GetInfoFromSelector(pBP->Seg, mode, NULL) + GetIntelBase() + pBP->Offset;
|
|
|
|
if (READMEM((PVOID)lpAddress, &byte, 1)) {
|
|
if (byte != 0xcc) {
|
|
static BYTE bpOp = 0xcc;
|
|
|
|
PRINTF("Writing %02X to %08X\n", bpOp, lpAddress);
|
|
WRITEMEM((PVOID)lpAddress, &bpOp, 1);
|
|
pBP->Opcode = byte;
|
|
}
|
|
} else {
|
|
|
|
PRINTF("Error enabling breakpoint at %04X:%08X\n", pBP->Seg, pBP->Offset);
|
|
return;
|
|
}
|
|
|
|
pBP->Flags |= VDMBP_ENABLED;
|
|
}
|
|
|
|
|
|
VOID
|
|
UpdateBreakPoint(
|
|
int Cmd
|
|
)
|
|
|
|
{
|
|
ULONG lpAddress;
|
|
VDM_BREAKPOINT VdmBreakPoint;
|
|
int BPNum;
|
|
|
|
|
|
lpAddress = (*GetExpression)("ntvdm!VdmBreakPoints");
|
|
|
|
if (!lpAddress) {
|
|
PRINTF("Could not find symbol ntvdm!VdmBreakPoints\n");
|
|
return;
|
|
}
|
|
|
|
if (!GetNextToken()) {
|
|
PRINTF("Please specify an breakpoint #\n");
|
|
return;
|
|
}
|
|
sscanf(lpArgumentString, "%d", &BPNum);
|
|
|
|
if (BPNum > MAX_VDM_BREAKPOINTS) {
|
|
PRINTF("Invalid breakpoint - %d\n", BPNum);
|
|
}
|
|
|
|
lpAddress += BPNum*sizeof(VDM_BREAKPOINT);
|
|
|
|
if (!READMEM((PVOID)lpAddress, &VdmBreakPoint, sizeof(VDM_BREAKPOINT))) {
|
|
PRINTF("Error reading BP memory\n");
|
|
return;
|
|
}
|
|
|
|
switch(Cmd) {
|
|
|
|
case 1: // CLEAR
|
|
|
|
if (VdmBreakPoint.Flags & VDMBP_SET) {
|
|
if (VdmBreakPoint.Flags & VDMBP_ENABLED) {
|
|
DisableBreakPoint(&VdmBreakPoint);
|
|
}
|
|
VdmBreakPoint.Flags &= ~VDMBP_SET;
|
|
}
|
|
break;
|
|
|
|
case 2: // DISABLE
|
|
|
|
if (VdmBreakPoint.Flags & VDMBP_SET) {
|
|
if (VdmBreakPoint.Flags & VDMBP_ENABLED) {
|
|
DisableBreakPoint(&VdmBreakPoint);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case 3: // ENABLE
|
|
|
|
if (VdmBreakPoint.Flags & VDMBP_SET) {
|
|
if (!(VdmBreakPoint.Flags & VDMBP_ENABLED)) {
|
|
EnableBreakPoint(&VdmBreakPoint);
|
|
}
|
|
}
|
|
break;
|
|
|
|
}
|
|
|
|
WRITEMEM((PVOID)lpAddress, &VdmBreakPoint, sizeof(VDM_BREAKPOINT));
|
|
}
|
|
|
|
VOID
|
|
bc(
|
|
CMD_ARGLIST
|
|
)
|
|
{
|
|
CMD_INIT();
|
|
UpdateBreakPoint(1);
|
|
}
|
|
|
|
VOID
|
|
bd(
|
|
CMD_ARGLIST
|
|
)
|
|
{
|
|
CMD_INIT();
|
|
UpdateBreakPoint(2);
|
|
}
|
|
|
|
VOID
|
|
be(
|
|
CMD_ARGLIST
|
|
)
|
|
{
|
|
CMD_INIT();
|
|
UpdateBreakPoint(3);
|
|
}
|
|
|
|
|
|
VOID
|
|
bl(
|
|
CMD_ARGLIST
|
|
)
|
|
{
|
|
ULONG lpAddress;
|
|
VDM_BREAKPOINT VdmBreakPoint;
|
|
int BPNum;
|
|
int mode;
|
|
DWORD dist;
|
|
CHAR sym_text[255];
|
|
|
|
CMD_INIT();
|
|
|
|
lpAddress = (*GetExpression)("ntvdm!VdmBreakPoints");
|
|
|
|
if (!lpAddress) {
|
|
PRINTF("Could not find symbol ntvdm!VdmBreakPoints\n");
|
|
return;
|
|
}
|
|
|
|
for (BPNum = 0; BPNum < MAX_VDM_BREAKPOINTS;
|
|
BPNum++, lpAddress+=sizeof(VDM_BREAKPOINT)) {
|
|
|
|
if (!READMEM((PVOID)lpAddress, &VdmBreakPoint, sizeof(VDM_BREAKPOINT))) {
|
|
PRINTF("Error reading BP memory\n");
|
|
return;
|
|
}
|
|
|
|
if (VdmBreakPoint.Flags & VDMBP_SET) {
|
|
|
|
PRINTF("%d %s ", BPNum,
|
|
(VdmBreakPoint.Flags & VDMBP_ENABLED) ? "e" : "d");
|
|
|
|
if (VdmBreakPoint.Flags & VDMBP_V86) {
|
|
mode = V86_MODE;
|
|
PRINTF("&");
|
|
} else {
|
|
mode = PROT_MODE;
|
|
PRINTF("#");
|
|
}
|
|
|
|
PRINTF("%04X:", VdmBreakPoint.Seg);
|
|
|
|
if (VdmBreakPoint.Offset > 0xffff) {
|
|
PRINTF("%08X", VdmBreakPoint.Offset);
|
|
} else {
|
|
PRINTF("%04X", VdmBreakPoint.Offset);
|
|
}
|
|
|
|
PRINTF(" %04X:***", VdmBreakPoint.Count);
|
|
|
|
|
|
if (FindSymbol(VdmBreakPoint.Seg, VdmBreakPoint.Offset,
|
|
sym_text, &dist, BEFORE, mode )) {
|
|
|
|
if ( dist == 0 ) {
|
|
PRINTF(" %s\n", sym_text );
|
|
} else {
|
|
PRINTF(" %s+0x%lx\n", sym_text, dist );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
VOID
|
|
bp(
|
|
CMD_ARGLIST
|
|
)
|
|
{
|
|
ULONG lpAddress, lpTmp;
|
|
VDM_BREAKPOINT VdmBreakPoint;
|
|
int BPNum;
|
|
VDMCONTEXT ThreadContext;
|
|
WORD selector;
|
|
ULONG offset;
|
|
USHORT count = 1;
|
|
int mode;
|
|
USHORT flags = 0;
|
|
|
|
CMD_INIT();
|
|
|
|
lpAddress = (*GetExpression)("ntvdm!VdmBreakPoints");
|
|
|
|
if (!lpAddress) {
|
|
PRINTF("Could not find symbol ntvdm!VdmBreakPoints\n");
|
|
return;
|
|
}
|
|
|
|
mode = GetContext( &ThreadContext );
|
|
|
|
if (!GetNextToken()) {
|
|
PRINTF("Please enter an address\n");
|
|
return;
|
|
}
|
|
|
|
if (!ParseIntelAddress(&mode, &selector, &offset)) {
|
|
return;
|
|
}
|
|
|
|
if (mode == V86_MODE) {
|
|
flags = VDMBP_V86;
|
|
}
|
|
|
|
//
|
|
// first see if it's set already
|
|
//
|
|
for (lpTmp = lpAddress, BPNum = 0; BPNum < MAX_VDM_BREAKPOINTS;
|
|
BPNum++, lpTmp+=sizeof(VDM_BREAKPOINT)) {
|
|
|
|
if (!READMEM((PVOID)lpTmp, &VdmBreakPoint, sizeof(VDM_BREAKPOINT))) {
|
|
PRINTF("Error reading BP memory\n");
|
|
return;
|
|
}
|
|
|
|
if (VdmBreakPoint.Flags & VDMBP_SET) {
|
|
if ((VdmBreakPoint.Seg == selector) &&
|
|
(VdmBreakPoint.Offset == offset) &&
|
|
!(VdmBreakPoint.Flags ^ flags))
|
|
{
|
|
|
|
VdmBreakPoint.Count = count;
|
|
VdmBreakPoint.Flags |= VDMBP_FLUSH;
|
|
|
|
if (!(VdmBreakPoint.Flags & VDMBP_ENABLED)) {
|
|
EnableBreakPoint(&VdmBreakPoint);
|
|
}
|
|
|
|
WRITEMEM((PVOID)lpTmp, &VdmBreakPoint, sizeof(VDM_BREAKPOINT));
|
|
PRINTF("breakpoint %d redefined\n", BPNum);
|
|
return;
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
for (lpTmp = lpAddress, BPNum = 0; BPNum < MAX_VDM_BREAKPOINTS;
|
|
BPNum++,lpTmp+=sizeof(VDM_BREAKPOINT)) {
|
|
if (!READMEM((PVOID)lpTmp, &VdmBreakPoint, sizeof(VDM_BREAKPOINT))) {
|
|
PRINTF("Error reading BP memory\n");
|
|
return;
|
|
}
|
|
|
|
if (!(VdmBreakPoint.Flags & VDMBP_SET)) {
|
|
VdmBreakPoint.Seg = selector;
|
|
VdmBreakPoint.Offset = offset;
|
|
VdmBreakPoint.Count = count;
|
|
VdmBreakPoint.Flags = VDMBP_SET | VDMBP_FLUSH;
|
|
EnableBreakPoint(&VdmBreakPoint);
|
|
|
|
WRITEMEM((PVOID)lpTmp, &VdmBreakPoint, sizeof(VDM_BREAKPOINT));
|
|
return;
|
|
|
|
}
|
|
}
|
|
}
|