remcore.c

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

C
756
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Remote access core - trap file interface.
*
****************************************************************************/


#include <string.h>

#include "dbgdefn.h"
#include "dbgreg.h"
#include "dbgerr.h"
#include "dbgio.h"
#include "dbgmem.h"
#include "dbgtoggl.h"
#include "dbginfo.h"
#include "trpcore.h"
#include "tcerr.h"
#include "dbglit.h"
#include "mad.h"
#include "dui.h"

extern void             FiniSuppServices( void );
extern void             InitSuppServices( void );
extern void             RestoreHandlers( void );
extern void             GrabHandlers( void );
extern int              SameAddrSpace( address, address );
extern void             SectLoad( unsigned int );
extern void             FreeThreads( void );
extern void             RemapSection( unsigned, unsigned );
extern void             CheckForNewThreads( bool );
extern void             AddAliasInfo( unsigned, unsigned );
extern void             GetSysConfig( void );
extern void             AddrFix( address * );
extern void             AddrFloat( address * );
extern void             InvalidateTblCache( void );
extern void             InitLC( location_context *new, bool use_real_regs );
extern dtid_t           RemoteSetThread( dtid_t );
extern void             RemoteSectTblRead( void * );
extern void             RemoteSectTblWrite( void * );
extern void             CheckMADChange( void );
#if defined(__GUI__) && defined(__OS2__)
extern unsigned         OnAnotherThread( unsigned(*)(), unsigned, void *, unsigned, void * );
#else
#define                 OnAnotherThread( a,b,c,d,e ) a( b,c,d,e )
#endif

extern unsigned         MaxPacketLen;
extern unsigned         TaskId;
extern machine_state    *DbgRegs;
extern system_config    SysConfig;
extern address          NilAddr;
extern struct location_context Context;
extern unsigned         CurrRegSize;

//NYI: We don't know the size of the incoming err msg. Now assume max is 80.
#define MAX_ERR_MSG_SIZE        80

typedef struct{
    address     addr;
    unsigned    len;
    char        *data;
} cache_block;

typedef struct {
    address     addr;
    addr48_off  end;
    unsigned    info;
    unsigned    len;
    unsigned_8  data[1];        /* variable sized */
} machine_data_cache;

static cache_block              Cache;
static machine_data_cache       *MData = NULL;

static bool IsInterrupt( addr_ptr *addr, unsigned size )
{
    return( MADAddrInterrupt( addr, size, &DbgRegs->mr ) == MS_OK );
}

static unsigned MemRead( address addr, void *ptr, unsigned size )
{
    mx_entry            in[1];
    mx_entry            out[1];
    read_mem_req        acc;
    bool                int_tbl;
    unsigned            left;
    unsigned            piece;
    unsigned            got;

    if( size == 0 ) return( 0 );
    SectLoad( addr.sect_id );
    acc.req = REQ_READ_MEM;
    AddrFix( &addr );
    acc.mem_addr = addr.mach;
    in[0].ptr = &acc;
    in[0].len = sizeof( acc );
    left = size;
    for( ;; ) {
        if( left > MaxPacketLen ) {
            piece = MaxPacketLen;
        } else {
            piece = left;
        }
        out[0].ptr = ptr;
        out[0].len = piece;
        acc.len = piece;

        int_tbl = IsInterrupt( &(acc.mem_addr), size );
        if( int_tbl ) RestoreHandlers();
        CONV_LE_32( acc.mem_addr.offset );
        CONV_LE_16( acc.mem_addr.segment );
        CONV_LE_16( acc.len );
        got = TrapAccess( 1, &in, 1, &out );
        if( int_tbl ) GrabHandlers();

        left -= got;
        if( left == 0 ) break;
        if( got != piece ) break;
    addr.mach.offset += piece;
        acc.mem_addr = addr.mach;
        ptr = (char *)ptr + piece;
    }
    return( size - left );
}

void FiniCache( void )
{
    _Free( Cache.data );
    Cache.data = NULL;
}

void InitCache( address addr, unsigned size )
{
    void *ptr;

    if( size == 0 ) return;
    FiniCache();
    _Alloc( ptr, size );
    if( ptr == NULL ) return;
    Cache.data = ptr;
    Cache.addr = addr;
    Cache.len = MemRead( addr, ptr, size );
}

bool HaveCache( void )
{
    return( Cache.data != NULL );
}

static bool ReadCache( address addr, char *data, unsigned len )
{
    if( Cache.data == NULL ) return( FALSE );
    if( !SameAddrSpace( Cache.addr, addr ) ) return( FALSE );
    if( len > Cache.len ) return( FALSE );
    if( Cache.addr.mach.offset > addr.mach.offset ) return( FALSE );
    addr.mach.offset -= Cache.addr.mach.offset;
    if( Cache.len - len < addr.mach.offset ) return( FALSE );
    memcpy( data, &Cache.data[ addr.mach.offset ], len );
    return( TRUE );
}

unsigned ProgPeek( address addr, void *data, unsigned len )
{
    if( ReadCache( addr, data, len ) ) {
        return( len );
    } else {
        return( MemRead( addr, data, len ) );
    }
}

