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

📄 os2v2acc.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*
*                            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 <stddef.h>
#include <string.h>
#include <i86.h>
#define INCL_BASE
#define INCL_DOSDEVICES
#define INCL_DOSMEMMGR
#define INCL_DOSSIGNALS
#define INCL_DOSPROCESS
#undef INCL_DOSINFOSEG
#include <os2.h>
#include <os2dbg.h>
#include <string.h>
#include "trpimp.h"
#include "dosdebug.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"

__GINFOSEG              *GblInfo;
dos_debug               Buff;
static BOOL             stopOnSecond;
USHORT                  TaskFS;
extern char             SetHardMode( char );
extern VOID             InitDebugThread(VOID);

#ifdef DEBUG_OUT

void Out( char *str )
{
    USHORT      written;

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

#define NSIZE 20
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_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

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;


extern void bp( void );
bool    ExpectingAFault;
char    OS2ExtList[] = { ".exe\0" };

#pragma aux bp = 0xcc;

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

/*
 * RecordModHandle - save module handle for later reference
 */
void RecordModHandle( ULONG value )
{
    SEL         sel;

    if( ModHandles == NULL ) {
        DosAllocSeg( sizeof( ULONG ), (PSEL)&sel, 0 );
        ModHandles = MK_FP( sel, 0 );
    } else {
        DosReallocSeg( (NumModHandles+1)*sizeof( ULONG ),
                       FP_SEG( ModHandles ) );
    }
    ModHandles[ NumModHandles ] = value;
    ++NumModHandles;
}


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

    if( DosChgFilePtr( 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;

    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 != 0x5a4d ) break;   /* MZ */

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

        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[256];

    if( mte == LastMTE ) {
        return;
    }
    memset( ObjInfo, 0, sizeof( ObjInfo ) );
    DosGetModName( mte, 144, 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( dos_debug *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 = MakeLocalPtrFlat( (void *) &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 = MakeLocalPtrFlat( (void *) &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;
            }
            return( FALSE );
        }
    }
//    return( FALSE );
}


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

void ReadRegs( dos_debug *buff )
{

    buff->Cmd = DBG_C_ReadReg;
    CallDosDebug( buff );
}

void ReadLinear( char *data, ULONG lin, USHORT size )
{
    Buff.Cmd = DBG_C_ReadMemBuf;
    Buff.Addr = lin;
    Buff.Buffer = MakeLocalPtrFlat( data );
    Buff.Len = size;
    CallDosDebug( &Buff );
}

void WriteLinear( char *data, ULONG lin, USHORT size )
{
    Buff.Cmd = DBG_C_WriteMemBuf;
    Buff.Addr = lin;
    Buff.Buffer = MakeLocalPtrFlat( data );
    Buff.Len = size;
    CallDosDebug( &Buff );
}

USHORT WriteBuffer( char *data, USHORT segv, ULONG offv, USHORT size )
{
    USHORT      length;
    bool        iugs;
    USHORT      resdata;
    ULONG       flat;

    if( segv < 4 ) {
        return( 0 );
    }

    length = size;
    if( Pid != 0 ) {
        iugs = IsUnknownGDTSeg( segv );
        if( !iugs ) {
            flat = MakeItFlatNumberOne( segv, offv );
            WriteLinear( data, flat, size );
            if( Buff.Cmd == DBG_N_Success ) {
                return( size );
            }
        }
        while( length != 0 ) {
            Buff.Cmd = DBG_C_WriteMem_D;
            if( length == 1 ) {
                if( iugs ) {
                    if( !TaskReadWord( segv, offv, &resdata )) {
                        break;
                    }
                    resdata &= 0xff00;
                    resdata |= *data;
                    if( !TaskWriteWord( segv, offv, resdata ) ) {
                        break;
                    }
                } else {
                    Buff.Cmd = DBG_C_ReadMem_D;
                    Buff.Addr = MakeItFlatNumberOne( segv, offv );
                    CallDosDebug( &Buff );
                    Buff.Cmd = DBG_C_WriteMem_D;
                    Buff.Addr = MakeItFlatNumberOne( segv, offv );
                    Buff.Value &= 0xff00;
                    Buff.Value |= *data;
                    CallDosDebug( &Buff );
                    if( Buff.Cmd != DBG_N_Success ) {
                        break;
                    }
                }
                data++;
                length--;
                offv++;
            } else {
                resdata = *data;
                data++;
                resdata |= *data << 8;
                data++;
                if( iugs ) {
                    if( !TaskWriteWord( segv, offv, resdata ) ) {
                        break;
                    }
                } else {
                    Buff.Value = resdata;
                    Buff.Addr = MakeItFlatNumberOne( segv, offv );
                    CallDosDebug( &Buff );
                    if( Buff.Cmd != DBG_N_Success ) {
                        break;
                    }
                }
                length -= 2;
                offv += 2;
            }
        }
    }
    return( size - length ); /* return amount written */
}


static USHORT ReadBuffer( char *data, USHORT segv, ULONG offv, USHORT size )
{
    USHORT      length;
    bool        iugs;
    USHORT      resdata;
    ULONG       flat;

    if( segv < 4 ) {
        return( 0 );
    }
    length = size;
    if( Pid != 0 ) {
        iugs = IsUnknownGDTSeg( segv );
        if( !iugs ) {
            flat = MakeItFlatNumberOne( segv, offv );
            ReadLinear( data, flat, size );
            if( Buff.Cmd == DBG_N_Success ) {
                return( size );
            }
        }
        while( length != 0 ) {
            if( iugs ) {
                if( !TaskReadWord( segv, offv, &resdata ) ) {
                    break;
                }
            } else {
                Buff.Cmd = DBG_C_ReadMem_D;
                Buff.Addr = MakeItFlatNumberOne( segv, offv );
                CallDosDebug( &Buff );
                if( Buff.Cmd != DBG_N_Success ) {
                    break;
                }
                resdata = Buff.Value;
            }
            *data = resdata & 0xff;
            data++;
            offv++;
            length--;
            if( length != 0 ) {

⌨️ 快捷键说明

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