File:  [WindowsNT SDKs] / ntddk / src / video / displays / s3 / debug.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Thu Aug 9 18:31:12 2018 UTC (7 years, 9 months ago) by root
Branches: msft, MAIN
CVS tags: ntddk-nov-1993, HEAD
Microsoft Windows NT Build 511 (DDK SDK) 11-01-1993

/******************************Module*Header*******************************\
* Module Name: debug.c
*
* debug helper routines
*
* Copyright (c) 1992-1993 Microsoft Corporation
*
\**************************************************************************/

#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>

#include "driver.h"

#include <ntsdexts.h>

#include "lines.h"


#if DBG

#define LOG_SIZE_IN_BYTES 4000

typedef struct _LOGGER {
    ULONG ulEnd;
    ULONG ulCurrent;
    CHAR  achBuf[LOG_SIZE_IN_BYTES];
} DBGLOG;

#define GetAddress(dst, src)\
try {\
    dst = (VOID*) lpGetExpressionRoutine(src);\
} except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?\
            EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {\
    lpOutputRoutine("NTSD: Access violation on \"%s\", switch to server context\n", src);\
    return;\
}

DBGLOG glog = {0, 0};           // If you muck with this, fix 'dumplog' too
ULONG  DebugLevel = 0;
ULONG  LogLevel = 1;

#endif // DBG

/*****************************************************************************
 *
 *   Routine Description:
 *
 *      This function is variable-argument, level-sensitive debug print
 *      routine.
 *      If the specified debug level for the print statement is lower or equal
 *      to the current debug level, the message will be printed.
 *
 *   Arguments:
 *
 *      DebugPrintLevel - Specifies at which debugging level the string should
 *          be printed
 *
 *      DebugMessage - Variable argument ascii c string
 *
 *   Return Value:
 *
 *      None.
 *
 ***************************************************************************/

VOID
DebugPrint(
    ULONG DebugPrintLevel,
    PCHAR DebugMessage,
    ...
    )


{

#if DBG

    va_list ap;

    va_start(ap, DebugMessage);

    if (DebugPrintLevel <= DebugLevel) {

        char buffer[128];

        vsprintf(buffer, DebugMessage, ap);

        OutputDebugStringA(buffer);
    }

    va_end(ap);

#endif // DBG

} // DebugPrint()


/*****************************************************************************
 *
 *   Routine Description:
 *
 *      This function is variable-argument, level-sensitive debug log
 *      routine.
 *      If the specified debug level for the log statement is lower or equal
 *      to the current debug level, the message will be logged.
 *
 *   Arguments:
 *
 *      DebugLogLevel - Specifies at which debugging level the string should
 *          be logged
 *
 *      DebugMessage - Variable argument ascii c string
 *
 *   Return Value:
 *
 *      None.
 *
 ***************************************************************************/

VOID
DebugLog(
    ULONG DebugLogLevel,
    PCHAR DebugMessage,
    ...
    )


{

#if DBG

    va_list ap;

    va_start(ap, DebugMessage);

    if (DebugLogLevel <= LogLevel) {

        char buffer[128];
        int  length;

        length = vsprintf(buffer, DebugMessage, ap);

        length++;           // Don't forget '\0' terminator!

        // Wrap around to the beginning of the log if not enough room for
        // string:

        if (glog.ulCurrent + length >= LOG_SIZE_IN_BYTES) {
            glog.ulEnd     = glog.ulCurrent;
            glog.ulCurrent = 0;
        }

        memcpy(&glog.achBuf[glog.ulCurrent], buffer, length);
        glog.ulCurrent += length;
    }

    va_end(ap);

#endif // DBG

} // DebugLog()


/*****************************************************************************
 *
 *   Routine Description:
 *
 *       This function is called as an NTSD extension to dump a LineState
 *
 *   Arguments:
 *
 *       hCurrentProcess - Supplies a handle to the current process (at the
 *           time the extension was called).
 *
 *       hCurrentThread - Supplies a handle to the current thread (at the
 *           time the extension was called).
 *
 *       CurrentPc - Supplies the current pc at the time the extension is
 *           called.
 *
 *       lpExtensionApis - Supplies the address of the functions callable
 *           by this extension.
 *
 *       lpArgumentString - the float to display
 *
 *   Return Value:
 *
 *       None.
 *
 ***************************************************************************/
