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

📄 nlmacc.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    acc = GetInPtr(0);

    addr.offset = acc->mem_addr.offset;
    addr.segment = acc->mem_addr.segment;
    len = ReadWrite( ReadMemory, &addr, GetOutPtr(0), acc->len );
    return( len );
}

unsigned ReqWrite_mem( void )
{
    addr48_ptr          addr;
    write_mem_req       *acc;
    write_mem_ret       *ret;
    unsigned            len;

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

    len = GetTotalSize() - sizeof(*acc);

    addr.offset = acc->mem_addr.offset;
    addr.segment = acc->mem_addr.segment;
    ret->len = ReadWrite( WriteMemory, &addr, GetInPtr(sizeof(*acc)), len );
    return( sizeof( *ret ) );
}


unsigned ReqRead_io( void )
{
    read_io_req *acc;
    void         *data;

    acc = GetInPtr(0);
    data = GetOutPtr( 0 );
    if( acc->len == 1 ) {
        *( (byte *)data ) = in_b( acc->IO_offset );
    } else if( acc->len == 2 ) {
        *( (word *)data ) = in_w( acc->IO_offset );
    } else {
        *( (dword *)data ) = in_d( acc->IO_offset );
    }
    return( acc->len );
}


unsigned ReqWrite_io( void )
{
    write_io_req        *acc;
    write_io_ret        *ret;
    void         *data;
    unsigned  len;

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    data = GetInPtr( sizeof( *acc ) );
    len = GetTotalSize() - sizeof( *acc );
    if( len == 1 ) {
        out_b( acc->IO_offset, *( (byte *)data ) );
    } else if( len == 2 ) {
        out_w( acc->IO_offset, *( (word *)data ) );
    } else {
        out_d( acc->IO_offset, *( (dword *)data ) );
    }
    ret->len = len;
    return( sizeof( *ret ) );
}

//obsolete
unsigned ReqRead_cpu( void )
{
    trap_cpu_regs       *regs;

    regs = GetOutPtr(0);
    if( MSB == NULL ) {
        memset( regs, 0, sizeof( *regs ) );
    } else {
        *regs = MSB->cpu;
    }
    return( sizeof( *regs ) );
}

//obsolete
unsigned ReqRead_fpu( void )
{
    trap_fpu_regs       *regs;

    regs = GetOutPtr(0);
    if( MSB == NULL ) {
        memset( regs, 0, sizeof( *regs ) );
    } else {
        *regs = MSB->fpu;
    }
    return( sizeof( *regs ) );
}

//obsolete
unsigned ReqWrite_cpu( void )
{
    if( MSB != NULL ) {
        MSB->cpu = *(trap_cpu_regs *)GetInPtr(sizeof(write_cpu_req));
    }
    return( 0 );
}

//obsolete
unsigned ReqWrite_fpu( void )
{
    if( MSB != NULL ) {
        MSB->fpu = *(trap_fpu_regs *)GetInPtr(sizeof(write_fpu_req));
    }
    return( 0 );
}

unsigned ReqRead_regs( void )
{
    mad_registers       *mr;

    mr = GetOutPtr(0);
    memset( mr, 0, sizeof( mr->x86 ) );
    if( MSB != NULL ) {
        mr->x86.cpu = *(struct x86_cpu *)&MSB->cpu;
        mr->x86.fpu = *(struct x86_fpu *)&MSB->fpu;
    }
    return( sizeof( mr->x86 ) );
}

unsigned ReqWrite_regs( void )
{
    mad_registers       *mr;

    mr = GetInPtr(sizeof(write_regs_req));
    if( MSB != NULL ) {
        *(struct x86_cpu *)&MSB->cpu = mr->x86.cpu;
        *(struct x86_fpu *)&MSB->fpu = mr->x86.fpu;
    }
    return( 0 );
}

static char *LoadName;
static unsigned LoadLen;
static prog_load_ret *LoadRet;

