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

📄 os2v2acc.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    dst = src = WatchPoints;
    for( i = 0; i < WatchCount; ++i ) {
        if( src->addr.segment != acc->watch_addr.segment ||
                src->addr.offset != acc->watch_addr.offset ) {
            *dst = *src;
            ++dst;
        } else {
            DebugExecute( &Buff, DBG_C_Stop, FALSE );
            Buff.Cmd = DBG_C_ClearWatch;
            Buff.Index = 0; // src->id;
            CallDosDebug( &Buff );
        }
        ++src;
    }
    DebugRegsNeeded -= (acc->watch_addr.offset & (acc->size - 1)) ? 2 : 1;
    --WatchCount;
    return( 0 );
}

static volatile bool     BrkPending;

void SetBrkPending( void )
{
    BrkPending = TRUE;
}

static unsigned MapReturn( unsigned conditions )
{
    if( BrkPending ) {
        /* Get CS:EIP & SS:ESP correct */
        ReadRegs( &Buff );
        return( conditions | COND_USER );
    }
    Out( "Map Return - " );
    OutNum( Buff.Cmd );
    Out( "\r\n" );
    switch( Buff.Cmd ) {
    case DBG_N_Success:
        return( conditions );
    case DBG_N_AsyncStop:
        return( conditions | COND_USER );
//    case DBG_N_Signal:
//        return( TRAP_USER );
    case DBG_N_SStep:
        return( conditions | COND_TRACE );
    case DBG_N_Breakpoint:
        return( conditions | COND_BREAK );
    case DBG_N_Exception:
        switch( ExceptNum ) {
        case XCPT_PROCESS_TERMINATE:
        case XCPT_ASYNC_PROCESS_TERMINATE:
            return( conditions | COND_TERMINATE );
        default:
            return( conditions | COND_EXCEPTION );
        }
    case DBG_N_Watchpoint:
        return( conditions | COND_WATCH );
    case DBG_N_ModuleLoad:
        return( conditions | COND_LIBRARIES );
    case DBG_N_ThreadTerm:
        return( conditions );
    case DBG_N_Error: // must terminate application - system semaphore locked
        Buff.Cmd = DBG_C_Term;
        Buff.Pid = Pid;
        CallDosDebug( &Buff );
    default:
        AtEnd = TRUE;
        CanExecTask = FALSE;
        return( conditions | COND_TERMINATE );
    }
}

static bool setDebugRegs(void)
{
    int                 needed;
    int                 i;

    needed = 0;
    for( i = 0; i < WatchCount; ++i ) {
        needed += WatchPoints[i].addr.offset & (WatchPoints[i].len - 1) ? 2 : 1;
        if( needed > 4 ) {
            return( FALSE );
        }
    }
    for( i = 0; i < WatchCount; ++i ) {
        Buff.Cmd = DBG_C_SetWatch;
        Buff.Addr = MakeItFlatNumberOne( WatchPoints[i].addr.segment,
                                        WatchPoints[i].addr.offset & ~(WatchPoints[i].len - 1) );
        Buff.Len = WatchPoints[i].len;
        Buff.Index = 0;
        Buff.Value = DBG_W_Write | DBG_W_Local;
        CallDosDebug( &Buff );
        if( WatchPoints[i].addr.offset & (WatchPoints[i].len - 1) ) {
            Buff.Cmd = DBG_C_SetWatch;
            Buff.Addr += WatchPoints[i].len;
            Buff.Index = 0;
            CallDosDebug( &Buff );
        }
    }
    return( TRUE );
}

static void watchSingleStep(void)
{
    uDB_t               save;
    dword               memval;
    int                 i;

    DebugExecute( &Buff, DBG_C_SStep, TRUE );
    while( Buff.Cmd == DBG_N_SStep ) {
        for (i = 0; i < WatchCount; ++i) {
            ReadRegs( &save );
            ReadBuffer( (char *)&memval, WatchPoints[i].addr.segment,
                       WatchPoints[i].addr.offset, sizeof( memval ) );
            WriteRegs(&save);
            if( WatchPoints[i].value != memval ) {
                Buff.Cmd = DBG_N_Watchpoint;
                return;
            }
        }
        DebugExecute( &Buff, DBG_C_SStep, TRUE );
    }
}

/* This break handler ensures that upon hitting Ctrl-C or Ctrl-Break when
   the debugger has focus, the debuggee will be actually interrupted instead
   of killing the debugger. We do NOT handle XCPT_SIGNAL_KILLPROC, hence
   the debugger can still be killed by another app (a Good Thing).
   Note: Ctrl-C doesn't seem to be sending signals for some reason, but
   Ctrl-Break is working so it doesn't really matter.
*/
ULONG _System BreakHandler( PEXCEPTIONREPORTRECORD       pExRec,
                            PEXCEPTIONREGISTRATIONRECORD pRegRec,
                            PCONTEXTRECORD               pCtxRec,
                            PVOID                        args )
{
    switch( pExRec->ExceptionNum ) {
        case XCPT_SIGNAL: {
            switch( pExRec->ExceptionInfo[0] ) {
               case XCPT_SIGNAL_INTR:
               case XCPT_SIGNAL_BREAK:
                   SetBrkPending();
                   return( XCPT_CONTINUE_EXECUTION );
            }
        }
    }
    /* Pass everything else further down */
    return( XCPT_CONTINUE_SEARCH );
}

static unsigned progRun( bool step )
{
    prog_go_ret                 *ret;
    ULONG                       ulTimes;
    EXCEPTIONREGISTRATIONRECORD RegRec = {0}; // must be on stack!

    RegRec.ExceptionHandler = BreakHandler;

    ret = GetOutPtr( 0 );
    if( NumModHandles > CurrModHandle ) {
        ret->conditions = COND_LIBRARIES;
        ret->stack_pointer.segment   = lastSS;
        ret->stack_pointer.offset    = lastESP;
        ret->program_counter.segment = lastCS;
        ret->program_counter.offset  = lastEIP;
        return( sizeof( *ret ) );
    }
    BrkPending = FALSE;

    // Set exception handler and don't forget to set signal focus!
    DosSetExceptionHandler( &RegRec );
    DosSetSignalExceptionFocus( SIG_SETFOCUS, &ulTimes );

    if( AtEnd ) {
        Buff.Cmd = DBG_N_ProcTerm;
    } else if( step ) {
        DebugExecute( &Buff, DBG_C_SStep, TRUE );
    } else if( !setDebugRegs() ) {
        watchSingleStep();
    } else {
        DebugExecute( &Buff, DBG_C_Go, TRUE );
        if( Buff.Cmd == DBG_N_Success ) {
            Buff.Cmd = DBG_N_ProcTerm;
        }
    }

    DosSetSignalExceptionFocus( SIG_UNSETFOCUS, &ulTimes );
    DosUnsetExceptionHandler( &RegRec );

    ret->conditions = ( COND_CONFIG | COND_THREAD );
    if( NumModHandles > CurrModHandle ) {
        ret->conditions |= COND_LIBRARIES;
    }
    ret->conditions = MapReturn( ret->conditions );
    lastSS = ret->stack_pointer.segment   = Buff.SS;
    lastESP = ret->stack_pointer.offset   = Buff.ESP;
    lastCS = ret->program_counter.segment = Buff.CS;
    lastEIP = ret->program_counter.offset = Buff.EIP;
    //runret->thread = Buff.Tid;
    //if( runret->returnvalue == TRAP_TERMINATE ) {
    //    AtEnd = TRUE;
    //    CanExecTask = FALSE;
    //}
    return( sizeof( *ret ) );
}

unsigned ReqProg_go( void )
{
    unsigned    rc;

    PMUnLock();
    rc = progRun( FALSE );
    PMLock( Buff.Pid, Buff.Tid );
    return( rc );
}

unsigned ReqProg_step( void )
{
    unsigned    rc;

    PMUnLock();
    rc = progRun( TRUE );
    PMLock( Buff.Pid, Buff.Tid );
    return( rc );
}

unsigned ReqFile_write_console( void )
{
    ULONG        len;
    ULONG        written_len;
    char         *ptr;
    file_write_console_ret      *ret;

    ptr = GetInPtr( sizeof( file_write_console_req ) );
    len = GetTotalSize() - sizeof( file_write_console_req );
    ret = GetOutPtr( 0 );
    if( CanExecTask ) {
        /* print/program request */
        ret->len = len;
        ret->err = 0;
        TaskPrint( ptr, len );
    } else {
        ret->err = DosWrite( 2, ptr, len, &written_len );
        ret->len = written_len;
    }
    return( sizeof( *ret ) );
}

struct thd_state {
    unsigned char   dbg_state;
    unsigned char   thread_state;
    unsigned short  priority;
};

static int ValidThread( TID thread )
{
    struct  thd_state  state; /* TStat_t with IBM headers */
    TID     save;

    if( thread == 0 )
        return( 0 );
    save     = Buff.Tid;
    Buff.Tid = thread;
    Buff.Cmd = DBG_C_ThrdStat;
    Buff.Buffer = (ULONG)&state;
    Buff.Len = 4;
    CallDosDebug( &Buff );
    Buff.Tid = save;
    return( Buff.Cmd == DBG_N_Success );
}

unsigned ReqThread_get_next( void )
{
    thread_get_next_req *acc;
    thread_get_next_ret *ret;
    TID                 thread;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );

    if( Pid != 0 ) {
        thread = acc->thread;
        while( ++thread <= 256 ) {
            if( ValidThread( thread ) ) {
                ret->thread = thread;
                //NYI:Assume all threads can be run
                ret->state = THREAD_THAWED;
                return( sizeof( *ret ) );
            }
        }
    }
    ret->thread = (acc->thread == 0) ? 1 : 0;
    return( sizeof( *ret ) );
}

