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

📄 os2v2acc.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
{
    mad_registers       *mr;

    mr = GetInPtr( sizeof( write_regs_req ) );
    if( Pid != 0 ) {
        WriteCPU( &mr->x86.cpu );
        WriteRegs( &Buff );
        Buff.Cmd    = DBG_C_WriteCoRegs;
        Buff.Buffer = (ULONG)&mr->x86.fpu;
        Buff.Value  = DBG_CO_387;       /* for 2.0: DBG_CO_387 */
        Buff.Len    = DBG_LEN_387;      /* for 2.0: buffer size */
        Buff.Index  = 0;                /* for 2.0: must be zero */
        CallDosDebug( &Buff );
        WriteXMMRegs( &mr->x86.xmm );
    }
    return( 0 );
}

unsigned ReqGet_lib_name( void )
{
    get_lib_name_req    *acc;
    get_lib_name_ret    *ret;
    char                *name;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    if( acc->handle != 0 ) {
        CurrModHandle = acc->handle + 1;
    }
    if( CurrModHandle >= NumModHandles ) {
        ret->handle = 0;
        return( sizeof( *ret ) );
    }
    name = GetOutPtr( sizeof( *ret ) );
    Buff.Value = ModHandles[CurrModHandle];
    DosQueryModuleName( ModHandles[CurrModHandle], 128, name );
    ret->handle = CurrModHandle;
    return( sizeof( *ret ) + strlen( name ) + 1 );
}

static USHORT GetEXEFlags( char *name )
{
    HFILE       hdl;
    USHORT      type;
    ULONG       new_head;
    USHORT      exeflags;

    if( !FindNewHeader( name, &hdl, &new_head, &type ) ) {
        return( 0 );
    }
    if( type == EXE_NE ) {
        SeekRead( hdl, new_head + 0x0c, &exeflags, sizeof( exeflags ) );
    } else if( type == EXE_LE || type == EXE_LX ) {
        SeekRead( hdl, new_head + 0x10, &exeflags, sizeof( exeflags ) );
    } else {
        exeflags = 0;
    }
    DosClose( hdl );
    exeflags &= 0x0700;
    return( exeflags );

} /* GetEXEFlags */

static bool FindLinearStartAddress( ULONG *pLin, char *name )
{
    bool        rc;
    HFILE       hdl;
    USHORT      type;
    ULONG       new_head;
    ULONG       objnum;
    USHORT      sobjn;
    ULONG       eip;
    USHORT      ip;

    if( !FindNewHeader( name, &hdl, &new_head, &type ) ) {
        return( FALSE );
    }
    for( ;; ) {
        rc = FALSE;
        if( type == EXE_NE ) {
            if( !SeekRead( hdl, new_head + 0x14, &ip, sizeof( ip ) ) ) {
                break;
            }
            eip = ip;
            if( !SeekRead( hdl, new_head + 0x16, &sobjn, sizeof( sobjn ) ) ) {
                break;
            }
            objnum = sobjn;

            Is32Bit = FALSE;
        } else if( type == EXE_LE || type == EXE_LX ) {
            if( !SeekRead( hdl, new_head + 0x1c, &eip, sizeof( eip ) ) ) {
                break;
            }
            if( !SeekRead( hdl, new_head + 0x18, &objnum, sizeof( objnum ) ) ) {
                break;
            }

            Is32Bit = TRUE;
        } else {
            break;
        }

        Buff.Cmd   = DBG_C_NumToAddr;
        Buff.Value = objnum;
        Buff.MTE   = ModHandles[0];
        CallDosDebug( &Buff );
        if( Buff.Cmd != DBG_N_Success ) {
            break;
        }
        *pLin = eip + Buff.Addr;

        Buff.MTE = ModHandles[0];

        rc = TRUE;
        break;
    }
    DosClose( hdl );
    return( rc );
} /* FindLinearStartAddress */