static void LoadHelper( void )
{
    int         err;
    int         handle;
    char        *src, *dst;
    char        nlm_name[256];
    char        ch;
    unsigned    len;

    Enable();
    MSBHead = NULL;
    ThreadId = 0;
    MSB = NULL;
    src = LoadName;
    StringToNLMPath( src, nlm_name );
    dst = CmdLine;
    len = LoadLen;

    for( ;; ) {
        if( len == 0 )
            break;
        ch = *src;
        if( ch == '\0' )
            ch = ' ';
        *dst = ch;
        ++dst;
        ++src;
        --len;
    }

    if( dst > CmdLine && src[-1] == '\0' )
        --dst;
    *dst = '\0';
    LoadRet->err = 0;
    NLMState = NLM_PRELOADING;
    _DBG_EVENT(( "*LoadHelper: NLMState = NLM_PRELOADING\r\n" ));
    ExpectingEvent = TRUE;

    if( nlm_name[0] == '\0'
     || ( handle = IOOpen( nlm_name, O_RDONLY ) ) == -1
     || IOSeek( handle, SEEK_SET, offsetof( nlm_header, moduleName ) )
                != offsetof( nlm_header, moduleName )
     || IORead( handle, NLMName, 14 ) != 14
     || IOClose( handle ) != 0 ) {
        NLMState = NLM_NONE;
        _DBG_EVENT(( "  NLMState = NLM_NONE\r\n" ));
        DebuggerLoadedNLM = NULL;
        if( LoadRet != NULL )
            LoadRet->err = 2;
        _DBG_EVENT(( "  Waking up the debugger for noopen event\r\n" ));
        WakeDebugger();
    } else {
        _DBG_EVENT(( "  Name is '%S'\r\n", NLMName ));
        err = LoadModule( systemConsoleScreen, CmdLine, LO_DEBUG );
        _DBG_EVENT(( "  Load ret code %d\r\n", err ));
        if( err != 0 ) {
            NLMState = NLM_NONE;
            _DBG_EVENT(( "    NLMState = NLM_NONE\r\n" ));
            DebuggerLoadedNLM = NULL;
            if( LoadRet != NULL )
                LoadRet->err = err;
            _DBG_EVENT(( "    Waking up the debugger for noload event\r\n" ));
            WakeDebugger();
        }
    }
    FreeThread( LocateThread( RunningProcess ) );

    if( NLMState != NLM_NONE) {
        NLMState = NLM_LOADED;
        _DBG_EVENT(( "LoadHelper: NLMState = NLM_LOADED\r\n" ));
#if defined ( _USE_NEW_KERNEL )
        kSemaphoreWait( kHelperSem );
#else
        CPSemaphore( HelperSem );
#endif
        _DBG_EVENT(( "LoadHelper: Helper awake -- calling KillMe NLM=%8x!\r\n", DebuggerLoadedNLM ));
        NLMState = NLM_NONE;
        _DBG_EVENT(( "LoadHelper: NLMState = NLM_NONE\r\n" ));
        if( DebuggerLoadedNLM )
            KillMe( DebuggerLoadedNLM );
    }
    DebuggerLoadedNLM = NULL;
    _DBG_EVENT(( "LoadHelper: Helper killing itself\r\n" ));
    Suicide();
}

#if 0
static void LoadHelper( void )
{
    int         err;
    int         handle;
    char        *src, *dst;
    char        nlm_name[256];
    char        ch;
    unsigned    len;

    Enable();
    MSBHead = NULL;
    ThreadId = 0;
    MSB = NULL;
    src = LoadName;
    StringToNLMPath( src, nlm_name );
    dst = CmdLine;
    len = LoadLen;
    for( ;; ) {
        if( len == 0 )
            break;
        ch = *src;
        if( ch == '\0' )
            ch = ' ';
        *dst = ch;
        ++dst;
        ++src;
        --len;
    }
    if( dst > CmdLine && src[-1] == '\0' )
        --dst;
    *dst = '\0';
    LoadRet->err = 0;
    NLMState = NLM_PRELOADING;
    _DBG_EVENT(( "*LoadHelper: NLMState = NLM_PRELOADING\r\n" ));
    ExpectingEvent = TRUE;
    if( nlm_name[0] == '\0'
     || ( handle = IOOpen( nlm_name, O_RDONLY ) ) == -1
     || IOSeek( handle, SEEK_SET, offsetof( nlm_header, moduleName ) )
                != offsetof( nlm_header, moduleName )
     || IORead( handle, NLMName, 14 ) != 14
     || IOClose( handle ) != 0 ) {
        NLMState = NLM_NONE;
        _DBG_EVENT(( "  NLMState = NLM_NONE\r\n" ));
        DebuggerLoadedNLM = NULL;
        if( LoadRet != NULL ) LoadRet->err = 2;
        _DBG_EVENT(( "  Waking up the debugger for noopen event\r\n" ));
        WakeDebugger();
    } else {
        _DBG_EVENT(( "  Name is '%S'\r\n", NLMName ));
        err = LoadModule( systemConsoleScreen, CmdLine, LO_DEBUG );
        _DBG_EVENT(( "  Load ret code %d\r\n", err ));
        if( err != 0 ) {
            NLMState = NLM_NONE;
            _DBG_EVENT(( "    NLMState = NLM_NONE\r\n" ));
            DebuggerLoadedNLM = NULL;
            if( LoadRet != NULL )
                LoadRet->err = err;
            _DBG_EVENT(( "    Waking up the debugger for noload event\r\n" ));
            WakeDebugger();
        }
    }
    FreeThread( LocateThread( RunningProcess ) );
    NLMState = NLM_LOADED;
    _DBG_EVENT(( "LoadHelper: NLMState = NLM_LOADED\r\n" ));
    CPSemaphore( HelperSem );
    _DBG_EVENT(( "LoadHelper: Helper awake -- calling KillMe NLM=%8x!\r\n", DebuggerLoadedNLM ));
    NLMState = NLM_NONE;
    _DBG_EVENT(( "LoadHelper: NLMState = NLM_NONE\r\n" ));
    if( DebuggerLoadedNLM )
        KillMe( DebuggerLoadedNLM );
    DebuggerLoadedNLM = NULL;
    _DBG_EVENT(( "LoadHelper: Helper killing itself\r\n" ));
    Suicide();
}
#endif

