summaryrefslogblamecommitdiffstats
path: root/private/mvdm/ieuvddex/trace.c
blob: 7ac1aea9e14ac40c8ffa8c69cc28d28b3421cd78 (plain) (tree)











































































































































































































































































































































































                                                                                                  
/*++

Copyright (c) 1991  Microsoft Corporation

Module Name:

    trace.c

Abstract:

    This file contains code to dump the dpmi trace table

Author:

    Neil Sandlin (neilsa) 1-Nov-1995

Revision History:

--*/

#include <ieuvddex.h>
#include <stdio.h>
#include <dpmi.h>


HANDLE hCurrentProcess;
//
// Local constants
//

#define ReadDword(addr, value) ReadProcessMem( CurrentProcess, \
                               (LPVOID) addr, &value,           \
                               sizeof(ULONG), NULL )

#define WriteDword(addr, value) WriteProcessMem( CurrentProcess,   \
                               (LPVOID) addr, &value,              \
                               sizeof(ULONG), NULL )


BOOL
ReadMemExpression(
    LPSTR expr,
    LPVOID buffer,
    ULONG len
    )
{
    PVOID pMem;

    pMem = (PVOID)(*GetExpression)(expr);
    if (!pMem) {
        PRINTF("DPMI trace history not available\n");
        return FALSE;
    }

    if (!ReadProcessMem(hCurrentProcess, pMem, buffer, len, NULL)) {
        PRINTF("Error reading memory\n");
        return FALSE;
    }

    return TRUE;
}

VOID
DumpTraceEntry(
    int index,
    DPMI_TRACE_ENTRY TraceEntry,
    ULONG Verbosity
    )

{
    PRINTF("%4x ",index);

    switch(TraceEntry.Type) {

    case DPMI_SET_PMODE_INT_HANDLER:
        PRINTF("SetPModeInt  %.2x -> %.4x:%.8x", TraceEntry.v1, TraceEntry.v2, TraceEntry.v3);
        break;

    case DPMI_SET_FAULT_HANDLER:
        PRINTF("SetFault     %.2x -> %.4x:%.8x", TraceEntry.v1, TraceEntry.v2, TraceEntry.v3);
        break;

    case DPMI_DISPATCH_INT:
        PRINTF("Dispatch Int %.2x ", TraceEntry.v1);
        break;
    case DPMI_HW_INT:
        PRINTF("Hw Int       %.2x ", TraceEntry.v1);
        break;
    case DPMI_SW_INT:
        PRINTF("Sw Int       %.2x ", TraceEntry.v1);
        break;

    case DPMI_FAULT:
        PRINTF("Fault        %.2x ec=%.8x", TraceEntry.v1, TraceEntry.v2);
        break;
    case DPMI_DISPATCH_FAULT:
        PRINTF("Dispatch Flt %.2x ", TraceEntry.v1);
        break;

    case DPMI_FAULT_IRET:
        PRINTF("Fault Iret");
        break;
    case DPMI_INT_IRET16:
        PRINTF("Int Iret16");
        break;
    case DPMI_INT_IRET32:
        PRINTF("Int Iret32");
        break;

    case DPMI_OP_EMULATION:
        PRINTF("Op Emulation");
        break;

    default:
        PRINTF("Unknown Trace Entry : %d\n", TraceEntry.Type);
        return;
    }

    if (Verbosity) {
        PRINTF("\n");
        PRINTF("eax=%08lx ebx=%08lx ecx=%08lx edx=%08lx esi=%08lx edi=%08lx\n",
            TraceEntry.eax,
            TraceEntry.ebx,
            TraceEntry.ecx,
            TraceEntry.edx,
            TraceEntry.esi,
            TraceEntry.edi );
        PRINTF("eip=%08lx esp=%08lx ebp=%08lx                ",
            TraceEntry.eip,
            TraceEntry.esp,
            TraceEntry.ebp );
        if ( TraceEntry.eflags & FLAG_OVERFLOW ) {
            PRINTF("ov ");
        } else {
            PRINTF("nv ");
        }
        if ( TraceEntry.eflags & FLAG_DIRECTION ) {
            PRINTF("dn ");
        } else {
            PRINTF("up ");
        }
        if ( TraceEntry.eflags & FLAG_INTERRUPT ) {
            PRINTF("ei ");
        } else {
            PRINTF("di ");
        }
        if ( TraceEntry.eflags & FLAG_SIGN ) {
            PRINTF("ng ");
        } else {
            PRINTF("pl ");
        }
        if ( TraceEntry.eflags & FLAG_ZERO ) {
            PRINTF("zr ");
        } else {
            PRINTF("nz ");
        }
        if ( TraceEntry.eflags & FLAG_AUXILLIARY ) {
            PRINTF("ac ");
        } else {
            PRINTF("na ");
        }
        if ( TraceEntry.eflags & FLAG_PARITY ) {
            PRINTF("po ");
        } else {
            PRINTF("pe ");
        }
        if ( TraceEntry.eflags & FLAG_CARRY ) {
            PRINTF("cy ");
        } else {
            PRINTF("nc ");
        }
        PRINTF("\n");
        PRINTF("cs=%04x  ss=%04x  ds=%04x  es=%04x  fs=%04x  gs=%04x             efl=%08lx\n",
                TraceEntry.cs,
                TraceEntry.ss,
                TraceEntry.ds,
                TraceEntry.es,
                TraceEntry.fs,
                TraceEntry.gs,
                TraceEntry.eflags );
    }

    PRINTF("\n");

}


