📄 os2v2acc.c
字号:
ret->thread = 1;
ret->flags = LD_FLAG_IS_PROT;
*/
} else {
ret->task_id = Pid;
ret->flags = LD_FLAG_IS_PROT;
Buff.Pid = Pid;
Buff.Tid = 0;
Buff.Cmd = DBG_C_Connect;
Buff.Value = DBG_L_386;
CallDosDebug( &Buff );
Buff.Pid = Pid;
Buff.Tid = 1;
DebugExecute( &Buff, DBG_C_Stop, FALSE );
if( Buff.Cmd != DBG_N_Success ) {
ret->err = 14; /* can't load */
return( sizeof( *ret ) );
}
ReadRegs( &Buff );
CanExecTask = FALSE;
if( FindLinearStartAddress( &startLinear, UtilBuff ) ) {
if( Is32Bit ) {
ret->flags |= LD_FLAG_IS_32;
}
CanExecTask = ExecuteUntilLinearAddressHit( startLinear );
ReadRegs( &Buff );
}
#if 0
if( CanExecTask ) {
dos_debug save;
save.Pid = Pid;
save.Tid = 1;
ReadRegs( &save );
if( !CausePgmToLoadThisDLL( startLinear ) ) {
CanExecTask = FALSE;
}
WriteRegs( &save );
}
#endif
Buff.Pid = Pid;
Buff.Tid = 1;
ReadRegs( &Buff );
TaskFS = Buff.FS;
}
ret->flags |= LD_FLAG_HAVE_RUNTIME_DLLS;
ret->mod_handle = 0;
CurrModHandle = 1;
return( sizeof( *ret ) );
}
unsigned ReqProg_kill( void )
{
prog_kill_ret *ret;
ret = GetOutPtr( 0 );
SaveStdIn = NIL_DOS_HANDLE;
SaveStdOut = NIL_DOS_HANDLE;
if( Pid != 0 ) {
Buff.Cmd = DBG_C_Term;
Buff.Pid = Pid;
CallDosDebug( &Buff );
}
NumModHandles = 0;
CurrModHandle = 1;
Pid = 0;
ret->err = 0;
DosSleep( 500 ); // Without this, it seems that restarts happen too fast
// and we end up running a 2nd instance of a dead task
// or some such sillyness. I don't really know, but
// this DosSleep avoids problems when restarting a PM app
// ( ... Yes, this is a Hail Mary ... )
StopPMHelp();
return( sizeof( *ret ) );
}
unsigned ReqSet_break( void )
{
byte ch;
set_break_req *acc;
set_break_ret *ret;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
ReadBuffer( &ch, acc->break_addr.segment, acc->break_addr.offset, sizeof(byte) );
ret->old = ch;
ch = 0xCC;
WriteBuffer( &ch, acc->break_addr.segment, acc->break_addr.offset, sizeof(byte) );
return( sizeof( *ret ) );
}
unsigned ReqClear_break( void )
{
clear_break_req *acc;
byte ch;
acc = GetInPtr( 0 );
ch = acc->old;
WriteBuffer( &ch, acc->break_addr.segment, acc->break_addr.offset, sizeof(byte) );
return( 0 );
}
unsigned ReqSet_watch( void )
{
set_watch_req *acc;
set_watch_ret *ret;
dword buff;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
ret->err = 1;
if( WatchCount < MAX_WP ) { // nyi - artificial limit (32 should be lots)
WatchPoints[ WatchCount ].addr.segment = acc->watch_addr.segment;
WatchPoints[ WatchCount ].addr.offset = acc->watch_addr.offset;
WatchPoints[ WatchCount ].len = acc->size;
ReadBuffer( (char *)&buff, acc->watch_addr.segment,
acc->watch_addr.offset, sizeof(dword) );
WatchPoints[ WatchCount ].value = buff;
DebugRegsNeeded += ( acc->watch_addr.offset & ( acc->size-1 ) ) ? 2 : 1;
ret->err = 0;
++WatchCount;
}
ret->multiplier = 50000;
if( ret->err == 0 && DebugRegsNeeded <= 4 ) {
ret->multiplier |= USING_DEBUG_REG;
}
return( sizeof( *ret ) );
}
unsigned ReqClear_watch( void )
{
clear_watch_req *acc;
watch *dst;
watch *src;
int i;
acc = GetInPtr( 0 );
dst = src = WatchPoints;
for( i = 0; i < WatchCount; ++i ) {
if( src->addr.segment != acc->watch_addr.segment ||
src->addr.offset != acc->watch_addr.offset ) {
*dst = *src;
++dst;
} else {
DebugExecute( &Buff, DBG_C_Stop, FALSE );
Buff.Cmd = DBG_C_ClearWatch;
Buff.Index = 0; // src->id;
CallDosDebug( &Buff );
}
++src;
}
DebugRegsNeeded -= ( acc->watch_addr.offset & ( acc->size-1 ) ) ? 2 : 1;
--WatchCount;
return( 0 );
}
static volatile bool BrkPending;
void SetBrkPending( void )
{
BrkPending = TRUE;
}
static void pascal far __loadds BrkHandler( USHORT sig_arg, USHORT sig_num )
{
PFNSIGHANDLER prev_hdl;
USHORT prev_act;
sig_arg = sig_arg;
SetBrkPending();
DosSetSigHandler( BrkHandler, &prev_hdl, &prev_act, 4, sig_num );
}
static unsigned MapReturn( unsigned conditions )
{
if( BrkPending ) {
/* Get CS:EIP & SS:ESP correct */
ReadRegs( &Buff );
return( conditions | COND_USER );
}
// Out( "Map Return - " );
// OutNum( Buff.Cmd );
// Out( "\r\n" );
switch( Buff.Cmd ) {
case DBG_N_Success:
return( conditions );
case DBG_N_AsyncStop:
return( conditions | COND_USER );
// case DBG_N_Signal:
// return( TRAP_USER );
case DBG_N_SStep:
return( conditions | COND_TRACE );
case DBG_N_Breakpoint:
return( conditions | COND_BREAK );
case DBG_N_Exception:
switch( ExceptNum ) {
case XCPT_PROCESS_TERMINATE:
case XCPT_ASYNC_PROCESS_TERMINATE:
return( conditions | COND_TERMINATE );
default:
return( conditions | COND_EXCEPTION );
}
case DBG_N_Watchpoint:
return( conditions | COND_WATCH );
case DBG_N_ModuleLoad:
return( conditions | COND_LIBRARIES );
case DBG_N_ThreadTerm:
return( conditions );
case DBG_N_Error: // must terminate application - system semaphore locked
Buff.Cmd = DBG_C_Term;
Buff.Pid = Pid;
CallDosDebug( &Buff );
default:
AtEnd = TRUE;
CanExecTask = FALSE;
return( conditions | COND_TERMINATE );
}
}
static bool setDebugRegs( void )
{
int needed;
int i;
needed = 0;
for( i = 0; i < WatchCount; ++i ) {
needed += WatchPoints[ i ].addr.offset & ( WatchPoints[ i ].len -1 ) ? 2 : 1;
if( needed > 4 ) {
return( FALSE );
}
}
for( i = 0; i < WatchCount; ++i ) {
Buff.Cmd = DBG_C_SetWatch;
Buff.Addr = MakeItFlatNumberOne( WatchPoints[ i ].addr.segment,
WatchPoints[ i ].addr.offset & ~( WatchPoints[ i ].len -1 ) );
Buff.Len = WatchPoints[ i ].len;
Buff.Index = 0;
Buff.Value = DBG_W_Write | DBG_W_Local;
CallDosDebug( &Buff );
if( WatchPoints[ i ].addr.offset & ( WatchPoints[ i ].len-1 ) ) {
Buff.Cmd = DBG_C_SetWatch;
Buff.Addr += WatchPoints[ i ].len;
Buff.Index = 0;
CallDosDebug( &Buff );
}
}
return( TRUE );
}
static void watchSingleStep( void )
{
dos_debug save;
dword memval;
int i;
DebugExecute( &Buff, DBG_C_SStep, TRUE );
while( Buff.Cmd == DBG_N_SStep ) {
for( i = 0; i < WatchCount; ++i ) {
ReadRegs( &save );
ReadBuffer( (char *)&memval, WatchPoints[ i ].addr.segment,
WatchPoints[ i ].addr.offset, sizeof( memval ) );
WriteRegs( &save );
if( WatchPoints[ i ].value != memval ) {
Buff.Cmd = DBG_N_Watchpoint;
return;
}
}
DebugExecute( &Buff, DBG_C_SStep, TRUE );
}
}
static unsigned progRun( bool step )
{
PFNSIGHANDLER prev_brk_hdl;
PFNSIGHANDLER prev_intr_hdl;
USHORT prev_intr_act;
USHORT prev_brk_act;
prog_go_ret *ret;
ret = GetOutPtr( 0 );
if( NumModHandles > CurrModHandle ) {
ret->conditions = COND_LIBRARIES;
ret->stack_pointer.segment = lastSS;
ret->stack_pointer.offset = lastESP;
ret->program_counter.segment = lastCS;
ret->program_counter.offset = lastEIP;
return( sizeof( *ret ) );
}
BrkPending = FALSE;
DosSetSigHandler( BrkHandler, &prev_intr_hdl, &prev_intr_act, 2, SIG_CTRLC );
DosSetSigHandler( BrkHandler, &prev_brk_hdl, &prev_brk_act, 2, SIG_CTRLBREAK );
if( AtEnd ) {
Buff.Cmd = DBG_N_ProcTerm;
} else if( step ) {
DebugExecute( &Buff, DBG_C_SStep, TRUE );
} else if( !setDebugRegs() ) {
watchSingleStep();
} else {
DebugExecute( &Buff, DBG_C_Go, TRUE );
if( Buff.Cmd == DBG_N_Success ) {
Buff.Cmd = DBG_N_ProcTerm;
}
}
DosSetSigHandler( prev_brk_hdl, &prev_brk_hdl, &prev_brk_act,
prev_brk_act, SIG_CTRLBREAK );
DosSetSigHandler( prev_brk_hdl, &prev_intr_hdl, &prev_intr_act,
prev_brk_act, SIG_CTRLC );
ret->conditions = ( COND_CONFIG | COND_THREAD );
if( NumModHandles > CurrModHandle ) {
ret->conditions |= COND_LIBRARIES;
}
ret->conditions = MapReturn( ret->conditions );
lastSS = ret->stack_pointer.segment = Buff.SS;
lastESP = ret->stack_pointer.offset = Buff.ESP;
lastCS = ret->program_counter.segment = Buff.CS;
lastEIP = ret->program_counter.offset = Buff.EIP;
//runret->thread = Buff.Tid;
//if( runret->returnvalue == TRAP_TERMINATE ) {
// AtEnd = TRUE;
// CanExecTask = FALSE;
//}
return( sizeof( *ret ) );
}
unsigned ReqProg_go( void )
{
unsigned rc;
PMUnLock();
rc = progRun( FALSE );
PMLock( Buff.Pid, Buff.Tid );
return( rc );
}
unsigned ReqProg_step( void )
{
unsigned rc;
PMUnLock();
rc = progRun( TRUE );
PMLock( Buff.Pid, Buff.Tid );
return( rc );
}
unsigned ReqFile_write_console( void )
{
USHORT len;
USHORT written_len;
char *ptr;
file_write_console_ret *ret;
ptr = GetInPtr( sizeof( file_write_console_req ) );
len = GetTotalSize() - sizeof( file_write_console_req );
ret = GetOutPtr( 0 );
if( CanExecTask ) {
/* print/program request */
ret->len = len;
ret->err = 0;
TaskPrint( ptr, len );
} else {
ret->err = DosWrite( 2, ptr, len, &written_len );
ret->len = written_len;
}
return( sizeof( *ret ) );
}
static int ValidThread( TID thread )
{
struct thd_state state;
TID save;
if( thread == 0 ) return( 0 );
save = Buff.Tid;
Buff.Tid = thread;
Buff.Cmd = DBG_C_ThrdStat;
Buff.Buffer = MakeLocalPtrFlat( &state );
Buff.Len = 4;
CallDosDebug( &Buff );
Buff.Tid = save;
return( Buff.Cmd == DBG_N_Success );
}
unsigned ReqThread_get_next( void )
{
thread_get_next_req *acc;
thread_get_next_ret *ret;
TID thread;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
if( Pid != 0 ) {
thread = acc->thread;
while( ++thread <= 256 ) {
if( ValidThread( thread ) ) {
ret->thread = thread;
//NYI:Assume all threads can be run
ret->state = THREAD_THAWED;
return( sizeof( *ret ) );
}
}
}
ret->thread = ( acc->thread == 0 ) ? 1 : 0;
return( sizeof( *ret ) );
}
unsigned ReqThread_set( void )
{
thread_set_req *acc;
thread_set_ret *ret;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
ret->err = 0;
ret->old_thread = Buff.Tid;
if( ValidThread( acc->thread ) ) {
Buff.Pid = Pid;
Buff.Tid = acc->thread;
Buff.Cmd = DBG_C_ReadReg;
CallDosDebug( &Buff );
} else if( acc->thread != 0 ) {
ret->err = 1;
}
return( sizeof( *ret ) );
}
static unsigned DoThread( trace_codes code )
{
TID save;
thread_thaw_req *acc;
thread_thaw_ret *ret;
acc = GetInPtr( 0 );
ret = GetOutPtr( 0 );
if( ValidThread( acc->thread ) ) {
save = Buff.Tid;
Buff.Pid = Pid;
Buff.Tid = acc->thread;
Buff.Cmd = code;
CallDosDebug( &Buff );
Buff.Tid = save;
ret->err = 0;
} else {
ret->err = 1; // failed
}
return( sizeof( *ret ) );
}
unsigned ReqThread_freeze( void )
{
return( DoThread( DBG_C_Freeze ) );
}
unsigned ReqThread_thaw( void )
{
return( DoThread( DBG_C_Resume ) );
}
unsigned ReqGet_message_text( void )
{
get_message_text_ret *ret;
char *err_txt;
ret = GetOutPtr( 0 );
err_txt = GetOutPtr( sizeof(*ret) );
if( ExceptNum == -1 ) {
err_txt[0] = '\0';
} else {
strcpy( err_txt, GetExceptionText() );
}
ExceptNum = -1;
ret->flags = MSG_NEWLINE | MSG_ERROR;
return( sizeof( *ret ) + strlen( err_txt ) + 1 );
}
unsigned ReqGet_next_alias( void )
{
get_next_alias_req *acc;
get_next_alias_ret *ret;
ret = GetOutPtr( 0 );
ret->seg = 0;
ret->alias = 0;
acc = GetInPtr( 0 );
if( Is32Bit && acc->seg == 0 ) {
ret->seg = FlatCS;
ret->alias = FlatDS;
}
return( sizeof( *ret ) );
}
void TRAPENTRY TellHandles( HAB hab, HWND hwnd )
{
TellSoftModeHandles( hab, hwnd );
}
char TRAPENTRY TellHardMode( char hard )
{
return( SetHardMode( hard ) );
}
trap_version TRAPENTRY TrapInit( char *parm, char *err, bool remote )
{
trap_version ver;
USHORT os2ver;
SEL li,gi;
__LINFOSEG *linfo;
parm = parm;
Remote = remote;
err[0] = '\0';
ver.major = TRAP_MAJOR_VERSION;
ver.minor = TRAP_MINOR_VERSION;
ver.remote = FALSE;
SaveStdIn = NIL_DOS_HANDLE;
SaveStdOut = NIL_DOS_HANDLE;
Screen = DEBUG_SCREEN;
if( parm[0] == '2' ) {
stopOnSecond = TRUE;
}
DosGetVersion( &os2ver );
if( os2ver < 0x200 ) {
StrCopy( TRP_OS2_Wrong_Version, err );
return( ver );
}
if( DosGetInfoSeg( &gi, &li ) != 0 ) {
StrCopy( TRP_OS2_no_info, err );
return( ver );
}
GblInfo = MK_FP( gi, 0 );
linfo = MK_FP( li, 0 );
TypeProcess = linfo->typeProcess;
if( !GetDos32Debug( err ) ) {
return( ver );
}
InitSoftDebug();
InitDebugThread();
return( ver );
}
void TRAPENTRY TrapFini( void )
{
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -