static USHORT LibLoadPTrace( TRACEBUF FAR_PTR *buff ) { int cmd; int value; USHORT rv; USHORT offv; USHORT segv; char name[BUFF_SIZE]; cmd = buff->cmd; value = buff->value; segv = buff->segv; offv = buff->offv; for( ;; ) { rv = DosPTrace( buff ); if( MainMod == 0 ) MainMod = buff->mte; if( buff->cmd != PT_RET_LIB_LOADED ) return( rv ); buff->cmd = PT_CMD_GET_LIB_NAME; buff->segv = FP_SEG( name ); buff->offv = FP_OFF( name ); DosPTrace( buff ); CodeLoad( buff, buff->value, name, ( MainMod == buff->value ) ? SAMP_MAIN_LOAD : SAMP_CODE_LOAD ); buff->value = value; buff->cmd = cmd; buff->offv = offv; buff->segv = segv; } }
static USHORT WriteBuffer( char far *data, USHORT segv, USHORT offv, USHORT size ) { USHORT length; length = size; if( Pid != 0 ) { while( length != 0 ) { Buff.cmd = PT_CMD_WRITE_MEM_D; if( length == 1 ) { Buff.cmd = PT_CMD_READ_MEM_D; Buff.offv = offv; Buff.segv = segv; DosPTrace( &Buff ); Buff.cmd = PT_CMD_WRITE_MEM_D; Buff.offv = offv; Buff.segv = segv; Buff.value &= 0xff00; Buff.value |= *data; DosPTrace( &Buff ); if( Buff.cmd != PT_RET_SUCCESS ) break; data++; length--; offv++; } else { Buff.value = *data; data++; Buff.value |= *data << 8; data++; Buff.offv = offv; Buff.segv = segv; DosPTrace( &Buff ); if( Buff.cmd != PT_RET_SUCCESS ) break; length -= 2; offv += 2; } } } return( size - length ); /* return amount written */ }
static void __far Sleeper( void ) { static TRACEBUF mybuff; for( ;; ) { DosSleep( SleepTime ); mybuff.pid = Pid; mybuff.tid = 1; mybuff.cmd = PT_CMD_STOP; if( DosPTrace( &mybuff ) != 0 ) { #if 0 InternalError( "DosPTrace( STOP ) failed" ); #endif } } }
static void writeMemory( seg_offset *to, int size, char *from ) { static TRACEBUF mybuff; mybuff.pid = Pid; mybuff.tid = 0; /* NB: callgraph info only supported on thread 0 */ mybuff.segv = to->segment; mybuff.offv = to->offset + size - 1; while( size ) { size--; mybuff.value = from[size]; mybuff.cmd = PT_CMD_WRITE_MEM_D; DosPTrace( &mybuff ); mybuff.offv--; } }
static void readMemory( seg_offset *from, int size, char *to ) { static TRACEBUF mybuff; mybuff.pid = Pid; mybuff.tid = 0; /* NB: callgraph info only supported on thread 0 */ mybuff.segv = from->segment; mybuff.offv = from->offset + size - 1; while( size ) { mybuff.cmd = PT_CMD_READ_MEM_D; DosPTrace( &mybuff ); size--; mybuff.offv--; to[size] = mybuff.value; } }
static void CodeLoad( TRACEBUF FAR_PTR *buff, USHORT mte, const char *name, samp_block_kinds kind ) { seg_offset ovl; int i; ovl.offset = 0; ovl.segment = 0; WriteCodeLoad( ovl, name, kind ); buff->mte = mte; for( i = 1;; ++i ) { buff->cmd = PT_CMD_SEG_TO_SEL; buff->value = i; if( DosPTrace( buff ) != 0 ) break; if( buff->cmd != PT_RET_SUCCESS ) break; WriteAddrMap( i, buff->value, 0 ); } }
static USHORT ReadBuffer( char far *data, USHORT segv, USHORT offv, USHORT size ) { USHORT length; length = size; if( Pid != 0 ) { while( length != 0 ) { Buff.cmd = PT_CMD_READ_MEM_D; Buff.offv = offv; Buff.segv = segv; DosPTrace( &Buff ); if( Buff.cmd != PT_RET_SUCCESS ) break; *data = Buff.value & 0xff; data++; offv++; length--; if( length != 0 ) { *data = Buff.value >> 8; data++; offv++; length--; } } }
static USHORT ReadRegs( TRACEBUF far *buff ) { buff->cmd = PT_CMD_READ_REGS; return( DosPTrace( buff ) ); }
static USHORT WriteRegs( TRACEBUF far *buff ) { buff->cmd = PT_CMD_WRITE_REGS; return( DosPTrace( buff ) ); }
void StartProg( const char *cmd, const char *prog, char *full_args, char *dos_args ) { const char *src; char *dst; USHORT drive; ULONG map; USHORT len; USHORT tid; USHORT rc; char buff[BSIZE]; seg_offset where; char *cmd_tail; /* unused parameters */ (void)cmd; MaxThread = 0; GrowArrays( 1 ); src = prog; dst = UtilBuff; DosQCurDisk( &drive, &map ); if( src[0] == '\0' || src[1] == '\0' || src[1] != ':' ) { *dst++ = drive - 1 + 'A'; *dst++ = ':'; } else { *dst++ = *src++; *dst++ = *src++; } if( src[0] != '\\' ) { ++dst; len = BUFF_SIZE - ( dst - UtilBuff ); DosQCurDir( drive, (PBYTE)dst, &len ); dst[-1] = '\\'; if( *dst == '\\' || *dst == '\0' ) { *dst = '\0'; } else { while( *dst != '\0' ) { ++dst; } *dst++ = '\\'; } } strcpy( dst, src ); dst = UtilBuff + strlen( UtilBuff ) + 1; cmd_tail = dst; strcpy( dst, full_args ); dst += strlen( dst ); *++dst = '\0'; /* Need two nulls at end */ LoadProg( UtilBuff, cmd_tail ); Output( MsgArray[MSG_SAMPLE_1 - ERR_FIRST_MESSAGE] ); Output( UtilBuff ); Output( "\r\n" ); Buff.pid = Pid; Buff.tid = 1; Buff.cmd = PT_CMD_STOP; LibLoadPTrace( &Buff ); if( OSVer < 0x1400 ) { /* OS/2 2.x already dumped out MainMod as a Module load */ CodeLoad( &Buff, MainMod, ExeName, SAMP_MAIN_LOAD ); } InitialCS = Buff.u.r.CS; rc = DosCreateThread( Sleeper, (PUSHORT)&tid, Stack + STACK_SIZE ); if( rc != 0 ) { InternalError( MsgArray[MSG_SAMPLE_4 - ERR_FIRST_MESSAGE] ); } rc = DosSetPrty( PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, tid ); if( rc != 0 ) { InternalError( MsgArray[MSG_SAMPLE_5 - ERR_FIRST_MESSAGE] ); } Buff.pid = Pid; Buff.tid = 1; for( ;; ) { Buff.cmd = PT_CMD_GO; if( LibLoadPTrace( &Buff ) != 0 ) { InternalError( MsgArray[MSG_SAMPLE_7 - ERR_FIRST_MESSAGE] ); } if( Buff.cmd == PT_RET_BREAK && Buff.u.r.DX != 0 ) { /* a mark */ len = 0; Buff.segv = Buff.u.r.DX; Buff.offv = Buff.u.r.AX; for( ;; ) { Buff.cmd = PT_CMD_READ_MEM_D; DosPTrace( &Buff ); buff[len] = Buff.value; if( Buff.cmd != PT_RET_SUCCESS ) buff[len] = '\0'; if( len == BSIZE ) buff[len] = '\0'; if( buff[len] == '\0' ) break; ++len; Buff.offv++; } where.segment = Buff.u.r.CS; where.offset = Buff.u.r.IP; WriteMark( buff, where ); Buff.cmd = PT_CMD_READ_REGS; DosPTrace( &Buff ); Buff.u.r.IP++; Buff.cmd = PT_CMD_WRITE_REGS; DosPTrace( &Buff ); continue; } else if( Buff.cmd == PT_RET_BREAK ) { /* common info pass */ CommonAddr.segment = Buff.u.r.CX; CommonAddr.offset = Buff.u.r.BX; Buff.cmd = PT_CMD_READ_REGS; DosPTrace( &Buff ); Buff.u.r.IP++; Buff.cmd = PT_CMD_WRITE_REGS; DosPTrace( &Buff ); continue; } if( Buff.cmd == PT_RET_FUNERAL ) break; if( Buff.cmd != PT_RET_LIB_LOADED && Buff.cmd != PT_RET_STOPPED && Buff.cmd != PT_RET_TRD_TERMINATE ) { InternalError( MsgArray[MSG_SAMPLE_6 - ERR_FIRST_MESSAGE] ); break; } RecordSample( Buff.u.r.IP, Buff.u.r.CS, Buff.tid ); } report(); }