unsigned ReqThread_set( void )
{
    thread_set_req      *acc;
    thread_set_ret      *ret;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    ret->err = 0;
    ret->old_thread = Buff.Tid;
    if( ValidThread( acc->thread ) ) {
        Buff.Pid = Pid;
        Buff.Tid = acc->thread;
        Buff.Cmd = DBG_C_ReadReg;
        CallDosDebug( &Buff );
    } else if( acc->thread != 0 ) {
        ret->err = 1;
    }
    return( sizeof( *ret ) );
}

typedef enum {                  /* values for .cmd field */
        PT_CMD_READ_MEM_I = 1,  /* read I-space */
        PT_CMD_READ_MEM_D,      /* read D-space */
        PT_CMD_READ_REGS,       /* read registers */
        PT_WRITE_CMD_MEM_I,     /* write I-space */
        PT_CMD_WRITE_MEM_D,     /* write D-space */
        PT_CMD_WRITE_REGS,      /* write registers */
        PT_CMD_GO,              /* go (with signal) */
        PT_CMD_TERMINATE,       /* terminate child process */
        PT_CMD_SINGLE_STEP,     /* single step */
        PT_CMD_STOP,            /* stop child process */
        PT_CMD_FREEZE,          /* freeze child process */
        PT_CMD_RESUME,          /* resume child process */
        PT_CMD_SEG_TO_SEL,      /* resume child process */
        PT_CMD_READ_8087,       /* read npx */
        PT_CMD_WRITE_8087,      /* write npx */
        PT_CMD_GET_LIB_NAME,    /* get library module name */
        PT_CMD_THREAD_STAT,     /* get thread status */
#if 0   /* depends on which documentation you believe */
        PT_CMD_READ_MEM_B,      /* read memory block */
        PT_CMD_WRITE_MEM_B,     /* write memory block */
#else
        PT_CMD_MAP_RO_ALIAS,    /* create a read only segment alias */
        PT_CMD_MAP_WR_ALIAS,    /* create a read/write segment alias */
        PT_CMD_UNMAP_ALIAS      /* unmap a segment alias */
#endif
} trace_codes;

static unsigned DoThread( trace_codes code )
{
    TID                 save;
    thread_thaw_req     *acc;
    thread_thaw_ret     *ret;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    if( ValidThread( acc->thread ) ) {
        save = Buff.Tid;
        Buff.Pid = Pid;
        Buff.Tid = acc->thread;
        Buff.Cmd = code;
        CallDosDebug( &Buff );
        Buff.Tid = save;
        ret->err = 0;
    } else {
        ret->err = 1;   // failed
    }
    return( sizeof( *ret ) );
}

unsigned ReqThread_freeze( void )
{
    return( DoThread( DBG_C_Freeze ) );
}

unsigned ReqThread_thaw( void )
{
    return( DoThread( DBG_C_Resume ) );
}

unsigned ReqGet_message_text( void )
{
    get_message_text_ret        *ret;
    char                        *err_txt;

    ret = GetOutPtr( 0 );
    err_txt = GetOutPtr( sizeof( *ret ) );
    if( ExceptNum == -1 ) {
        err_txt[0] = '\0';
    } else {
        strcpy( err_txt, GetExceptionText() );
    }
    ExceptNum = -1;
    ret->flags = MSG_NEWLINE | MSG_ERROR;
    return( sizeof( *ret ) + strlen( err_txt ) + 1 );
}

unsigned ReqGet_next_alias( void )
{
    get_next_alias_req  *acc;
    get_next_alias_ret  *ret;

    ret = GetOutPtr( 0 );
    ret->seg = 0;
    ret->alias = 0;
    acc = GetInPtr( 0 );
    if( Is32Bit && acc->seg == 0 ) {
        ret->seg   = FlatCS;
        ret->alias = FlatDS;
    }
    return( sizeof( *ret ) );
}

void TRAPENTRY TellHandles( HAB hab, HWND hwnd )
{
    TellSoftModeHandles( hab, hwnd );
}

char TRAPENTRY TellHardMode( char hard )
{
    return( SetHardMode( hard ) );
}

trap_version TRAPENTRY TrapInit( char *parm, char *err, bool remote )
{
    trap_version        ver;
    PTIB                ptib;
    PPIB                ppib;

    parm = parm;
    Remote = remote;
    err[0] = '\0';
    ver.major  = TRAP_MAJOR_VERSION;
    ver.minor  = TRAP_MINOR_VERSION;
    ver.remote = FALSE;
    SaveStdIn  = NIL_DOS_HANDLE;
    SaveStdOut = NIL_DOS_HANDLE;
    Screen     = DEBUG_SCREEN;
    if( parm[0] == '2' ) {
        stopOnSecond = TRUE;
    }

    DosGetInfoBlocks( &ptib, &ppib );
    TypeProcess = ppib->pib_ultype;

    InitSoftDebug();
    InitDebugThread();

    return( ver );
}

void TRAPENTRY TrapFini( void )
{
}

⌨️ 快捷键说明

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