VOID dumplog(
    HANDLE hCurrentProcess,
    HANDLE hCurrentThread,
    DWORD dwCurrentPc,
    PNTSD_EXTENSION_APIS lpExtensionApis,
    LPSTR lpArgumentString)
{

#if DBG

    PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
    PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
    PNTSD_GET_SYMBOL     lpGetSymbolRoutine;

    ULONG       cFrom;
    ULONG       cTo;
    ULONG       cCurrent;
    DBGLOG*     plogOriginal;
    DBGLOG*     plog;
    ULONG       ulCurrent;
    ULONG       ulEnd;
    CHAR*       pchEnd;
    CHAR*       pch;

    UNREFERENCED_PARAMETER(hCurrentThread);
    UNREFERENCED_PARAMETER(dwCurrentPc);

    lpOutputRoutine        = lpExtensionApis->lpOutputRoutine;
    lpGetExpressionRoutine = lpExtensionApis->lpGetExpressionRoutine;
    lpGetSymbolRoutine     = lpExtensionApis->lpGetSymbolRoutine;

    lpOutputRoutine("!s3.dumplog [<from#> [<to#>]]\n\n");

    // Evaluate the argument string to get the address of
    // the Line Structure

    cTo   = 1;              // Defaults
    cFrom = 20;

    pch = strpbrk(lpArgumentString, "0123456789");
    if (pch != NULL)        // Use defaults if no args given
    {
        cFrom = atoi(pch);
        pch = strchr(pch, ' ');
        if (pch != NULL)
        {
            pch = strpbrk(pch, "0123456789");
            if (pch != NULL)
                cTo = atoi(pch);
        }
    }

    // Do some parameter validation, then read the log into the
    // debugger process's address space:

    if (cTo >= cFrom)
        cTo = cFrom;

    if (cTo < 1)
    {
        cTo   = 1;
        cFrom = 1;
    }

    GetAddress(plogOriginal, "glog");

    if (!ReadProcessMemory(hCurrentProcess,
                          (LPVOID) &(plogOriginal->ulCurrent),
                          &ulCurrent,
                          sizeof(ulCurrent),
                          NULL))
        return;

    if (!ReadProcessMemory(hCurrentProcess,
                          (LPVOID) &(plogOriginal->ulEnd),
                          &ulEnd,
                          sizeof(ulEnd),
                          NULL))
        return;

    if (ulCurrent == 0 && ulEnd == 0)
    {
        lpOutputRoutine("Log empty\n\n");
        return;
    }

    plog = (DBGLOG*) LocalAlloc(0, sizeof(DBGLOG) + 1);

    if (plog == NULL) {
        lpOutputRoutine("Couldn't allocate temporary buffer!\n");
        return;
    }

    if (!ReadProcessMemory(hCurrentProcess,
                          (LPVOID) &(plogOriginal->achBuf[0]),
                          &plog->achBuf[1],
                          LOG_SIZE_IN_BYTES,
                          NULL))
        return;

    // Mark the first byte in the buffer as being a zero, because
    // we're going to search backwards through the buffer for zeroes,
    // and we'll want to stop when we get to the beginning:

    plog->achBuf[0] = 0;
    ulCurrent++;
    ulEnd++;

    // Find the start string by going backwards through the buffer
    // and counting strings until the count becomes equal to 'cFrom':

    cCurrent = 0;
    pch      = &plog->achBuf[ulCurrent - 1];
    pchEnd   = &plog->achBuf[0];

    while (TRUE)
    {
        if (*(--pch) == 0)
        {
            cCurrent++;
            if (--cFrom == 0)
                break;

            if (pch == &plog->achBuf[ulCurrent - 1])
                break;         // We're back to where we started!
        }

        // Make sure we wrap the end of the buffer:

        if (pch <= pchEnd)
        {
            if (ulCurrent >= ulEnd)
                break;

            pch = &plog->achBuf[ulEnd - 1];
        }
    }

    // pch is pointing to zero byte before our start string:

    pch++;

    // Output the strings:

    pchEnd = &plog->achBuf[max(ulEnd, ulCurrent)];

    while (cCurrent >= cTo)
    {
        lpOutputRoutine("-%li: %s", cCurrent, pch);
        pch += strlen(pch) + 1;
        cCurrent--;

        // Make sure we wrap when we get to the end of the buffer:

        if (pch >= pchEnd)
            pch = &plog->achBuf[1];     // First char in buffer is a NULL
    }

    lpOutputRoutine("\n");
    LocalFree(plog);

#endif // DBG

    return;
}

