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

📄 os2v2acc.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************
*
*                            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:  OS/2 2.x specific debug core.
*
****************************************************************************/


#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define INCL_DOSEXCEPTIONS
#define INCL_DOSPROCESS
#define INCL_DOSMISC
#define INCL_DOSERRORS
#define INCL_DOSSESMGR
#define INCL_DOSMODULEMGR
#include <os2.h>
#include "dosdebug.h"
#include "trpimp.h"
#include "os2trap.h"
#include "os2v2acc.h"
#include "bsexcpt.h"
#include "wdpmhelp.h"
#include "softmode.h"
#include "madregs.h"
#define ERROR_DEFINE_CONSTS
#include "os2err.h"
#include "exedos.h"
#include "exeos2.h"
#include "exeflat.h"
#include "x86cpu.h"

uDB_t                   Buff;
static BOOL             stopOnSecond;
static BOOL             isAttached;
USHORT                  TaskFS;
static byte             saved_splice_bp;
static BOOL             splice_bp_set;
static ULONG            splice_bp_lin_addr;
extern VOID             InitDebugThread( VOID );

#ifdef DEBUG_OUT

static void Out( char *str )
{
    USHORT  written;

    DosWrite( 1, str, strlen( str ), &written );
}

#define NSIZE 20
static void OutNum( ULONG i )
{
    char    numbuff[NSIZE];
    char    *ptr;

    ptr = numbuff+NSIZE;
    *--ptr = '\0';
    if( i == 0 ) {
        *--ptr = '0';
    }
    while( i != 0 ) {
        *--ptr = "0123456789abcdef"[i & 0x0f];
        i >>= 4;
    }
    Out( ptr );
}

#endif

#define EXE_MZ  0x5a4d
#define EXE_NE  0x454e
#define EXE_LE  0x454c
#define EXE_LX  0x584c

#define OBJECT_IS_CODE  0x0004L
#define OBJECT_IS_BIG   0x2000L

#define EXE_IS_FULLSCREEN       0x0100
#define EXE_IS_PMC              0x0200
#define EXE_IS_PM               0x0300

/* Kernel memory not accessible via DosDebug */
#define KERNEL_MEM_OFFSET       0xE0000000

static ULONG            ExceptLinear;
static UCHAR            TypeProcess;
static BOOL             Is32Bit;
static watch            WatchPoints[MAX_WP];
static short            WatchCount = 0;
static short            DebugRegsNeeded = 0;
static unsigned_16      lastCS;
static unsigned_16      lastSS;
static unsigned_32      lastEIP;
static unsigned_32      lastESP;


bool    ExpectingAFault;
char    OS2ExtList[] = {".exe\0"};

static bool Is32BitSeg( unsigned seg )
{
    if( IsFlatSeg( seg ) )
        return( TRUE );
    if( IsUnknownGDTSeg( seg ) )
        return( TRUE );
    return( FALSE );
}

/*
 * RecordModHandle - save module handle for later reference
 */
static void RecordModHandle( ULONG value )
{
    if( ModHandles == NULL ) {
        DosAllocMem( &ModHandles, sizeof(ULONG) * 512, PAG_COMMIT | PAG_READ | PAG_WRITE );
        }
    ModHandles[NumModHandles] = value;
    ++NumModHandles;
}


/*
 * SeekRead - seek to a file position, and read the data
 */
static BOOL SeekRead( HFILE handle, ULONG newpos, void *ptr, ULONG size )
{
    ULONG       read;
    ULONG       pos;

    if( DosSetFilePtr(handle, newpos, 0, &pos) != 0 ) {
        return( FALSE );
    }
    if( DosRead(handle, ptr, size, &read) != 0 ) {
        return( FALSE );
    }
    if( read != size ) {
        return( FALSE );
    }
    return( TRUE );

} /* SeekRead */


/*
 * FindNewHeader - get a pointer to the new exe header
 */
static BOOL FindNewHeader( char *name, HFILE *hdl,
                          ULONG *new_head, USHORT *id )
{
    long        open_rc;
    HFILE       h;
    BOOL        rc;
    USHORT      data; /* MUST be 16-bit! */

    open_rc = OpenFile( name, 0, OPEN_PRIVATE );
    if( open_rc < 0 ) {
        return( FALSE );
    }
    h = open_rc;
    rc = FALSE;
    while( 1 ) {
        if( !SeekRead( h, 0x00, &data, sizeof( data ) ) ) {
            break;
        }
        if( data != EXE_MZ ) break;   /* MZ */

        if( !SeekRead( h, 0x18, &data, sizeof( data ) ) ) {
            break;
        }
        if( data < 0x40 )       /* offset of relocation header */
            break;

        if( !SeekRead( h, 0x3c, new_head, sizeof( ULONG ) ) ) {
            break;
        }

        if( !SeekRead( h, *new_head, id, sizeof( USHORT ) ) ) {
            break;
        }
        rc = TRUE;
        break;
    }
    if( !rc ) {
        DosClose( h );
    }
    *hdl = h;
    return( rc );

} /* FindNewHeader */

#define MAX_OBJECTS     128

static ULONG            LastMTE;
static unsigned         NumObjects;
static object_record    ObjInfo[MAX_OBJECTS];

static void GetObjectInfo( ULONG mte )
{
    HFILE               hdl;
    ULONG               new_head;
    USHORT              type;
    unsigned_32         objoff;
    unsigned_32         numobjs;

    char                buff[CCHMAXPATH];

    if( mte == LastMTE ) {
        return;
    }
    memset( ObjInfo, 0, sizeof( ObjInfo ) );
    DosQueryModuleName( mte, sizeof( buff ), buff );
    NumObjects = 0;
    if( !FindNewHeader( buff, &hdl, &new_head, &type ) ) {
        return;
    }
    if( type != EXE_LE && type != EXE_LX ) {
        DosClose( hdl );
        return;
    }
    SeekRead( hdl, new_head + 0x40, &objoff, sizeof( objoff ) );
    SeekRead( hdl, new_head + 0x44, &numobjs, sizeof( numobjs ) );
    if( numobjs <= MAX_OBJECTS ) {
        SeekRead( hdl, new_head + objoff, ObjInfo, numobjs * sizeof( ObjInfo[0] ) );
        NumObjects = numobjs;
    }
    LastMTE = mte;
    DosClose( hdl );
}