VOID
DumpTrace(
    IN HANDLE CurrentProcess,
    IN HANDLE CurrentThread,
    IN LPSTR ArgumentString,
    IN ULONG Verbosity
    )
/*++

Routine Description:

    This routine dumps the DPMI trace history buffer.

Arguments:

    CurrentProcess -- Supplies a handle to the process to dump selectors for
    CurrentThread -- Supplies a handle to the thread to dump selectors for
    ArgumentString -- Supplies the arguments to the !sel command

Return Value

    None.

--*/
{
    PVOID pMem;
    BOOL bTrace;
    int TraceCount, TraceIndex, MaxEntries;
    int index;
    int Lines;
    int i;
    DPMI_TRACE_ENTRY TraceEntry;
    ULONG TraceTableBase;

    hCurrentProcess = CurrentProcess;

    TraceTableBase = (ULONG)(*GetExpression)("ntvdm!DpmiTraceTable");
    if (!TraceTableBase) {
        PRINTF("DPMI trace history not available\n");
        return;
    }

    if (!ReadMemExpression("ntvdm!bDpmiTraceOn", &bTrace, 4)) {
        return;
    }

    if (!bTrace) {
        PRINTF("Trace is not on\n");
        return;
    }

    if (!ReadMemExpression("ntvdm!DpmiTraceCount", &TraceCount, 4)) {
        return;
    }

    if (!TraceCount) {
        PRINTF("Trace history buffer is empty\n");
        return;
    }

    if (!ReadMemExpression("ntvdm!DpmiTraceIndex", &TraceIndex, 4)) {
        return;
    }

    if (!ReadMemExpression("ntvdm!DpmiMaxTraceEntries", &MaxEntries, 4)) {
        return;
    }
    PRINTF("TraceBuffer contains %d entries, current index=%d, max=%d\n",
                                TraceCount, TraceIndex, MaxEntries);

    if ((TraceCount < 0) || (TraceCount > 2000) ||
        (TraceIndex < 0) || (TraceIndex > 2000) ||
        (MaxEntries < 0) || (MaxEntries > 2000)) {
        PRINTF("Trace buffer appears corrupt!\n");
        return;
    }

    Lines = (int)(*GetExpression)(ArgumentString);
    if (!Lines) {
        if (Verbosity) {
            Lines = 12;
        } else {
            Lines = 50;
        }
    }


    if (Lines > TraceCount) {
        Lines = TraceCount;
    }

    index = TraceIndex - Lines;
    if (index<0) {
        index += MaxEntries;
    }

    for (i=0; i<Lines; i++) {

        pMem = (PVOID) (TraceTableBase + index*sizeof(DPMI_TRACE_ENTRY));

        if (!ReadProcessMem(hCurrentProcess, pMem, &TraceEntry, sizeof(DPMI_TRACE_ENTRY), NULL)) {
            PRINTF("Error reading memory\n");
            return;
        }


        DumpTraceEntry(index, TraceEntry, Verbosity);

        index++;
        if (index >= MaxEntries) {
            index = 0;
        }
    }


}



VOID
TraceControl(
    IN HANDLE CurrentProcess,
    IN HANDLE CurrentThread,
    IN LPSTR ArgumentString
    )
/*++

Routine Description:

    This routine dumps LDT selectors.  The selectors are dumped from the
    user mode Ldt, rather than the system ldt.

Arguments:

    CurrentProcess -- Supplies a handle to the process to dump selectors for
    CurrentThread -- Supplies a handle to the thread to dump selectors for
    ArgumentString -- Supplies the arguments to the !sel command

Return Value

    None.

--*/
{

    PVOID pMem;
    BOOL bTrace;
    int Count;
    hCurrentProcess = CurrentProcess;

    if (!ReadMemExpression("ntvdm!bDpmiTraceOn", &bTrace, 4)) {
        return;
    }
    pMem = (PVOID)(*GetExpression)("ntvdm!bDpmiTraceOn");
    if (!pMem) {
        PRINTF("DPMI trace history not available\n");
        return;
    }

    if (!ReadDword(pMem, bTrace)) {
        PRINTF("Error reading memory\n");
        return;
    }

    if (!bTrace) {
        int Count = 0;
        bTrace = 1;
        WriteDword(pMem, bTrace);
        pMem = (PVOID)(*GetExpression)("ntvdm!bDpmiTraceCount");
        WriteDword(pMem, Count);
        (*Print)("Trace is now on and reset\n");
    } else {
        bTrace = 0;
        WriteDword(pMem, bTrace);
        (*Print)("Trace is now off\n");
    }
}