⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kdctrl.c

📁 See Hanoi.cpp for the implementation of this cla
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 1990-2000  Microsoft Corporation.  All rights reserved.

Module Name:

    kdctrl.c

Abstract:

    This module implements CPU specific remote debug APIs.

Environment:

    WinCE

--*/

#include "kdp.h"

#if defined(x86)
int             __cdecl _inp(unsigned short);
int             __cdecl _outp(unsigned short, int);
unsigned short  __cdecl _inpw(unsigned short);
unsigned short  __cdecl _outpw(unsigned short, unsigned short);
unsigned long   __cdecl _inpd(unsigned short);
unsigned long   __cdecl _outpd(unsigned short, unsigned long);
#pragma intrinsic(_inp, _inpw, _inpd, _outp, _outpw, _outpd)
extern PTHREAD g_CurFPUOwner;
#endif

extern BOOLEAN KdpSendContext;
extern PROCESS *kdProcArray;
extern ROMHDR * const pTOC;
extern PCALLSTACK pStk;
extern PPROCESS pLastProc;
extern PTHREAD pWalkThread;
//void NKOtherPrintfA(char *szFormat, ...);

BOOLEAN bGlobalBreakPoint;

BOOL fThreadWalk;

DWORD ReloadAllSymbols(LPBYTE lpBuffer, BOOL fDoCopy);
#if defined(MIPS) || defined(x86) || defined(PPC)
void CpuContextToContext(CONTEXT *pCtx, CPUCONTEXT *pCpuCtx);
#endif
//BOOL GetNameandImageBase(PPROCESS pProc, DWORD dwAddress, PNAMEANDBASE pnb, BOOL fRedundant);

VOID
KdpSetLoadState (
    IN PDBGKD_WAIT_STATE_CHANGE WaitStateChange,
    IN PCONTEXT ContextRecord
    )

/*++

Routine Description:

    Fill in the Wait_State_Change message record for the load symbol case.

Arguments:

    WaitStateChange - Supplies pointer to record to fill in

    ContextRecord - Supplies a pointer to a context record.

Return Value:

    None.

--*/

{
    //
    //  Copy context record
    //
    WaitStateChange->Context = *ContextRecord;
    return;
}

VOID
KdpSetStateChange (
    IN PDBGKD_WAIT_STATE_CHANGE WaitStateChange,
    IN PEXCEPTION_RECORD ExceptionRecord,
    IN PCONTEXT ContextRecord,
    IN BOOLEAN SecondChance
    )

/*++

Routine Description:

    Fill in the Wait_State_Change message record.

Arguments:

    WaitStateChange - Supplies pointer to record to fill in

    ExceptionRecord - Supplies a pointer to an exception record.

    ContextRecord - Supplies a pointer to a context record.

    SecondChance - Supplies a boolean value that determines whether this is
        the first or second chance for the exception.

Return Value:

    None.

--*/