bool DebugExecute( uDB_t *buff, ULONG cmd, bool stop_on_module_load )
{
    EXCEPTIONREPORTRECORD       ex;
    ULONG                       value;
    ULONG                       stopvalue;
    ULONG                       notify = 0;
    BOOL                        got_second_notification;
    ULONG                       fcp;
    CONTEXTRECORD               fcr;

    buff->Cmd = cmd;
    value = buff->Value;
    if( cmd == DBG_C_Go ) {
        value = 0;
    }
    stopvalue = XCPT_CONTINUE_EXECUTION;
    got_second_notification = FALSE;
    if( cmd == DBG_C_Stop ) {
        stopvalue = XCPT_CONTINUE_STOP;
    }

    for( ;; ) {
        buff->Value = value;
        buff->Cmd = cmd;
        CallDosDebug( buff );

        value = stopvalue;
        cmd = DBG_C_Continue;

        /*
         * handle the preemptive notifications
         */
        switch( buff->Cmd ) {
        case DBG_N_ModuleLoad:
            RecordModHandle( buff->Value );
            if( stop_on_module_load )
                return( TRUE );
            break;
        case DBG_N_ModuleFree:
            break;
        case DBG_N_NewProc:
            break;
        case DBG_N_ProcTerm:
            value = XCPT_CONTINUE_STOP;         /* halt us */
            notify = DBG_N_ProcTerm;
            break;
        case DBG_N_ThreadCreate:
            break;
        case DBG_N_ThreadTerm:
            break;
        case DBG_N_AliasFree:
            break;
        case DBG_N_Exception:
            ExceptLinear = buff->Addr;
            if( buff->Value == DBG_X_STACK_INVALID ) {
                value = XCPT_CONTINUE_SEARCH;
                break;
            }
            fcp = buff->Len;
            if( buff->Value == DBG_X_PRE_FIRST_CHANCE ) {
                ExceptNum = buff->Buffer;
                if( ExceptNum == XCPT_BREAKPOINT ) {
                    notify = DBG_N_Breakpoint;
                    value = XCPT_CONTINUE_STOP;
                    break;
                } else if( ExceptNum == XCPT_SINGLE_STEP ) {
                    notify = DBG_N_SStep;
                    value = XCPT_CONTINUE_STOP;
                    break;
                }
            }
            //
            // NOTE: Going to second chance causes OS/2 to report the
            //       exception in the debugee.  However, if you report
            //       the fault at the first chance notification, the
            //       debugee's own fault handlers will not get invoked!
            //
            if( buff->Value == DBG_X_FIRST_CHANCE && !ExpectingAFault ) {
                if( stopOnSecond && !got_second_notification ) {
                    value = XCPT_CONTINUE_SEARCH;
                    break;
                }
            }
            notify = DBG_N_Exception;
            value = XCPT_CONTINUE_STOP;

            /*
             * Buffer contains the ptr to the exception block
             */
            buff->Cmd = DBG_C_ReadMemBuf;
            buff->Addr = buff->Buffer;
            buff->Buffer = (ULONG)&ex;
            buff->Len = sizeof( ex );
            CallDosDebug( buff );
            ExceptNum = ex.ExceptionNum;
            if( ExceptNum == XCPT_PROCESS_TERMINATE ||
                ExceptNum == XCPT_ASYNC_PROCESS_TERMINATE ||
                ExceptNum == XCPT_GUARD_PAGE_VIOLATION ||
                ( ExceptNum & XCPT_CUSTOMER_CODE ) ) {
                value = XCPT_CONTINUE_SEARCH;
                break;
            }

            /*
             * get the context record
             */
            buff->Cmd = DBG_C_ReadMemBuf;
            buff->Addr = fcp;
            buff->Buffer = (ULONG)&fcr;
            buff->Len = sizeof( fcr );
            CallDosDebug( buff );
            buff->EAX = fcr.ctx_RegEax;
            buff->EBX = fcr.ctx_RegEbx;
            buff->ECX = fcr.ctx_RegEcx;
            buff->EDX = fcr.ctx_RegEdx;
            buff->ESI = fcr.ctx_RegEsi;
            buff->EDI = fcr.ctx_RegEdi;
            buff->ESP = fcr.ctx_RegEsp;
            buff->EBP = fcr.ctx_RegEbp;
            buff->DS  = fcr.ctx_SegDs;
            buff->CS  = fcr.ctx_SegCs;
            buff->ES  = fcr.ctx_SegEs;
            buff->FS  = fcr.ctx_SegFs;
            buff->GS  = fcr.ctx_SegGs;
            buff->SS  = fcr.ctx_SegSs;
            buff->EIP = fcr.ctx_RegEip;
            buff->EFlags = fcr.ctx_EFlags;
            WriteRegs(buff);

            if( ExpectingAFault || got_second_notification ) {
                break;
            }
            if( stopOnSecond ) {
                value = XCPT_CONTINUE_EXECUTION;
                got_second_notification = TRUE;
            }
            break;
        default:
            if( notify != 0 ) {
                buff->Cmd = notify;
                // Check if we hit our splice DLL breakpoint
                if( (notify == DBG_N_Breakpoint) && splice_bp_set && (splice_bp_lin_addr == ExceptLinear) ) {
                    uDB_t       save;

                    // Remove breakpoint
                    WriteLinear( &saved_splice_bp, splice_bp_lin_addr, sizeof( byte ) );
                    splice_bp_set = FALSE;
                    splice_bp_lin_addr = 0;

                    // Attempt to load helper DLL
                    save.Pid = Pid;
                    save.Tid = 1;
                    ReadRegs( &save );
                    ExpectingAFault = TRUE;
                    // NB - the following will recursively call DebugExecute!
                    if( !CausePgmToLoadHelperDLL( ExceptLinear ) ) {
                        CanExecTask = FALSE;
                    } else {
                        CanExecTask = TRUE;
                    }
                    WriteRegs( &save );
                    break;
                }
            }
            return( FALSE );
        }
    }
//    return( FALSE );
}


void WriteRegs( uDB_t *buff )
{
    buff->Cmd = DBG_C_WriteReg;
    CallDosDebug( buff );
}

void ReadRegs( uDB_t *buff )
{
    buff->Cmd = DBG_C_ReadReg;
    CallDosDebug( buff );
}

void ReadXMMRegs( struct x86_xmm *xmm_regs )
{
    TaskReadXMMRegs( xmm_regs );
}

void WriteXMMRegs( struct x86_xmm *xmm_regs )
{
    TaskWriteXMMRegs( xmm_regs );
}

void ReadLinear( char *data, ULONG lin, USHORT size )

⌨️ 快捷键说明

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