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 trap_elen ProgRun( bool step ) { bool watch386; prog_go_ret *ret; ret = GetOutPtr( 0 ); if( Flags.DRsOn ) { SetSingle386(); } else { SetSingleStep(); } if( step ) { TaskRegs.EFL |= FLG_T; } else { watch386 = SetDebugRegs(); if( WatchCount != 0 && !watch386 ) { if( Flags.DRsOn ) { SetWatch386( WatchCount, WatchPoints ); } else { SetWatchPnt( WatchCount, WatchPoints ); } TaskRegs.EFL |= FLG_T; } } out( "in CS:EIP=" ); out( hex( TaskRegs.CS ) ); out(":" ); out( hex( TaskRegs.EIP ) ); out( " SS:ESP=" ); out( hex( TaskRegs.SS ) ); out(":" ); out( hex( TaskRegs.ESP ) ); out( "\r\n" ); ret->conditions = MapReturn( ClearDebugRegs( RunProg( &TaskRegs, &TaskRegs ) ) ); ret->conditions |= COND_CONFIG; // out( "cond=" ); out( hex( ret->conditions ) ); out( " CS:EIP=" ); out( hex( TaskRegs.CS ) ); out(":" ); out( hex( TaskRegs.EIP ) ); out( " SS:ESP=" ); out( hex( TaskRegs.SS ) ); out(":" ); out( hex( TaskRegs.ESP ) ); out( "\r\n" ); ret->stack_pointer.segment = TaskRegs.SS; ret->stack_pointer.offset = TaskRegs.ESP; ret->program_counter.segment = TaskRegs.CS; ret->program_counter.offset = TaskRegs.EIP; TaskRegs.EFL &= ~FLG_T; WatchCount = 0; return( sizeof( *ret ) ); }
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 ) ); }