{

    ULONG   Index;
    ULONG   Offset;
    PVOID   Lower;
    PVOID   Upper;
#if defined(MIPS16SUPPORT) || defined(THUMBSUPPORT)
    KDP_BREAKPOINT_TYPE Instruction;
    ULONG Length;
#endif

    //
    //  Set up description of event, including exception record
    //

    WaitStateChange->NewState = DbgKdExceptionStateChange;
    WaitStateChange->ProcessorType = 0;
    WaitStateChange->Processor = (USHORT)0;
    WaitStateChange->NumberProcessors = (ULONG)1;
    WaitStateChange->Thread = (PVOID)hCurThread;
    WaitStateChange->ProgramCounter = (PVOID)CONTEXT_TO_PROGRAM_COUNTER(ContextRecord);
    KdpQuickMoveMemory(
                (PCHAR)&WaitStateChange->u.Exception.ExceptionRecord,
                (PCHAR)ExceptionRecord,
                sizeof(EXCEPTION_RECORD)
                );
    WaitStateChange->u.Exception.FirstChance = !SecondChance;

    //
    //  Copy instruction stream immediately following location of event
    //

    WaitStateChange->ControlReport.InstructionCount =
        (WORD)KdpMoveMemory(
            &(WaitStateChange->ControlReport.InstructionStream[0]),
            WaitStateChange->ProgramCounter,
            DBGKD_MAXSTREAM
            );

#if defined(SH3)
    ContextRecord->DebugRegisters.BarA  = READ_REGISTER_ULONG(UBCBarA);
    ContextRecord->DebugRegisters.BasrA = READ_REGISTER_UCHAR(UBCBasrA);
    ContextRecord->DebugRegisters.BamrA = READ_REGISTER_UCHAR(UBCBamrA);
    ContextRecord->DebugRegisters.BbrA  = READ_REGISTER_USHORT(UBCBbrA); 
    ContextRecord->DebugRegisters.BarB  = READ_REGISTER_ULONG(UBCBarB);
    ContextRecord->DebugRegisters.BasrB = READ_REGISTER_UCHAR(UBCBasrB);
    ContextRecord->DebugRegisters.BamrB = READ_REGISTER_UCHAR(UBCBamrB);
    ContextRecord->DebugRegisters.BbrB  = READ_REGISTER_USHORT(UBCBbrB); 
    ContextRecord->DebugRegisters.BdrB  = READ_REGISTER_ULONG(UBCBdrB);
    ContextRecord->DebugRegisters.BdmrB = READ_REGISTER_ULONG(UBCBdmrB);
    ContextRecord->DebugRegisters.Brcr  = READ_REGISTER_USHORT(UBCBrcr);
    ContextRecord->DebugRegisters.Align = 0;
#elif defined(SH3e) || defined(SH4)
    WaitStateChange->DebugRegisters.BarA  = READ_REGISTER_ULONG(UBCBarA);
    WaitStateChange->DebugRegisters.BasrA = READ_REGISTER_UCHAR(UBCBasrA);
    WaitStateChange->DebugRegisters.BamrA = READ_REGISTER_UCHAR(UBCBamrA);
    WaitStateChange->DebugRegisters.BbrA  = READ_REGISTER_USHORT(UBCBbrA); 
    WaitStateChange->DebugRegisters.BarB  = READ_REGISTER_ULONG(UBCBarB);
    WaitStateChange->DebugRegisters.BasrB = READ_REGISTER_UCHAR(UBCBasrB);
    WaitStateChange->DebugRegisters.BamrB = READ_REGISTER_UCHAR(UBCBamrB);
    WaitStateChange->DebugRegisters.BbrB  = READ_REGISTER_USHORT(UBCBbrB); 
    WaitStateChange->DebugRegisters.BdrB  = READ_REGISTER_ULONG(UBCBdrB);
    WaitStateChange->DebugRegisters.BdmrB = READ_REGISTER_ULONG(UBCBdmrB);
    WaitStateChange->DebugRegisters.Brcr  = READ_REGISTER_USHORT(UBCBrcr);
    WaitStateChange->DebugRegisters.Align = 0;
#endif

#if defined(x86)
    if (g_CurFPUOwner) 
    {
        KCall((LPVOID)FPUFlushContext,0,0,0);
        ContextRecord->FloatSave = *(PTH_TO_FLTSAVEAREAPTR(pCurThread));
    }
#endif

    //
    //  Copy context record immediately following instruction stream
    //
    WaitStateChange->Context = *ContextRecord;

    //
    // Examine each entry in the table in turn
    //

    for (Index = 0; Index < BREAKPOINT_TABLE_SIZE; Index++) {
        Lower = WaitStateChange->ProgramCounter;
        Upper = (PVOID)((PUCHAR)WaitStateChange->ProgramCounter +
                       WaitStateChange->ControlReport.InstructionCount - 1);

        if ( (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_IN_USE) &&
             ((KdpBreakpointTable[Index].Address >= Lower) &&
              (KdpBreakpointTable[Index].Address <= Upper))
           ) {

            //
            // Breakpoint is in use and falls in range, restore original
            // code in WaitStateChange InstructionStream 
            //

#if defined(MIPS16SUPPORT) || defined(THUMBSUPPORT)
            if (KdpBreakpointTable[Index].Flags & KD_BREAKPOINT_16BIT) {
                Instruction = KDP_BREAKPOINT_16BIT_VALUE;
                Length = sizeof(KDP_BREAKPOINT_16BIT_TYPE);
            } else {
                Instruction = KDP_BREAKPOINT_32BIT_VALUE;
                Length = sizeof(KDP_BREAKPOINT_32BIT_TYPE);
            }

            if (KdpBreakpointTable[Index].Content != Instruction) {
                Offset = (ULONG)KdpBreakpointTable[Index].Address -
                         (ULONG)Lower;
                KdpMoveMemory(
                    &(WaitStateChange->ControlReport.InstructionStream[0])
                    + Offset,
                    (PCHAR)&KdpBreakpointTable[Index].Content,
                    Length
                );
            }

#else
            if (KdpBreakpointTable[Index].Content != KdpBreakpointInstruction) {
                Offset = (ULONG)KdpBreakpointTable[Index].Address -
                         (ULONG)Lower;
                KdpMoveMemory(
                    &(WaitStateChange->ControlReport.InstructionStream[0])
                    + Offset,
                    (PCHAR)&KdpBreakpointTable[Index].Content,
                    sizeof(KDP_BREAKPOINT_TYPE)
                    );
            }
#endif
        }
    }
#if defined(x86)
        WaitStateChange->ControlReport.Dr6 = ContextRecord->Dr6;
    WaitStateChange->ControlReport.Dr7 = ContextRecord->Dr7;

	    WaitStateChange->ControlReport.SegCs = (WORD)ContextRecord->SegCs;
    WaitStateChange->ControlReport.SegDs = (WORD)ContextRecord->SegDs;
    WaitStateChange->ControlReport.SegEs = (WORD)ContextRecord->SegEs;
    WaitStateChange->ControlReport.SegFs = (WORD)ContextRecord->SegFs;

    WaitStateChange->ControlReport.EFlags = ContextRecord->EFlags;

    WaitStateChange->ControlReport.ReportFlags = REPORT_INCLUDES_SEGS;
#endif
}

