📄 rsiacc.c
字号:
unsigned_32 off;
unsigned i;
object_record obj;
union {
dos_exe_header dos;
os2_flat_header os2;
} head;
handle = open( name, O_BINARY | O_RDONLY, 0 );
if( handle == -1 ) return;
read( handle, &head.dos, sizeof( head.dos ) );
if( head.dos.signature != DOS_SIGNATURE ) {
close( handle );
return;
}
lseek( handle, OS2_NE_OFFSET, SEEK_SET );
read( handle, &off, sizeof( off ) );
lseek( handle, off, SEEK_SET );
read( handle, &head.os2, sizeof( head.os2 ) );
switch( head.os2.signature ) {
case OSF_FLAT_SIGNATURE:
case OSF_FLAT_LX_SIGNATURE:
lseek( handle, head.os2.objtab_off + off, SEEK_SET );
NumObjects = head.os2.num_objects;
ObjInfo = realloc( ObjInfo, NumObjects * sizeof( *ObjInfo ) );
for( i = 0; i < head.os2.num_objects; ++i ) {
read( handle, &obj, sizeof( obj ) );
ObjInfo[i].size = obj.size;
ObjInfo[i].start = obj.addr;
}
break;
default:
NumObjects = 0;
break;
}
close( handle );
}
unsigned ReqProg_load()
{
char *src;
char *dst;
char *name;
char ch;
prog_load_ret *ret;
unsigned len;
_DBG1(( "AccLoadProg\r\n" ));
AtEnd = FALSE;
dst = UtilBuff;
src = name = GetInPtr( sizeof( prog_load_req ) );
ret = GetOutPtr( 0 );
while( *src != '\0' ) ++src;
++src;
len = GetTotalSize() - (src - name) - sizeof( prog_load_req );
for( ;; ) {
if( len == 0 ) break;
ch = *src;
if( ch == '\0' ) ch = ' ';
*dst = ch;
++src;
++dst;
--len;
}
if( dst > UtilBuff ) --dst;
*dst = '\0';
_DBG1(( "about to debugload\r\n" ));
_DBG1(( "Name :" ));
_DBG1(( name ));
_DBG1(( "\r\n" ));
_DBG1(( "UtilBuff :" ));
_DBG1(( UtilBuff ));
_DBG1(( "\r\n" ));
GetObjectInfo( name );
ret->err = D32DebugLoad( name, UtilBuff, &Proc );
_DBG1(( "back from debugload - %d\r\n", ret->err ));
ret->flags = LD_FLAG_IS_32 | LD_FLAG_IS_PROT | LD_FLAG_DISPLAY_DAMAGED;
if( ret->err == 0 ) {
ret->task_id = Proc.es;
} else {
ret->task_id = 0;
}
ret->mod_handle = 0;
Proc.int_id = -1;
_DBG1(( "done AccLoadProg\r\n" ));
return( sizeof( *ret ) );
}
unsigned ReqProg_kill()
{
prog_kill_ret *ret;
_DBG1(( "AccKillProg\n" ));
ret = GetOutPtr( 0 );
InitRedirect();
AtEnd = TRUE;
ret->err = 0;
return( sizeof( *ret ) );
}
unsigned ReqSet_watch()
{
watch *curr;
set_watch_req *acc;
set_watch_ret *ret;
int i;
int needed;
_DBG1(( "AccSetWatch\n" ));
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
ret->multiplier = 5000;
ret->err = 0;
curr = WatchPoints + WatchCount;
curr->addr.segment = acc->watch_addr.segment;
curr->addr.offset = acc->watch_addr.offset;
curr->linear = DPMIGetSegmentBaseAddress( curr->addr.segment ) + curr->addr.offset;
curr->len = acc->size;
curr->dregs = ( curr->linear & (curr->len-1) ) ? 2 : 1;
curr->handle = -1;
curr->handle2 = -1;
curr->value = 0;
ReadMemory( (addr48_ptr *)&acc->watch_addr, (byte far *)&curr->value, curr->len );
++WatchCount;
needed = 0;
for( i = 0; i < WatchCount; ++i ) {
needed += WatchPoints[ i ].dregs;
}
if( needed <= 4 ) ret->multiplier |= USING_DEBUG_REG;
return( sizeof( *ret ) );
}
unsigned ReqClear_watch()
{
_DBG1(( "AccRestoreWatch\n" ));
/* assume all watches removed at same time */
WatchCount = 0;
return( 0 );
}
unsigned ReqSet_break()
{
set_break_req *acc;
set_break_ret *ret;
_DBG1(( "AccSetBreak\n" ));
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
D32DebugSetBreak( acc->break_addr.offset, acc->break_addr.segment,
FALSE, &Break, (byte *)&ret->old );
return( sizeof( *ret ) );
}
unsigned ReqClear_break()
{
clear_break_req *acc;
char dummy;
acc = GetInPtr( 0 );
_DBG1(( "AccRestoreBreak\n" ));
/* assume all breaks removed at same time */
D32DebugSetBreak( acc->break_addr.offset, acc->break_addr.segment,
FALSE, (byte *)&acc->old, &dummy );
return( 0 );
}
static unsigned long SetDRn( int i, unsigned long linear, long type )
{
switch( i ) {
case 0:
SetDR0( linear );
break;
case 1:
SetDR1( linear );
break;
case 2:
SetDR2( linear );
break;
case 3:
SetDR3( linear );
break;
}
return( ( type << DR7_RWLSHIFT(i) )
// | ( DR7_GEMASK << DR7_GLSHIFT(i) ) | DR7_GE
| ( DR7_LEMASK << DR7_GLSHIFT(i) ) | DR7_LE );
}
void ClearDebugRegs()
{
int i;
watch *wp;
if( IsDPMI ) {
for( i = WatchCount, wp = WatchPoints; i != 0; --i, ++wp ) {
if( wp->handle >= 0 ) {
DPMIClearWatch( wp->handle );
wp->handle = -1;
}
if( wp->handle2 >= 0 ) {
DPMIClearWatch( wp->handle2 );
wp->handle2 = -1;
}
}
} else {
SetDR6( 0 );
SetDR7( 0 );
}
}
static bool SetDebugRegs()
{
int needed;
int i;
watch *wp;
bool success;
long rc;
needed = 0;
for( i = WatchCount, wp = WatchPoints; i != 0; --i, ++wp ) {
needed += wp->dregs;
}
if( needed > 4 ) return( FALSE );
if( IsDPMI ) {
success = TRUE;
for( i = WatchCount, wp = WatchPoints; i != 0; --i, ++wp ) {
wp->handle = -1;
wp->handle2 = -1;
}
for( i = WatchCount, wp = WatchPoints; i != 0; --i, ++wp ) {
_DBG2(( "Setting Watch On %8.8lx\r\n", wp->linear ));
success = FALSE;
rc = DPMISetWatch( wp->linear, wp->len, DPMI_WATCH_WRITE );
_DBG2(( "OK 1 = %d\r\n", rc >= 0 ));
if( rc < 0 ) break;
wp->handle = rc;
if( wp->dregs == 2 ) {
rc = DPMISetWatch( wp->linear+4, wp->len, DPMI_WATCH_WRITE );
_DBG2(( "OK 2 = %d\r\n", rc >= 0 ));
if( rc <= 0 ) break;
wp->handle2 = rc;
}
success = TRUE;
}
if( !success ) {
ClearDebugRegs();
}
return( success );
} else {
int dr;
unsigned long dr7;
dr = 0;
dr7 = 0;
for( i = WatchCount, wp = WatchPoints; i != 0; --i, ++wp ) {
dr7 |= SetDRn( dr, wp->linear, DRLen( wp->len ) | DR7_BWR );
++dr;
if( wp->dregs == 2 ) {
dr7 |= SetDRn( dr, wp->linear+4, DRLen( wp->len ) | DR7_BWR );
++dr;
}
}
SetDR7( dr7 );
return( TRUE );
}
}
static unsigned DoRun()
{
D32DebugRun( &Proc );
switch( Proc.int_id ) {
case 1:
return( COND_TRACE );
case 3:
return( COND_BREAK );
case 5:
return( COND_USER );
case 6:
case 7:
case 0xd:
return( COND_EXCEPTION );
case 0x21:
return( COND_TERMINATE );
case 0x23:
return( COND_EXCEPTION ); // should be TRAP_USER
default:
return( COND_EXCEPTION );
}
}
static bool CheckWatchPoints()
{
addr48_ptr addr;
dword val;
watch *wp;
for( wp = WatchPoints; wp < WatchPoints + WatchCount; ++wp ) {
addr.segment = wp->addr.segment;
addr.offset = wp->addr.offset;
val = 0;
if( ReadMemory( &addr, (byte far *)&val, wp->len ) != wp->len ) {
return( TRUE );
}
if( val != wp->value ) {
return( TRUE );
}
}
return( FALSE );
}
static unsigned ProgRun( bool step )
{
prog_go_ret *ret;
byte int_buff[3];
addr48_ptr addr;
_DBG1(( "AccRunProg\n" ));
ret = GetOutPtr( 0 );
if( step ) {
Proc.eflags |= 0x100;
ret->conditions = DoRun();
Proc.eflags &= ~0x100;
} else if( WatchCount != 0 ) {
if( SetDebugRegs() ) {
ret->conditions = DoRun();
ClearDebugRegs();
if( ret->conditions & COND_TRACE ) {
ret->conditions |= COND_WATCH;
ret->conditions &= ~COND_TRACE;
}
} else {
for( ;; ) {
addr.segment = Proc.cs;
addr.offset = Proc.eip;
if( ReadMemory( &addr, int_buff, 3 ) == 3
&& int_buff[0] == 0xcd ) {
/* have to breakpoint across software interrupts because Intel
doesn't know how to design chips */
addr.offset = Proc.eip + 2;
int_buff[0] = 0xcc;
WriteMemory( &addr, int_buff, 1 );
} else {
Proc.eflags |= 0x100;
int_buff[0] = 0;
}
ret->conditions = DoRun();
if( int_buff[0] != 0 ) {
addr.offset = Proc.eip;
WriteMemory( &addr, &int_buff[2], 1 );
} else {
Proc.eflags &= ~0x100;
}
if( !(ret->conditions & (COND_TRACE|COND_BREAK)) ) break;
if( CheckWatchPoints() ) {
ret->conditions |= COND_WATCH;
ret->conditions &= ~(COND_TRACE|COND_BREAK);
break;
}
}
}
} else {
ret->conditions = DoRun();
}
ret->conditions |= COND_CONFIG;
ret->program_counter.offset = Proc.eip;
ret->program_counter.segment = Proc.cs;
ret->stack_pointer.offset = Proc.esp;
ret->stack_pointer.segment = Proc.ss;
return( sizeof( *ret ) );
}
unsigned ReqProg_go()
{
return( ProgRun( FALSE ) );
}
unsigned ReqProg_step()
{
return( ProgRun( TRUE ) );
}
unsigned ReqGet_next_alias()
{
get_next_alias_ret *ret;
ret = GetOutPtr( 0 );
ret->seg = 0;
ret->alias = 0;
return( sizeof( *ret ) );
}
unsigned ReqGet_err_text()
{
static char *DosErrMsgs[] = {
#include "dosmsgs.h"
};
get_err_text_req *acc;
char *err_txt;
#define MAX_CODE (sizeof( DosErrMsgs ) / sizeof( char * ) - 1)
_DBG(("AccErrText\r\n"));
acc = GetInPtr( 0 );
err_txt = GetOutPtr( 0 );
if( acc->err > MAX_CODE ) {
_DBG(( "After acc->error_code > MAX_CODE" ));
strcpy( (char *)err_txt, TRP_ERR_unknown_system_error );
ultoa( acc->err, (char *)err_txt + strlen( err_txt ), 16 );
_DBG(("After utoa()\r\n"));
} else {
strcpy( (char *)err_txt, DosErrMsgs[ acc->err ] );
_DBG(("After strcpy\r\n"));
}
return( strlen( err_txt ) + 1 );
}
unsigned ReqGet_lib_name()
{
char *ch;
get_lib_name_ret *ret;
ret = GetOutPtr( 0 );
ret->handle = 0;
ch = GetOutPtr( sizeof( *ret ) );
*ch = '\0';
return( sizeof( *ret ) + 1 );
}
unsigned ReqGet_message_text()
{
get_message_text_ret *ret;
char *err_txt;
ret = GetOutPtr( 0 );
err_txt = GetOutPtr( sizeof(*ret) );
if( Proc.int_id == -1 ) {
err_txt[0] = '\0';
} else {
ExceptionText( Proc.int_id, err_txt );
Proc.int_id = -1;
}
ret->flags = MSG_NEWLINE | MSG_ERROR;
return( sizeof( *ret ) + strlen( err_txt ) + 1 );
}
trap_version TRAPENTRY TrapInit( char *parm, char *err, bool remote )
{
trap_version ver;
int error_num;
extern int hotkey_int;
_DBG1(( "TrapInit\n" ));
remote = remote; parm = parm;
err[0] = '\0'; /* all ok */
ver.major = TRAP_MAJOR_VERSION;
ver.minor = TRAP_MINOR_VERSION;
ver.remote = FALSE;
InitRedirect();
RealNPXType = NPXType();
WatchCount = 0;
FakeBreak = FALSE;
hotkey_int = 5;
error_num = D32DebugInit( &Proc );
if( error_num ) {
_DBG(("D32DebugInit() failed:\n"));
exit(1);
}
Proc.int_id = -1;
D32DebugBreakOp(&Break); /* Get the 1 byte break op */
return( ver );
}
void TRAPENTRY TrapFini( void )
{
_DBG1(( "TrapFini\n" ));
D32DebugTerm();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -