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 + -
显示快捷键?