qnxacc.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,824 行 · 第 1/4 页

C
1,824
字号
            if( ProcInfo.loaded_proc ) {
                net_kill( ProcInfo.proc, ProcInfo.pid, SIGKILL );
            }
            goto fail;
        }
        if( !ProcInfo.loaded_proc ) {
            __qnx_debug_hold( ProcInfo.proc, ProcInfo.pid );
            ret->flags |= LD_FLAG_IS_STARTED;
        }
        ret->task_id = ProcInfo.pid;
        qnx_osinfo( ProcInfo.nid, &info );
        ProcInfo.cpu = info.cpu;
        ProcInfo.fpu = info.fpu;
        ProcInfo.version = info.version;
        ProcInfo.sflags = info.sflags;
        if( info.sflags & _PSF_PROTECTED ) {
            ret->flags |= LD_FLAG_IS_PROT;
        }
        if( info.sflags & _PSF_32BIT ) {
            ProcInfo.proc32 = TRUE;
        }
        has_flat = FALSE;
        if( __qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_PSINFO,
                            &off_info, sizeof( off_info ), 0, 0 ) != -1 ) {
            if( proc.flags & _PPF_FLAT ) {
                ProcInfo.flat = TRUE;
                ProcInfo.code_offset = off_info.codeoff;
                ProcInfo.data_offset = off_info.codeoff + off_info.codesize;
            }
            has_flat = TRUE;
        }
        if( ForceFpu32 < 0 ) {
            ProcInfo.fpu32 = FALSE;
        } else if( ForceFpu32 > 0 ) {
            ProcInfo.fpu32 = TRUE;
        } else if( ProcInfo.dbg32 ) {
            ProcInfo.fpu32 = TRUE;
        } else if( info.sflags & _PSF_EMU16_INSTALLED ) {
            /* 16-bit emulator always writes out 16-bit state */
            ProcInfo.fpu32 = FALSE;
        } else if( !ProcInfo.proc32 ) {
            ProcInfo.fpu32 = FALSE;
        } else if( has_flat ) {
            /* Proc32's that support flat model save 16-bit floating point
               state as the full 32-bit form */
            ProcInfo.fpu32 = TRUE;
        } else {
            ProcInfo.fpu32 = FALSE;
        }

        ProcInfo.thread[0].tid = ProcInfo.pid;
        errno = 0;
    }
fail:
    ret->err = errno;
    if( ret->err != 0 ) {
        qnx_vc_detach( ProcInfo.proc );
        ProcInfo.pid = 0;
    }
    ret->mod_handle = MH_DEBUGGEE;
    return( sizeof( *ret ) );
}

unsigned ReqProg_kill()
{
    prog_kill_ret       *ret;
    pid_t               pid;

    ret = GetOutPtr( 0 );
    for( pid = 0; pid = next_thread( pid, THREAD_ALL ); ) {
        if( ProcInfo.loaded_proc && !ProcInfo.at_end ) {
            net_kill( ProcInfo.proc, pid, SIGKILL );
            if( ProcInfo.nid == 0 ) { //NYI: temp kludge
                /* receive the MID signalling task death */
                Receive( 0, 0, 0 );
            }
        }
        __qnx_debug_detach( ProcInfo.proc, pid );
        if( ProcInfo.loaded_proc ) waitpid( -1, NULL, 0 );
    }
    if( ProcInfo.pid ) {
        qnx_proxy_rem_detach( ProcInfo.nid, ProcInfo.mid );
        qnx_vc_detach( ProcInfo.proc );
        ProcInfo.proc = PROC_PID;
    }
    ProcInfo.sig = -1;
    ProcInfo.sflags = 0;
    ProcInfo.at_end = FALSE;
    ProcInfo.save_in = -1;
    ProcInfo.save_out = -1;
    ret->err = 0;
    return( sizeof( *ret ) );
}


unsigned ReqSet_break()
{
    long             opcode;
    set_break_req       *acc;
    set_break_ret       *ret;

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

    __qnx_debug_brk( ProcInfo.proc, ProcInfo.pid, _DEBUG_BRK_SET, &opcode,
                     acc->break_addr.offset, acc->break_addr.segment );
    ret->old = opcode;
    return( sizeof( *ret ) );
}