unsigned ProgPoke( address addr, void *data, unsigned len )
{
    mx_entry            in[2];
    mx_entry            out[1];
    write_mem_req       acc;
    write_mem_ret       ret;
    bool                int_tbl;
    unsigned            left;
    unsigned            piece;

    SectLoad( addr.sect_id );
    acc.req = REQ_WRITE_MEM;
    AddrFix( &addr );
    acc.mem_addr = addr.mach;
    in[0].ptr = &acc;
    in[0].len = sizeof( acc );
    out[0].ptr = &ret;
    out[0].len = sizeof( ret );
    left = len;
    for( ;; ) {
        if( left > (MaxPacketLen - sizeof( acc )) ) {
            piece = MaxPacketLen - sizeof( acc );
        } else {
            piece = left;
        }
        in[1].ptr = data;
        in[1].len = piece;

        int_tbl = IsInterrupt( &(acc.mem_addr), len );
        if( int_tbl ) RestoreHandlers();
        CONV_LE_32( acc.mem_addr.offset );
        CONV_LE_16( acc.mem_addr.segment );
        TrapAccess( 2, &in, 1, &out );
        CONV_LE_16( ret.len );
        if( int_tbl ) GrabHandlers();

        left -= ret.len;
        if( left == 0 ) break;
        if( ret.len != piece ) break;
    addr.mach.offset += piece;
        acc.mem_addr = addr.mach;
        data = (char *)data + piece;
    }
    return( len - left );
}


unsigned long ProgChkSum( address addr, unsigned len )
{

    checksum_mem_req    acc;
    checksum_mem_ret    ret;

    SectLoad( addr.sect_id );
    acc.req = REQ_CHECKSUM_MEM;
    AddrFix( &addr );
    acc.in_addr = addr.mach;
    acc.len = len;
    TrapSimpAccess( sizeof( acc ), &acc, sizeof( ret ), &ret );
    return( ret.result );
}

unsigned PortPeek( unsigned port, void *data, unsigned size )
{
    mx_entry            in[1];
    mx_entry            out[1];
    read_io_req         acc;

    acc.req = REQ_READ_IO;
    acc.IO_offset = port;
    acc.len = size;
    in[0].ptr = &acc;
    in[0].len = sizeof( acc );
    out[0].ptr = data;
    out[0].len = size;
    return( TrapAccess( 1, &in, 1, &out ) );
}

unsigned PortPoke( unsigned port, void *data, unsigned size )
{
    mx_entry            in[2];
    mx_entry            out[1];
    write_io_req        acc;
    write_io_ret        ret;

    acc.req = REQ_WRITE_IO;
    acc.IO_offset = port;
    in[0].ptr = &acc;
    in[0].len = sizeof( acc );
    in[1].ptr = data;
    in[1].len = size;
    out[0].ptr = &ret;
    out[0].len = sizeof( ret );
    TrapAccess( 2, &in, 1, &out );
    return( ret.len );
}

static void ReadRegs( machine_state *state )
{
    read_regs_req       acc;

    acc.req = REQ_READ_REGS;
    TrapSimpAccess( sizeof(acc), &acc, CurrRegSize, &state->mr );
    MADRegistersHost( &state->mr );
    if( state->ovl != NULL ) {
        RemoteSectTblRead( state->ovl );
    }
}

void ReadDbgRegs( void )
{
    ReadRegs( DbgRegs );
    InitLC( &Context, TRUE );
}

static void WriteRegs( machine_state *state )
{
    mx_entry            in[2];
    write_regs_req      acc;
    mad_status          ms;

    ms = MADRegistersTarget( &state->mr );
    acc.req = REQ_WRITE_REGS;
    in[0].ptr = &acc;
    in[0].len = sizeof( acc );
    in[1].ptr = &state->mr;
    in[1].len = CurrRegSize;
    TrapAccess( 2, &in, 0, NULL );
    // Always convert regs back to host format; might be more
    // efficient to create a local copy instead
    MADRegistersHost( &state->mr );
    if( state->ovl != NULL ) {
        RemoteSectTblWrite( state->ovl );
    }
}

void WriteDbgRegs( void )
{
    WriteRegs( DbgRegs );
}

unsigned int ArgsLen( char *args )
{
    unsigned int        len = 0;

    while( *args != ARG_TERMINATE ) {
        len++;
        args++;
    }
    return( len );
}

void ClearMachineDataCache( void )
{
    MData->addr = NilAddr;
    MData->end  = 0;
}

/*
 * DoLoad -- load in user program as an overlay
 */

unsigned DoLoad( char *args, unsigned long *phandle )
{
    mx_entry            in[2];
    mx_entry            out[1];
    prog_load_req       acc;
    prog_load_ret       ret;

    ClearMachineDataCache();
    acc.req = REQ_PROG_LOAD;
    acc.true_argv = _IsOn( SW_TRUE_ARGV );
    in[0].ptr = &acc;
    in[0].len = sizeof( acc );
    in[1].ptr = args;
    in[1].len = ArgsLen( args );
    out[0].ptr = &ret;
    out[0].len = sizeof( ret );
    ret.flags = 0;      /* in case of error */
    ret.mod_handle = 0;
    ret.task_id = 0;
    RestoreHandlers();
    FiniSuppServices();

⌨️ 快捷键说明

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