/*****************************************************************************
 *
 *   Routine Description:
 *
 *       This function is called as an NTSD extension to dump
 *       the CRTC registers of an S3 chip
 *
 *   Arguments:
 *
 *       hCurrentProcess - Supplies a handle to the current process (at the
 *           time the extension was called).
 *
 *       hCurrentThread - Supplies a handle to the current thread (at the
 *           time the extension was called).
 *
 *       CurrentPc - Supplies the current pc at the time the extension is
 *           called.
 *
 *       lpExtensionApis - Supplies the address of the functions callable
 *           by this extension.
 *
 *       lpArgumentString - the float to display
 *
 *   Return Value:
 *
 *       None.
 *
 ***************************************************************************/
VOID dcrtc(
    HANDLE hCurrentProcess,
    HANDLE hCurrentThread,
    DWORD dwCurrentPc,
    PNTSD_EXTENSION_APIS lpExtensionApis,
    LPSTR lpArgumentString)
{

#if DBG

    PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
    PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
    PNTSD_GET_SYMBOL     lpGetSymbolRoutine;
    CHAR                 Symbol[64];
    DWORD                Displacement;
    BOOL                 b;

    BYTE    szBuff[256];
    INT     i;
    BYTE    ajCrtc[0x65];
    DWORD   dwAddr;

    UNREFERENCED_PARAMETER(hCurrentThread);
    UNREFERENCED_PARAMETER(dwCurrentPc);

    lpOutputRoutine        = lpExtensionApis->lpOutputRoutine;
    lpGetExpressionRoutine = lpExtensionApis->lpGetExpressionRoutine;
    lpGetSymbolRoutine     = lpExtensionApis->lpGetSymbolRoutine;

    //
    // Evaluate the argument string to get the address of
    // the Line Structure
    //

    dwAddr = (lpGetExpressionRoutine)(lpArgumentString);
    if (!dwAddr) {
        return;
    }

    //
    // Get the symbolic name
    //

    (lpGetSymbolRoutine)((LPVOID)dwAddr, Symbol, &Displacement);

    //
    // Read from the debuggees address space into our own.
    //

    b = ReadProcessMemory(hCurrentProcess,
                          (LPVOID)dwAddr,
                          ajCrtc,
                          sizeof(ajCrtc),
                          NULL);

    if (!b) {
        return;
    }

    for (i = 0; i < 0x65; i++)
    {
        sprintf(szBuff, "%4.4x: %2.2x\n", i, ajCrtc[i]);
        (lpOutputRoutine)(szBuff);
    }


#endif // DBG

    return;
}





/*****************************************************************************
 *
 *   Routine Description:
 *
 *       This function is called as an NTSD extension to dump a LineState
 *
 *   Arguments:
 *
 *       hCurrentProcess - Supplies a handle to the current process (at the
 *           time the extension was called).
 *
 *       hCurrentThread - Supplies a handle to the current thread (at the
 *           time the extension was called).
 *
 *       CurrentPc - Supplies the current pc at the time the extension is
 *           called.
 *
 *       lpExtensionApis - Supplies the address of the functions callable
 *           by this extension.
 *
 *       lpArgumentString - the float to display
 *
 *   Return Value:
 *
 *       None.
 *
 ***************************************************************************/
VOID dls(
    HANDLE hCurrentProcess,
    HANDLE hCurrentThread,
    DWORD dwCurrentPc,
    PNTSD_EXTENSION_APIS lpExtensionApis,
    LPSTR lpArgumentString)
{

#if DBG

    PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
    PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
    PNTSD_GET_SYMBOL     lpGetSymbolRoutine;
    CHAR                 Symbol[64];
    DWORD                Displacement;
    BOOL                 b;

    DWORD       dwAddr;
    LINESTATE   ls;
    BYTE        szBuff[256];

    UNREFERENCED_PARAMETER(hCurrentThread);
    UNREFERENCED_PARAMETER(dwCurrentPc);

    lpOutputRoutine        = lpExtensionApis->lpOutputRoutine;
    lpGetExpressionRoutine = lpExtensionApis->lpGetExpressionRoutine;
    lpGetSymbolRoutine     = lpExtensionApis->lpGetSymbolRoutine;

    //
    // Evaluate the argument string to get the address of
    // the Line Structure
    //

    dwAddr = (lpGetExpressionRoutine)(lpArgumentString);
    if (!dwAddr) {
        return;
    }

    //
    // Get the symbolic name
    //

    (lpGetSymbolRoutine)((LPVOID)dwAddr, Symbol, &Displacement);

    //
    // Read from the debuggees address space into our own.
    //

    b = ReadProcessMemory(hCurrentProcess,
                          (LPVOID)dwAddr,
                          &ls,
                          sizeof(ls),
                          NULL);

    if (!b) {
        return;
    }


    sprintf(szBuff, "LineState: %8.8x\n", dwAddr);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\tjAnd            : %2.2x\n", ls.jAnd);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\tjXor            : %2.2x\n", ls.jXor);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\tpspStart        : %4.4x\n", ls.pspStart);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\tpspEnd          : %4.4x\n", ls.pspEnd);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\tpsp             : %4.4x\n", ls.psp);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\tspRemaining     : %4.4x\n", ls.spRemaining);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\tspTotal         : %4.4x\n", ls.spTotal);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\tspTotal2        : %4.4x\n", ls.spTotal2);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\tspNext          : %4.4x\n", ls.spNext);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\tspComplex       : %4.4x\n", ls.spComplex);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\taspRtoL         : %4.4x\n", ls.aspRtoL);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\taspLtoR         : %4.4x\n", ls.aspLtoR);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\tulStyleMask     : %4.4x\n", ls.ulStyleMask);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\txyDensity       : %4.4x\n", ls.xyDensity);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\tcStyle          : %4.4x\n", ls.cStyle);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\tulStyleMaskLtoR : %4.4x\n", ls.ulStyleMaskLtoR);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\tulStyleMaskRtoL : %4.4x\n", ls.ulStyleMaskRtoL);
    (lpOutputRoutine)(szBuff);

    sprintf(szBuff, "\tulStartMask     : %4.4x\n", ls.ulStartMask);
    (lpOutputRoutine)(szBuff);

#endif // DBG

    return;
}

/*****************************************************************************
 *
 *   Routine Description:
 *
 *       This function is called as an NTSD extension to dump a dword
 *       (It's real function is as a prototype for other NT extensions.)
 *
 *   Arguments:
 *
 *       hCurrentProcess - Supplies a handle to the current process (at the
 *           time the extension was called).
 *
 *       hCurrentThread - Supplies a handle to the current thread (at the
 *           time the extension was called).
 *
 *       CurrentPc - Supplies the current pc at the time the extension is
 *           called.
 *
 *       lpExtensionApis - Supplies the address of the functions callable
 *           by this extension.
 *
 *       lpArgumentString - the float to display
 *
 *   Return Value:
 *
 *       None.
 *
 ***************************************************************************/
VOID dd(
    HANDLE hCurrentProcess,
    HANDLE hCurrentThread,
    DWORD dwCurrentPc,
    PNTSD_EXTENSION_APIS lpExtensionApis,
    LPSTR lpArgumentString)
{

#if DBG

    PNTSD_OUTPUT_ROUTINE lpOutputRoutine;
    PNTSD_GET_EXPRESSION lpGetExpressionRoutine;
    PNTSD_GET_SYMBOL     lpGetSymbolRoutine;
    CHAR                 Symbol[64];
    DWORD                Displacement;
    BOOL                 b;

    DWORD   dwAddr;
    DWORD   val;
    BYTE    szBuff[256];

    UNREFERENCED_PARAMETER(hCurrentThread);
    UNREFERENCED_PARAMETER(dwCurrentPc);

    lpOutputRoutine        = lpExtensionApis->lpOutputRoutine;
    lpGetExpressionRoutine = lpExtensionApis->lpGetExpressionRoutine;
    lpGetSymbolRoutine     = lpExtensionApis->lpGetSymbolRoutine;

    //
    // Evaluate the argument string to get the address of
    // the Line Structure
    //

    dwAddr = (lpGetExpressionRoutine)(lpArgumentString);
    if (!dwAddr) {
        return;
    }

    //
    // Get the symbolic name
    //

    (lpGetSymbolRoutine)((LPVOID)dwAddr, Symbol, &Displacement);

    //
    // Read from the debuggees address space into our own.
    //

    b = ReadProcessMemory(hCurrentProcess,
                          (LPVOID)dwAddr,
                          &val,
                          sizeof(val),
                          NULL);

    if (!b) {
        return;
    }

    sprintf(szBuff, "%8.8x: %8.8x\n", dwAddr, val);
    (lpOutputRoutine)(szBuff);
#endif // DBG

    return;
}


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.