unsigned ReqClear_break()
{
    long                 opcode;
    clear_break_req     *acc;

    acc = GetInPtr( 0 );
    opcode = acc->old;
    __qnx_debug_brk( ProcInfo.proc, ProcInfo.pid, _DEBUG_BRK_CLR, &opcode,
                acc->break_addr.offset, acc->break_addr.segment );
    return( 0 );
}

unsigned ReqSet_watch()
{
    unsigned      size;
    set_watch_req       *acc;
    set_watch_ret       *ret;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    for( size = acc->size; size != 0; --size ) {
        WatchPoints[ WatchCount ].seg = acc->watch_addr.segment;
        WatchPoints[ WatchCount ].off = acc->watch_addr.offset;
        #if 0
        ReadBuffer( &WatchPoints[ WatchCount ].byte,
            WatchPoints[ WatchCount ].seg, WatchPoints[ WatchCount ].off, 1 );
        #endif
        ++acc->watch_addr.offset;
        ++WatchCount;
    }
    ret->err = 0;
    ret->multiplier = 1000;
    return( sizeof( *ret ) );
}

unsigned ReqClear_watch()
{
    WatchCount = 0; /* assume all are cleared at the same time */
    return( 0 );
}

static void RunHandler( int sig )
{
    sig = sig;
    ProcInfo.stopped = TRUE;
    /* Running this signal handler will cause the Receive to terminate */
}