static BOOL ExecuteUntilLinearAddressHit( ULONG lin )
{
    byte        breakpnt = 0xCC;
    BOOL        rc = TRUE;

    ReadLinear( &saved_splice_bp, lin, sizeof( byte ) );
    WriteLinear( &breakpnt, lin, sizeof( byte ) );
    splice_bp_set = TRUE;
    splice_bp_lin_addr = lin;
    do {
        ExceptNum = 0;
        DebugExecute( &Buff, DBG_C_Go, TRUE );
        if( ExceptNum == 0 ) {
            rc = TRUE; // DLL loaded
            /* Breaking on DLL load means that this routine does not
             * necessarily stop when the linear address is truly hit;
             * this seemingly strange behaviour is desirable if we
             * want to debug startup code of DLLs (and we do) - we have
             * to stop program execution before DLLs are all loaded!
             */
            break;
        }
        if( ExceptNum != XCPT_BREAKPOINT ) {
            rc = FALSE;
            break;
        }
    } while( ExceptLinear != lin );
    return( rc );
}

void AppSession( void )
{
    if( !IsPMDebugger() )
        DosSelectSession( SID );
}

void DebugSession( void )
{
    if( !IsPMDebugger() )
        DosSelectSession( 0 );
}

static unsigned StartProcess( const char *exe_name, char *parms )
{
    STARTDATA       start;
    PTIB            ptib;
    PPIB            ppib;
    char            appname[CCHMAXPATH];
    unsigned        rc;

    start.Length = offsetof( STARTDATA, IconFile ); /* default for the rest */
    start.Related = 1;
    start.FgBg = !Remote;
    start.TraceOpt = 1;
    strcpy( appname, TRP_The_WATCOM_Debugger );
    strcat( appname, ": " );
    strcat( appname, exe_name );
    start.PgmTitle = (PSZ)appname;
    start.PgmName = UtilBuff;
    start.PgmInputs = parms;
    start.TermQ = 0;
    /* We need to inherit from parent to get open file handles etc. */
    start.InheritOpt = SSF_INHERTOPT_PARENT;
    /* We want debugger's (debugger's parent really) environment */
    DosGetInfoBlocks( &ptib, &ppib );
    start.Environment = ppib->pib_pchenv;
    rc = 0;
    if( GetEXEFlags( UtilBuff ) == EXE_IS_PM ) {
        if( TypeProcess == SSF_TYPE_WINDOWABLEVIO ) {
            rc = ERROR_NOT_IN_WINDOW;
        } else {
            start.SessionType = SSF_TYPE_PM;
            if( !IsPMDebugger() )
                StartPMHelp();
        }
    } else if( TypeProcess == PT_WINDOWABLEVIO || TypeProcess == PT_PM ) {
        start.SessionType = SSF_TYPE_WINDOWABLEVIO;
    } else if( TypeProcess == PT_FULLSCREEN ) {
        start.SessionType = SSF_TYPE_FULLSCREEN;
    }
    if( rc == 0 ) {
        rc = DosStartSession( (void *)&start, &SID, &Pid );
    }
    if( rc == ERROR_SMG_START_IN_BACKGROUND ) {
        rc = 0;
    }
    return( rc );
}

unsigned ReqProg_load( void )
{
    char            *parms;
    char            *end;
    char            *src;
    char            *prog;
    char            *endsrc;
    char            exe_name[CCHMAXPATH];
    ULONG           startLinear;
    prog_load_ret   *ret;
    int             attach_pid;

    LastMTE    = 0;
    ExceptNum  = -1;
    ret        = GetOutPtr(0);
    AtEnd      = FALSE;
    TaskFS     = 0;
    attach_pid = -1;
    src = prog = GetInPtr( sizeof( prog_load_req ) );

    // See if a PID was specified; if so, we will be attaching to
    // an existing process, not loading a new one. The PID may
    // be specified either as "#<hex pid>" or "<decimal pid>".
    if( *src == '#' ) {
        src++;
        attach_pid = strtoul( src, &endsrc, 16 );
        if( attach_pid == 0 )
            attach_pid = -1;
//        strcpy( buff, endsrc );
    } else {
        while( *src ) {
            if( !isdigit( *src ) ) {
                break;
            }
            src++;
        }
        if( *src == 0 && src != prog ) {
            attach_pid = atoi( prog );
        }
    }

    /* If PID was not specified, start the debuggee process */
    if( attach_pid == -1 ) {
        isAttached = FALSE;
        if( FindFilePath( prog, exe_name, OS2ExtList ) != 0 ) {
            exe_name[0] = '\0';
        }
        parms = AddDriveAndPath( exe_name, UtilBuff );
        while( *prog != '\0' )
            ++prog;
        ++prog;
        end = (char *)GetInPtr( GetTotalSize() - 1 ) + 1;
        MergeArgvArray( prog, parms, end - prog );
        ret->err = StartProcess( exe_name, parms );
    } else {
        isAttached = TRUE;
        Buff.Addr  = 0; // Sever connection
        Buff.Pid   = attach_pid;
        Buff.Tid   = 0;
        Buff.Cmd   = DBG_C_Attach;
        Buff.Value = DBG_L_386;
        CallDosDebug( &Buff );
        if( Buff.Cmd == DBG_N_Success ) {
            Pid = attach_pid;
            ret->err = 0;
        } else {
            ret->err = Buff.Value;
        }
    }

    if( ret->err != 0 ) {
        Pid = 0;
        /* may need to do this
        ret->task_id = Pid;
        ret->thread = 1;
        ret->flags = LD_FLAG_IS_PROT;
        */
    } else {
        ret->task_id = Pid;
        ret->flags = LD_FLAG_IS_PROT;

        if( !isAttached ) {
            Buff.Pid   = Pid;
            Buff.Tid   = 0;
            Buff.Cmd   = DBG_C_Connect;
            Buff.Value = DBG_L_386;
            CallDosDebug( &Buff );
        }
        else {
            ret->flags |= LD_FLAG_IS_STARTED;
            // TODO: figure out if 32-bit process
            Is32Bit = TRUE;
        }

        Buff.Pid = Pid;
        Buff.Tid = 1;
        if( !isAttached ) {
            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;
        splice_bp_set = FALSE;
        splice_bp_lin_addr = 0;

        if( isAttached ) {
        } else {
            if( FindLinearStartAddress( &startLinear, UtilBuff ) ) {
                CanExecTask = ExecuteUntilLinearAddressHit( startLinear );
                ReadRegs( &Buff );
            }
        }
        /* Splice our helper DLL into debuggee's context */
        if( CanExecTask ) {
            uDB_t       save;

            save.Pid = Pid;
            save.Tid = 1;
            ReadRegs( &save );
            if( !CausePgmToLoadHelperDLL( startLinear ) ) {
                CanExecTask = FALSE;
                // Note - the breakpoint is still set; we'll likely hit
                // it later
            } else {
                // Remove breakpoint
                WriteLinear( &saved_splice_bp, startLinear, sizeof( byte ) );
                splice_bp_set = FALSE;
                splice_bp_lin_addr = 0;
            }
            WriteRegs( &save );
        }
        Buff.Pid = Pid;
        Buff.Tid = 1;
        ReadRegs( &Buff );
        TaskFS = Buff.FS;
    }

    if( Is32Bit ) {
        ret->flags |= LD_FLAG_IS_32;
    }
    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 ) {
        if( isAttached )
            Buff.Cmd = DBG_C_Detach;
        else
            Buff.Cmd = DBG_C_Term;
        Buff.Pid = Pid;
        CallDosDebug( &Buff );
    }
    NumModHandles = 0;
    CurrModHandle = 1;
    Pid = 0;
    ret->err = 0;
    DosSleep( 100 ); // 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 );

⌨️ 快捷键说明

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