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

📄 ints.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
字号:
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <stdio.h>
#include <windows.h>
#include <string.h>
#include <dos.h>
#include "wdebug.h"

#define MAX_ISTACK      4096

typedef union {
    char        bytes[8];
    unsigned    short words[4];
} idt;

idt     IdtInt1,IdtInt3;
idt     NewIdtInt1,NewIdtInt3;
char    IStack[MAX_ISTACK];
WORD    SetCount = 0;
WORD    IntAccessed = 0;

extern DWORD    SaveEAX;
extern WORD     DPL;
extern WORD     CopySize;
extern WORD     OurOwnInt;
extern WORD     IDTSel;
extern WORD     InterruptStackSel;
extern DWORD    InterruptStackOff;


#pragma aux _CopyMemory parm [cx] [dx di] [ax] [si bx] value[ax];
extern short _CopyMemory( WORD, DWORD, WORD, DWORD );
extern void GetIDTSel( void );
extern void ReleaseIDTSel( void );
extern void InterruptCallback( void );

extern void ReflectInt1Int3( void );

/*
 * CopyMemory - use wgod to copy between two arbitrary selectors
 */
WORD CopyMemory( WORD dseg, DWORD doff, WORD sseg, DWORD soff, WORD size )
{
    CopySize = size;
    return( _CopyMemory( dseg, doff, sseg, soff ) );

} /* CopyMemory */

/*
 * SetDebugInterrupts32
 *
 * called to setup for 32-bit interrupts (by debugger or Dr. WATCOM)
 *
 * - check for WDEBUG.386 (can't work without it!)
 * - stomp the IDT for INT1 and INT3.  What actually happens is that
 *   WDEBUG.386 stomps the IDT to point at its own routine in the 32-bit
 *   world.  This routine sets some internal state so that it knows
 *   that an int1/3 occurred, and then calls the 16-bit routine that
 *   we provide using HookIDT.  This routine must cause some fault,
 *   (in our case, we cause an illegal instruction fault), which then
 *   causes us to go through the normal fault handling.
 *   NOTE: after a int1/3 occurs, the WDEBUG.386 restores the IDT back
 *   to normal.  Thus, when you wish to start handling int1/int3's again,
 *   the IDT must be reset to our handler (DoneWithInterrupt does this)
 *
 * - register our interrupt callback routine with WDEBUG.386.  This routine
 *   is invoked whenever a 32-bit fault occurs.  The routine runs on a
 *   stack that we specify.  WDEBUG.386 copies the register information
 *   into the provided structure (&SaveEAX) before it invokes the callback
 *   routine. NOTE:  "invoking" the callback routine really means that
 *   WDEBUG.386 changes the registers of the Windows VM such that the
 *   next time it runs, it begins execution at the callback routine.
 *   No actual calls occur.
 */
int __export FAR PASCAL SetDebugInterrupts32( void )
{
    SetCount++;
    if( SetCount > 1 ) {
        return( 1 );
    }

    if( CheckWin386Debug() != WGOD_VERSION ) {
        return( 0 );
    }
    DPL = (CS() & 0x03) << 5;
    OurOwnInt = 0;

    /*
     * set up our IDT
     */
    GetIDTSel();
    IDTInit( IDTSel );
    HookIDT( ReflectInt1Int3 );

    InterruptStackSel = FP_SEG( IStack );
    InterruptStackOff = (DWORD) (FP_OFF( IStack ) + MAX_ISTACK-16);


    /*
     * set up to be notified of faults by wgod
     */
    RegisterInterruptCallback( (LPVOID) InterruptCallback,
                        (LPVOID) &SaveEAX,
                        (LPVOID) &IStack[MAX_ISTACK-16] );

    return( 1 );


} /* SetDebugInterrupts32 */

/*
 * ResetDebugInterrupts32:
 *
 * This routine is called when someone is done using WINT32.DLL for
 * trapping 32-bit interrupts.  We restore the IDT, and unregister
 * our interrupt callback
 */
void __export FAR PASCAL ResetDebugInterrupts32( void )
{
    SetCount--;
    if( SetCount == 0 ) {
        CopyMemory( IDTSel, (DWORD) 1*8, DS(), (DWORD) &IdtInt1, 8 );
        CopyMemory( IDTSel, (DWORD) 3*8, DS(), (DWORD) &IdtInt3, 8 );
        IDTFini();
        ReleaseIDTSel();
        UnRegisterInterruptCallback( (LPVOID) InterruptCallback );
    }

} /* ResetDebugInterrupts32 */

/*
 * GetDebugInterruptData:
 *
 * called by someone to find out if the fault they got was a 32-bit fault.
 * If it was a 32-bit fault, then the register data is copied into a
 * specified data area.
 *
 * This routine must be followed by a DoneWithInterrupt call, otherwise
 * the INT1/INT3 IDT hooks will not be restored.
 */
BOOL __export FAR PASCAL GetDebugInterruptData( LPVOID data )
{
    if( OurOwnInt == 0 ) {
        return( 0 );
    }
    if( data != NULL ) {
        memcpy( data, &SaveEAX, sizeof( interrupt_struct ) );
    }
    IntAccessed++;
    return( 1 );

} /* GetDebugInterruptData */

/*
 * DoneWithInterrupt:
 *
 * called when someone is done handling a 32-bit fault.  The registers
 * are copied back to the data area for reloading by WDEBUG.386, and
 * the IDT is reset to point at our int1/3 handler.
 */
void __export FAR PASCAL DoneWithInterrupt( LPVOID data )
{
    if( data != NULL ) {
        memcpy( &SaveEAX, data, sizeof( interrupt_struct ) );
    }
    IntAccessed--;
    if( (int)IntAccessed <= 0 ) {
        IDTInit( IDTSel );
        HookIDT( ReflectInt1Int3 );
        OurOwnInt = 0;
    }

} /* DoneWithInterrupt */

int DebuggerCount = 0;

/*
 * IsDebuggerExecuting:
 *
 * called by Dr. WATCOM (or anyone else in the future) to see if there
 * is a debugger using WINT32.DLL
 */
BOOL __export FAR PASCAL IsDebuggerExecuting( void )
{
    return( DebuggerCount );

} /* IsDebuggerExecuting */

/*
 * DebuggerIsExecuting:
 *
 * called by the debugger to let Dr. WATCOM (or anyone else in the future)
 * know that it is executing and should not handle any faults or
 * notifications.
 *
 */
void __export FAR PASCAL DebuggerIsExecuting( int cnt )
{
    DebuggerCount += cnt;

} /* IsDebuggerExecuting */

⌨️ 快捷键说明

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