static int RunIt( unsigned step )
{
    struct _debug_info  info;
    void                (*old)();
    pid_t               pid;
    int                 ret;
    thread_info         *thread;
    thread_info         *new;
    unsigned            i;

    ProcInfo.stopped = TRUE;
    for( thread = ProcInfo.thread; thread < &ProcInfo.thread[ProcInfo.max_threads]; thread++ ) {
        if( thread->tid && thread->fork && !thread->frozen ) {
            __qnx_debug_cont( ProcInfo.proc, thread->tid, 0 );
            thread->tid = 0;
            ProcInfo.stopped = FALSE;
        }
    }
    if( !ProcInfo.stopped ) {
        return( COND_THREAD );
    }
    for( thread = ProcInfo.thread; thread < &ProcInfo.thread[ProcInfo.max_threads]; thread++ ) {
        if( thread->tid == 0 ) continue;
        if( step == 0 || thread->tid == ProcInfo.pid ) {
            if( !thread->frozen ) {
                if( __qnx_debug_cont( ProcInfo.proc, thread->tid, step ) == 0 ) {
                    ProcInfo.stopped = FALSE;
                }
            }
        }
    }
    if( !ProcInfo.stopped ) {
        old = signal( SIGINT, &RunHandler );
        Receive( MID, 0, 0 );
        signal( SIGINT, old );
        if( ProcInfo.stopped ) {
            if( step ) {
                __qnx_debug_hold( ProcInfo.proc, ProcInfo.pid );
            } else {
                for( thread = ProcInfo.thread; thread < &ProcInfo.thread[ProcInfo.max_threads]; thread++ ) {
                    if( thread->tid != 0 ) {
                        __qnx_debug_hold( ProcInfo.proc, thread->tid );
                    }
                }
            }
            return( COND_USER );
        }
        ret = 0;
        for( i = 0; i < ProcInfo.max_threads; i++ ) {
            /*
                Don't walk the thread array directly because it might move
                due to a realloc.
            */
            thread = &ProcInfo.thread[i];
            if( thread->frozen ) continue;
            pid = thread->tid;
            if( pid == 0 ) continue;
            if( step == 0 || pid == ProcInfo.pid ) {
                __qnx_debug_xfer( ProcInfo.proc, pid, _DEBUG_INFO, &info, sizeof( info ), 0, 0 );
                switch( info.debug_state ) {
                case _DEBUG_STATE_CONT:
                    __qnx_debug_hold( ProcInfo.proc, pid );
                    break;
                case _DEBUG_STATE_HELD:
                    ret |= COND_USER;
                    if(pid != ProcInfo.pid) {
                        ProcInfo.pid = pid;
                        ret |= COND_THREAD;
                    }
                    break;
                case _DEBUG_STATE_TRACE:
                    ret |= COND_TRACE;
                    if(pid != ProcInfo.pid) {
                        ProcInfo.pid = pid;
                        ret |= COND_THREAD;
                    }
                    break;
                case _DEBUG_STATE_BRK:
                    ret |= COND_BREAK;
                    if(pid != ProcInfo.pid) {
                        ProcInfo.pid = pid;
                        ret |= COND_THREAD;
                    }
                    break;
                case _DEBUG_STATE_WATCH:
                    ret |= COND_WATCH;
                    if(pid != ProcInfo.pid) {
                        ProcInfo.pid = pid;
                        ret |= COND_THREAD;
                    }
                    break;
                case _DEBUG_STATE_DEAD:
                    thread->dying = TRUE;
                    if( ( pid = next_thread( 0, THREAD_THAWED ) ) || ( pid = next_thread( 0, THREAD_FROZEN ) ) ) {
                        __qnx_debug_detach( ProcInfo.proc, thread->tid );
                        thread->tid = 0;
                        find_thread(pid)->frozen = FALSE;
                        ProcInfo.pid = pid;
                        ret |= COND_THREAD;
                    } else {
                        thread->dying = FALSE;
                        if( pid != ProcInfo.pid ) {
                            ProcInfo.pid = pid;
                            ret |= COND_THREAD;
                        }
                        ProcInfo.at_end = TRUE;
                        ret |= COND_TERMINATE;
                    }
                    break;
                case _DEBUG_STATE_SIGNAL:
                    __qnx_debug_sigclr( ProcInfo.proc, pid, info.signo );
                    if( info.signo == SIGINT ) {
                        ret |= COND_USER;
                    } else {
                        ProcInfo.sig = info.signo;
                        ret = COND_EXCEPTION;
                    }
                    break;
                case _DEBUG_STATE_FORK:
                    ProcInfo.fork = 1;
                    ProcInfo.son = info.messenger;
                    if( new = find_thread( 0 ) ) {
                        new->tid = ProcInfo.son;
                        new->frozen = TRUE;
                        new->fork = TRUE;
                        ret |= COND_THREAD;
                    }
                    ret |= COND_MESSAGE;
                    break;
                case _DEBUG_STATE_THREAD:
                    ProcInfo.son = info.messenger;
                    if( new = find_thread( 0 ) ) {
                        if( __qnx_debug_attach( ProcInfo.proc, ProcInfo.son, ProcInfo.mid ) == 0 ) {
                            new->tid = ProcInfo.son;
                            new->frozen = FALSE;
                        }
                    }
                    ret |= COND_THREAD;
                    break;
                }
            }
        }
        return( ret );
    }
    ProcInfo.at_end = TRUE;
    return( COND_TERMINATE );
}

static unsigned ProgRun( bool step )
{
    struct _reg_struct  regs;
    prog_go_ret         *ret;
    pid_t               pid;

    ret = GetOutPtr( 0 );
    if( ProcInfo.at_end ) {
        ret->conditions = COND_TERMINATE;
    } else if( step ) {
        ret->conditions = RunIt( 1 );
    } else {
        #if 0
        { int i;
        for( i = 0; i < WatchCount; ++i ) {
            Out( "watch at " );
            OutNum( WatchPoints[i].seg );
            Out( ":" );
            OutNum( WatchPoints[i].off );
            Out( "\n" );
        }
        }
        #endif
        for( pid = 0; pid = next_thread( pid, THREAD_THAWED ) ; ) {
            __qnx_debug_xfer( ProcInfo.proc, pid, _DEBUG_WATCH_WR, WatchPoints,
                    WatchCount * sizeof( struct _watch_struct ), 0, 0 );
        }
        ret->conditions = RunIt( 0 );
    }
    if( !(ret->conditions & COND_TERMINATE) ) {
        __qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_REG_RD, &regs, sizeof( regs ), 0, 0 );
        #if 0
        Out( "stopped at " );
        OutNum( regs.ip );
        Out( " because of " );
        OutNum( ret->conditions );
        Out( "\n" );
        #endif
        ret->program_counter.offset = regs.ip;
        ret->program_counter.segment = regs.cs;
        ret->stack_pointer.offset = regs.sp;
        ret->stack_pointer.segment = regs.ss;
    }
    ret->conditions |= COND_CONFIG;
    return( sizeof( *ret ) );
}

unsigned ReqProg_step()
{
    return( ProgRun( TRUE ) );
}

unsigned ReqProg_go()
{
    return( ProgRun( FALSE ) );
}

#define STK_ALIGN( v, type )    ((v)+(sizeof(type)-1) & ~(sizeof(type)-1))

static unsigned_16 Redir32( bool input )
{
    struct  _reg_struct save, new;
    int                 *save_hdl;
    unsigned            len;
    redirect_stdin_ret  *ret;
    char                *file_name;
    dword               code;
    addr48_ptr          slib;

    ret = GetOutPtr( 0 );
    file_name = GetInPtr( sizeof( redirect_stdin_req ) );
    ret->err = 1;
    if( ProcInfo.pid == 0 ) {
        return( sizeof( *ret ) );
    }
    slib = GetSLibTable( TRUE );
    if( slib.segment == 0 ) {
        return( sizeof( *ret ) );
    }
    if( __qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_REG_RD,
                          &save, sizeof( save ), 0, 0 ) != 0 ) {
        return( sizeof( *ret ) );
    }
    new = save;
    if( input ) {
        new.ax = 0;
        save_hdl = &ProcInfo.save_in;
    } else {
        new.ax = 1;
        save_hdl = &ProcInfo.save_out;
    }
    ret->err = 0;
    if( *save_hdl != -1 ) {
        new.cs = slib.segment & ~PRIV_MASK;
        new.cs |= save.cs & PRIV_MASK;
        new.ip = slib.offset;
        new.dx = *save_hdl;
        new.sp -= 3*sizeof( dword );
        code = 256;
        __qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_MEM_WR, &code,
            sizeof( code ), new.sp, new.ss );
        __qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_REG_WR, &new,
            sizeof( new ), 0, 0 );
        __qnx_debug_cont( ProcInfo.proc, ProcInfo.pid, 0 );
        Receive( 0, 0, 0 );
        *save_hdl = -1;
    }
    if( file_name[0] != '\0' ) {
        new.cs = slib.segment & ~PRIV_MASK;
        new.cs |= save.cs & PRIV_MASK;
        new.ip = slib.offset;
        len = strlen( file_name ) + 1;
        new.sp -= STK_ALIGN( len, dword );
        new.dx = new.sp;
        __qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_MEM_WR, file_name,
            len, new.sp, new.ss );
        new.sp -= 3*sizeof( dword );
        code = 257;
        __qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_MEM_WR, &code,
            sizeof( code ), new.sp, new.ss );
        __qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_REG_WR, &new,
            sizeof( new ), 0, 0 );
        __qnx_debug_cont( ProcInfo.proc, ProcInfo.pid, 0 );
        Receive( 0, 0, 0 );
        __qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_REG_RD, &new,
            sizeof( new ), 0, 0 );
        if( (unsigned)new.ax == -1 ) ret->err = 1;
        *save_hdl = new.ax;
    }
    __qnx_debug_xfer( ProcInfo.proc, ProcInfo.pid, _DEBUG_REG_WR, &save,
            sizeof( save ), 0, 0 );
    return( sizeof( *ret ) );
}


unsigned Redir16( bool input )
{
    struct  _reg_struct save, new;
    addr48_ptr          slib;
    addr32_ptr          func;
    int                 *save_hdl;
    unsigned            len;
    redirect_stdin_ret  *ret;
    char                *file_name;

    ret = GetOutPtr( 0 );
    file_name = GetInPtr( sizeof( redirect_stdin_req ) );
    ret->err = 1;
    if( ProcInfo.pid == 0 ) {
        return( sizeof( *ret ) );

⌨️ 快捷键说明

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