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

📄 os2v2acc.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        ret->thread = 1;
        ret->flags = LD_FLAG_IS_PROT;
        */
    } else {
        ret->task_id = Pid;
        ret->flags = LD_FLAG_IS_PROT;
        Buff.Pid = Pid;
        Buff.Tid = 0;
        Buff.Cmd = DBG_C_Connect;
        Buff.Value = DBG_L_386;
        CallDosDebug( &Buff );

        Buff.Pid = Pid;
        Buff.Tid = 1;
        DebugExecute( &Buff, DBG_C_Stop, FALSE );
        if( Buff.Cmd != DBG_N_Success ) {
            ret->err = 14; /* can't load */
            return( sizeof( *ret ) );
        }
        ReadRegs( &Buff );
        CanExecTask = FALSE;
        if( FindLinearStartAddress( &startLinear, UtilBuff ) ) {
            if( Is32Bit ) {
                ret->flags |= LD_FLAG_IS_32;
            }
            CanExecTask = ExecuteUntilLinearAddressHit( startLinear );
            ReadRegs( &Buff );
        }
#if 0
        if( CanExecTask ) {
            dos_debug   save;

            save.Pid = Pid;
            save.Tid = 1;
            ReadRegs( &save );
            if( !CausePgmToLoadThisDLL( startLinear ) ) {
                CanExecTask = FALSE;
            }
            WriteRegs( &save );
        }
#endif
        Buff.Pid = Pid;
        Buff.Tid = 1;
        ReadRegs( &Buff );
        TaskFS = Buff.FS;
    }
    ret->flags |= LD_FLAG_HAVE_RUNTIME_DLLS;
    ret->mod_handle = 0;
    CurrModHandle = 1;
    return( sizeof( *ret ) );
}

unsigned ReqProg_kill( void )
{
    prog_kill_ret       *ret;

    ret = GetOutPtr( 0 );
    SaveStdIn = NIL_DOS_HANDLE;
    SaveStdOut = NIL_DOS_HANDLE;
    if( Pid != 0 ) {
        Buff.Cmd = DBG_C_Term;
        Buff.Pid = Pid;
        CallDosDebug( &Buff );
    }
    NumModHandles = 0;
    CurrModHandle = 1;
    Pid = 0;
    ret->err = 0;
    DosSleep( 500 ); // Without this, it seems that restarts happen too fast
                     // and we end up running a 2nd instance of a dead task
                     // or some such sillyness.  I don't really know, but
                     // this DosSleep avoids problems when restarting a PM app
                     // ( ... Yes, this is a Hail Mary ... )
    StopPMHelp();
    return( sizeof( *ret ) );
}

unsigned ReqSet_break( void )
{
    byte             ch;
    set_break_req       *acc;
    set_break_ret       *ret;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    ReadBuffer( &ch, acc->break_addr.segment, acc->break_addr.offset, sizeof(byte) );
    ret->old = ch;
    ch = 0xCC;
    WriteBuffer( &ch, acc->break_addr.segment, acc->break_addr.offset, sizeof(byte) );
    return( sizeof( *ret ) );
}

unsigned ReqClear_break( void )
{
    clear_break_req     *acc;
    byte                 ch;

    acc = GetInPtr( 0 );
    ch = acc->old;
    WriteBuffer( &ch, acc->break_addr.segment, acc->break_addr.offset, sizeof(byte) );
    return( 0 );
}

unsigned ReqSet_watch( void )
{
    set_watch_req       *acc;
    set_watch_ret       *ret;
    dword         buff;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    ret->err = 1;
    if( WatchCount < MAX_WP ) { // nyi - artificial limit (32 should be lots)
        WatchPoints[ WatchCount ].addr.segment = acc->watch_addr.segment;
        WatchPoints[ WatchCount ].addr.offset = acc->watch_addr.offset;
        WatchPoints[ WatchCount ].len = acc->size;
        ReadBuffer( (char *)&buff, acc->watch_addr.segment,
                    acc->watch_addr.offset, sizeof(dword) );
        WatchPoints[ WatchCount ].value = buff;
        DebugRegsNeeded += ( acc->watch_addr.offset & ( acc->size-1 ) ) ? 2 : 1;
        ret->err = 0;
        ++WatchCount;
    }
    ret->multiplier = 50000;
    if( ret->err == 0 && DebugRegsNeeded <= 4 ) {
        ret->multiplier |= USING_DEBUG_REG;
    }
    return( sizeof( *ret ) );
}

unsigned ReqClear_watch( void )
{
    clear_watch_req     *acc;
    watch            *dst;
    watch            *src;
    int              i;


    acc = GetInPtr( 0 );
    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 void pascal far __loadds BrkHandler( USHORT sig_arg, USHORT sig_num )
{
    PFNSIGHANDLER   prev_hdl;
    USHORT          prev_act;

    sig_arg = sig_arg;
    SetBrkPending();
    DosSetSigHandler( BrkHandler, &prev_hdl, &prev_act, 4, sig_num );
}

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 )
{
    dos_debug           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 );
    }
}

static unsigned progRun( bool step )
{
    PFNSIGHANDLER       prev_brk_hdl;
    PFNSIGHANDLER       prev_intr_hdl;
    USHORT              prev_intr_act;
    USHORT              prev_brk_act;
    prog_go_ret         *ret;

    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;
    DosSetSigHandler( BrkHandler, &prev_intr_hdl, &prev_intr_act, 2, SIG_CTRLC );
    DosSetSigHandler( BrkHandler, &prev_brk_hdl, &prev_brk_act, 2, SIG_CTRLBREAK );

    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;
        }
    }
    DosSetSigHandler( prev_brk_hdl, &prev_brk_hdl, &prev_brk_act,
                       prev_brk_act, SIG_CTRLBREAK );
    DosSetSigHandler( prev_brk_hdl, &prev_intr_hdl, &prev_intr_act,
                       prev_brk_act, SIG_CTRLC );
    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 )
{
    USHORT       len;
    USHORT       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 ) );
}

static int ValidThread( TID thread )
{
    struct thd_state state;
    TID save;

    if( thread == 0 ) return( 0 );
    save = Buff.Tid;
    Buff.Tid = thread;
    Buff.Cmd = DBG_C_ThrdStat;
    Buff.Buffer = MakeLocalPtrFlat( &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 ) );
}

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;
    USHORT              os2ver;
    SEL                 li,gi;
    __LINFOSEG          *linfo;

    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;
    }

    DosGetVersion( &os2ver );
    if( os2ver < 0x200 ) {
        StrCopy( TRP_OS2_Wrong_Version, err );
        return( ver );
    }
    if( DosGetInfoSeg( &gi, &li ) != 0  ) {
        StrCopy( TRP_OS2_no_info, err );
        return( ver );
    }
    GblInfo = MK_FP( gi, 0 );
    linfo = MK_FP( li, 0 );
    TypeProcess = linfo->typeProcess;
    if( !GetDos32Debug( err ) ) {
        return( ver );
    }
    InitSoftDebug();
    InitDebugThread();

    return( ver );
}

void TRAPENTRY TrapFini( void )
{
}

⌨️ 快捷键说明

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