static char    helper_stack[8192]; /* We may return before thread dies! */

unsigned ReqProg_load( void )
{
    prog_load_ret       *ret;
    struct LoadDefinitionStructure *ld;
    LoadedListHandle    nlm;

    LoadName = (char *)GetInPtr( sizeof( prog_load_req ) );
    LoadLen = GetTotalSize() - sizeof( prog_load_req );
    ret = GetOutPtr( 0 );
    LoadRet = ret;
    // scheduling priority, code address, stack top, stack len, process name, resource tag
    CMakeProcess( 50, &LoadHelper, &helper_stack[ sizeof( helper_stack ) ],
                    sizeof( helper_stack ), TRP_The_WATCOM_Debugger, ProcessTag );
    _DBG_EVENT(( "*ReqProg_load: Putting debugger to sleep for load of %s\r\n", LoadName ));
    SleepDebugger();
    _DBG_EVENT(( "ReqProg_load: Debugger awake after load\r\n" ));

    ret->task_id = 1;
    ret->flags = LD_FLAG_IS_32 | LD_FLAG_IS_PROT;
    ret->mod_handle = 0;
    LoadRet = NULL;
    // The list that is traversed are all the loaded NLMs.
    // nlm is an index/handle of some sort.
    // ld is a pointer to a block of information about the NLM
    //    including its name.
    nlm = 0;
    for( ;; ) {
        nlm = GetNextLoadedListEntry( nlm );
        if( nlm == 0 )
            break;
        ld = ValidateModuleHandle( nlm );
        if( ld != DebuggerLoadedNLM ) {
            // skip the main NLM
            NewNLMListEntry( ld );
        }
    }
    _DBG_THREAD(("ReqProg_load: MSB after load=%8x\r\n", MSB));
    return( sizeof( *ret ) );
}

unsigned ReqProg_kill( void )
{
    msb         *m;
    prog_kill_ret       *ret;

    FreeInvalidThreads();
    if( DebuggerLoadedNLM != NULL ) {
        m = MSBHead;
        while( m != NULL ) {
            m->to_be_killed = TRUE;
            if( m->asleep && m->clib_created ) {
                DebuggerLoadedNLM = NULL;
                SetupPIDForACleanExit( m->os_id );
            }
#if defined ( _USE_NEW_KERNEL )
            _DBG_THREAD(( "----- Releasing semaphore for MSB=%8x, sem=%8x\r\n", m, m->ksem ));
            msb_KernelSemaphoreReleaseAll( m );
            m->ksem = NULL;
#else
            _DBG_THREAD(( "----- Releasing semaphore for MSB=%8x, sem=%8x\r\n", m, m->sem ));
            CSemaphoreReleaseAll( m->sem ); /* will be freed when thread awakes */
            m->sem = 0;
#endif
            m = m->next;
        }
    }
    while( NLMList != NULL ) {
        FreeAnNLMListEntry();
    }
    LastNLMListEntry = NULL;
#if defined ( _USE_NEW_KERNEL )
    kSemaphoreSignal( kHelperSem );
#else
    CVSemaphore( HelperSem );
#endif
    ret = GetOutPtr( 0 );
    ret->err = 0;
    return( sizeof( *ret ) );
}


unsigned Execute( msb *which )
{
    msb         *m;

    for( m = MSBHead; m != NULL; m = m->next ) {
        _DBG_THREAD(( "check thread msb=%8x: frozen=%d, asleep=%d\r\n", m, m->frozen, m->asleep ));
        if( !m->frozen && m->asleep ) {
            if( which == NULL || which == m ) {
#if defined ( _USE_NEW_KERNEL )
                _DBG_THREAD(( "Letting a thread execute, MSB=%8x, sem=%8x\r\n", m, m->ksem ));
                kSemaphoreSignal( m->ksem );
#else
                _DBG_THREAD(( "Letting a thread execute, MSB=%8x, sem=%8x\r\n", m, m->sem ));
                CVSemaphore( m->sem );
#endif
            }
        }
    }
    /* freeze all threads!!! */
    _DBG_EVENT(( "*Execute: Putting debugger to sleep for execution\r\n" ));
    SleepDebugger();
    _DBG_EVENT(( "Execute: Debugger awake after execution\r\n" ));
    if( MSB == NULL )
        return( COND_TERMINATE );
    switch( MSB->xnum )
    {
    case 1:
        if( FakeBreak ) {
            FakeBreak = FALSE;
            return( COND_USER );
        }
        if( MSB->errnum & DR6_BS ) {
            return( COND_TRACE );
        } else if( MSB->errnum & ( DR6_B0+DR6_B1+DR6_B2+DR6_B3 ) ) {
            return( COND_WATCH );
        } else {
            return( COND_EXCEPTION );
        }
    case 3:
        return( COND_BREAK );
    case ENTER_DEBUGGER_EVENT:
    case KEYBOARD_BREAK_EVENT:
        return( COND_USER );
    case TERMINATE_NLM_EVENT:
        if( DebuggerLoadedNLM == NULL ) {
            return( COND_LIBRARIES | COND_TERMINATE );
        } else {
            return( COND_LIBRARIES );
        }
    case START_NLM_EVENT:
        return( COND_LIBRARIES );
    case START_THREAD_EVENT:
    case TERMINATE_THREAD_EVENT:
        return( 0 );
    case INVALID_INTERRUPT_ABEND:
    case ASSEMBLY_ABEND:
    case BREAKPOINT_FUNCTION_EVENT:
    default:
        return( COND_EXCEPTION );
    }
}

unsigned ReqSet_watch( void )
{
    dword        l;
    set_watch_req       *acc;
    set_watch_ret       *ret;
    watch        *curr;
    int         i,needed;
    int         dreg_avail[4];

    acc = GetInPtr( 0 );
    ret = GetOutPtr( 0 );
    ret->err = 1;
    ret->multiplier = 2000;
    if( WatchCount < MAX_WP && ReadMemory( &acc->watch_addr, 4UL, &l ) == 0 ) {
        ret->err = 0;
        curr = WatchPoints + WatchCount;
        curr->addr.segment = acc->watch_addr.segment;
        curr->addr.offset = acc->watch_addr.offset;
        curr->linear = acc->watch_addr.offset;
        curr->len = acc->size;
        curr->linear &= ~(curr->len-1);
        curr->dregs = ( curr->addr.offset & (curr->len-1) ) ? 2 : 1;
        curr->value = l;
        ++WatchCount;
        needed = 0;
        for( i = 0; i < WatchCount; ++i ) {
            needed += WatchPoints[ i ].dregs;
        }
        for( i = 0; i < NUM_DREG; ++i ) {
            dreg_avail[ i ] = DoReserveBreakpoint();
            if( dreg_avail[ i ] < 0 )
                break;
        }
        for( i = 0; i < NUM_DREG; ++i ) {
            if( dreg_avail[ i ] < 0 )
                break;
            UnReserveABreakpoint( dreg_avail[ i ] );
        }
        if( needed <= i )
            ret->multiplier |= USING_DEBUG_REG;
    }
    return( sizeof( *ret ) );
}

unsigned ReqClear_watch( void )
{
    WatchCount = 0;
    return( 0 );
}

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

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

⌨️ 快捷键说明

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