VOID
KdpGetStateChange (
    IN PDBGKD_MANIPULATE_STATE ManipulateState,
    IN PCONTEXT ContextRecord
    )

/*++

Routine Description:

    Extract continuation control data from Manipulate_State message

    N.B. This is a noop for MIPS.

Arguments:

    ManipulateState - supplies pointer to Manipulate_State packet

    ContextRecord - Supplies a pointer to a context record.

Return Value:

    None.

--*/

{
#if defined(x86)
    PDBGKD_CONTROL_SET pControlSet;

    pControlSet = &ManipulateState->u.Continue2.ControlSet;

    if (pControlSet->TraceFlag)
    {
        ContextRecord->EFlags |= 0x00000100;     // TF
    }
    else
    {
        ContextRecord->EFlags &= ~0x00000100;    // TF
    }

        ContextRecord->Dr6 = 0;

    ContextRecord->Dr7 = pControlSet->Dr7;
#endif
}


BOOL CheckIfPThreadExists (PTHREAD pThreadToValidate)

{
    DWORD dwProcessIdx;
    PTHREAD pThread;

    for (dwProcessIdx = 0; dwProcessIdx < MAX_PROCESSES; dwProcessIdx++)    
    { // For each process:
        if (kdProcArray [dwProcessIdx].dwVMBase)
        { // Only if VM Base Addr of process is valid (not null):
            for (pThread = kdProcArray [dwProcessIdx].pTh; // Get process main thread
                 pThread;
                 pThread = pThread->pNextInProc) // Next thread
            { // walk list of threads attached to process (until we reach the end of the list or we found the matching pThread)
                if (pThreadToValidate == pThread) return TRUE;
            }
        }
    }
    return FALSE;
}

// Prevent HIGHADJ/LOW/LOW fixup problem
#if defined(PPC)
#pragma optimize("", off)
#endif

VOID
KdpReadControlSpace (
    IN PDBGKD_MANIPULATE_STATE m,
    IN PSTRING AdditionalData,
    IN PCONTEXT Context
    )

/*++

Routine Description:

    This function is called in response of a read control space state
    manipulation message.  Its function is to read implementation
    specific system data.

Arguments:

    m - Supplies the state manipulation message.

    AdditionalData - Supplies any additional data for the message.

    Context - Supplies the current context.

Return Value:

    None.

--*/

{

    PDBGKD_READ_MEMORY a = &m->u.ReadMemory;
    STRING MessageHeader;
    ULONG Process;
    ULONG NextOffset;
    DWORD dwReturnAddr;
    DWORD dwFrameTop = 0;
	PCALLSTACK pStackTemp;

    MessageHeader.Length = sizeof(*m);
    MessageHeader.Buffer = (PCHAR)m;

    m->ReturnStatus = STATUS_UNSUCCESSFUL; // By default (shorter and safer)

    //
    // TargetBaseAddress field is being used as the ControlSpace request id 
    //
    switch((ULONG)a->TargetBaseAddress) {

        case HANDLE_PROCESS_THREAD_INFO_REQ: // Replacing HANDLE_PROCESS_INFO_REQUEST

            GetProcessAndThreadInfo (AdditionalData);
            m->ReturnStatus = STATUS_SUCCESS; // the return status is in the message itself
            break;

        case HANDLE_PROCESS_INFO_REQUEST: // To be replaced by HANDLE_PROCESS_THREAD_INFO_REQ later (when no debugger using it is left)

            if (AdditionalData->Length > 0) {

                //
                // The request is for information on a specific process
                //

                Process = SH3strtoul(AdditionalData->Buffer, 16);
                
                AdditionalData->Length =
                    (USHORT)GetSpecificProcessInfo((PPROCESS)Process, 
                                                   AdditionalData->Buffer,
                                                   a->TransferCount);
            }
            else {

                //
                // Get process table...(truncation OK -> USHORT always 2 bytes)
                //  

                AdditionalData->Length = (USHORT)GetProcessInfo((PBYTE)AdditionalData->Buffer, a->TransferCount);
            }

            m->ReturnStatus = STATUS_SUCCESS;

            break;

        case HANDLE_GET_NEXT_OFFSET_REQUEST:

            if (AdditionalData->Length != sizeof(ULONG)) {
                AdditionalData->Length = 0;
                break; // Unsucessful
            }

            memcpy((PVOID)&NextOffset, (PVOID)AdditionalData->Buffer, sizeof(ULONG));

            if (!TranslateAddress(&NextOffset)) {
                AdditionalData->Length = 0;
                break; // Unsucessful
            }

            memcpy((PVOID)AdditionalData->Buffer, (PVOID)&NextOffset, sizeof(ULONG));


            m->ReturnStatus = STATUS_SUCCESS;
            AdditionalData->Length = sizeof(ULONG);

            break;

        case HANDLE_STACKWALK_REQUEST:
            //
            // The request is to translate a stack address
            //
            DEBUGGERMSG(KDZONE_STACKW, (L"+++ Read HANDLE_STACKWALK_REQUEST\r\n"));

            if ((AdditionalData->Length != sizeof(DWORD)) && (AdditionalData->Length != (sizeof(DWORD)*2)))
            {
                DEBUGGERMSG(KDZONE_STACKW, (L"Bad AdditionalData Length = %i\r\n--- Read HANDLE_STACKWALK_REQUEST\r\n", AdditionalData->Length));
                AdditionalData->Length = 0;
                break; // Unsucessful
            }

            memcpy((PVOID)&dwReturnAddr, (PVOID)AdditionalData->Buffer, sizeof(DWORD));
            if (AdditionalData->Length == (sizeof(DWORD)*2))
            {
                memcpy((PVOID)&dwFrameTop, (PVOID)(AdditionalData->Buffer+sizeof(DWORD)), sizeof(DWORD));
            }
            else
            {
                dwFrameTop = 0;
            }

            DEBUGGERMSG(KDZONE_STACKW, (TEXT("RCS: StalkWalk: Additional Length=%8.8lx - dwReturnAddr passed in = %8.8lx - dwFrameTop = %8.8lx \r\n"), AdditionalData->Length, dwReturnAddr, dwFrameTop));
  
            if (!TranslateRA(&dwReturnAddr, pWalkThread, dwFrameTop)) {
                DEBUGGERMSG( KDZONE_CTRL, (TEXT("**** RCS: StalkWalk: TranslateRA  **** FAILED **** on pWalkThread=%08X RA=%08X FP=%08X\r\n"), pWalkThread, dwReturnAddr, dwFrameTop));
                AdditionalData->Length = 0;
                DEBUGGERMSG(KDZONE_STACKW, (L"--- Read HANDLE_STACKWALK_REQUEST\r\n"));
                break; // Unsucessful
            }
            DEBUGGERMSG(KDZONE_STACKW, (TEXT("RCS: StalkWalk: pStk=%8.8lx dwReturnAddr=%8.8lx dwFrameTop=%8.8lx pWalkThread=%8.8lx\r\n"), pStk, dwReturnAddr, dwFrameTop, pWalkThread));

            memcpy((PVOID)AdditionalData->Buffer, (PVOID)&dwReturnAddr, sizeof(ULONG));

            m->ReturnStatus = STATUS_SUCCESS;
            AdditionalData->Length = sizeof(DWORD);

            DEBUGGERMSG(KDZONE_STACKW, (L"--- Read HANDLE_STACKWALK_REQUEST\r\n"));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -