/* * runProg: * * - we turn on the T-bit for single_step mode, and set the debug registers * for watch points (if we can). * - we then switch to the debuggee, and wait for a fault to occur. * - after the fault, we record information about it and return * */ static unsigned runProg( bool single_step ) { private_msg pmsg; BOOL watch386; BOOL dowatch; BOOL ton; restart_opts restart_option; prog_go_ret *ret; ret = GetOutPtr( 0 ); if( DebugeeTask == NULL ) { ret->conditions = COND_TERMINATE; return( sizeof( *ret ) ); } IntResult.EFlags &= ~TRACE_BIT; dowatch = FALSE; watch386 = FALSE; UnLockInput(); if( single_step ) { SingleStepMode(); } else if( WPCount != 0 ) { dowatch = TRUE; watch386 = SetDebugRegs(); } ret->conditions = 0; restart_option = RESTART_APP; while( DebugeeTask != NULL ) { if( dowatch && !watch386 ) { SingleStepMode(); } ton = TraceOn; pmsg = DebuggerWaitForMessage( RUNNING_DEBUGEE, TaskAtFault, restart_option ); TraceOn = FALSE; if( pmsg == FAULT_HIT ) { switch( IntResult.InterruptNumber ) { case INT_1: ret->conditions = COND_TRACE; if( watch386 ) { if( GetDR6() & 0xf ) { ret->conditions = COND_WATCH; if( DebugDebugeeOnly ) { if( !CheckWatchPoints() ) { restart_option = CHAIN; continue; } } } break; } if( !ton && DebugDebugeeOnly ) { restart_option = CHAIN; continue; } if( dowatch ) { if( CheckWatchPoints() ) { ret->conditions = COND_WATCH; } else { restart_option = RESTART_APP; continue; } } break; case INT_3: if( DebugDebugeeOnly ) { if( !IsOurBreakpoint( IntResult.CS, IntResult.EIP ) ) { IntResult.EIP++; restart_option = CHAIN; continue; } } ret->conditions = COND_BREAK; break; default: if( DebugDebugeeOnly ) { if( TaskAtFault != DebugeeTask ) { restart_option = CHAIN; continue; } } ret->conditions = COND_EXCEPTION; break; } break; } else if( pmsg == TASK_ENDED ) { ret->conditions = COND_TERMINATE; DebugeeTask = NULL; IntResult.CS = TerminateCSIP >> 16; IntResult.EIP = (DWORD) (WORD) TerminateCSIP; break; } else if( pmsg == GET_CHAR ) {
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 ) ); }